From: Cerion Armour-Brown Date: Fri, 18 Nov 2005 18:25:12 +0000 (+0000) Subject: Cleaned up toIR.c somewhat X-Git-Tag: svn/VALGRIND_3_1_1^2~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e6f7767c72e7bacd83e1be6008a6412f834db70d;p=thirdparty%2Fvalgrind.git Cleaned up toIR.c somewhat - cleaner extraction of instruction fields, consistent variable names, spaces for tabs, comments++ git-svn-id: svn://svn.valgrind.org/vex/trunk@1463 --- diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index d43aae9a93..49ab2c4a4b 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -58,6 +58,10 @@ - Some invalid forms of lswi and lswx are accepted when they should not be. + - All FP exceptions masked in FPSCR + + - FP condition codes not set in FPSCR + */ @@ -136,6 +140,22 @@ static IRBB* irbb; if (vex_traceflags & VEX_TRACE_FE) \ vex_sprintf(buf, format, ## args) +#if PPC32_TOIR_DEBUG +static void vex_printf_binary( UInt x, UInt len, Bool spaces ) +{ + UInt i; + vassert(len > 0 && len <= 32); + + for (i=len; i>0; i--) { + vex_printf("%d", ((x & (1<<(len-1))) != 0) ); + x = x << 1; + if (((i-1)%4)==0 && (i > 1) && spaces) { + vex_printf(" "); + } + } +} +#endif + /*------------------------------------------------------------*/ /*--- Offsets of various parts of the ppc32 guest state. ---*/ @@ -167,42 +187,81 @@ static IRBB* irbb; /*--- Extract instruction fields --- */ /*------------------------------------------------------------*/ +/* Extract field from insn, given idx (zero = lsb) and field length */ +#define IFIELD( insn, idx, len ) ((insn >> idx) & ((1<> 26) & 0x3F; +static UChar ifieldOPC( UInt instr ) { + return toUChar( IFIELD( instr, 26, 6 ) ); } -/* Extract 10-bit secondary opcode, instr[11:1] */ +/* Extract 10-bit secondary opcode, instr[10:1] */ static UInt ifieldOPClo10 ( UInt instr) { - return (instr >> 1 ) & 0x3FF; + return IFIELD( instr, 1, 10 ); +} + +/* Extract 9-bit secondary opcode, instr[9:1] */ +static UInt ifieldOPClo9 ( UInt instr) { + return IFIELD( instr, 1, 9 ); +} + +/* Extract 5-bit secondary opcode, instr[5:1] */ +static UInt ifieldOPClo5 ( UInt instr) { + return IFIELD( instr, 1, 5 ); } /* Extract RD (destination register) field, instr[25:21] */ -static UInt ifieldRD ( UInt instr ) { - return (instr >> 21) & 0x1F; +static UChar ifieldRegDS( UInt instr ) { + return toUChar( IFIELD( instr, 21, 5 ) ); +} + +/* Extract RA (1st source register) field, instr[20:16] */ +static UChar ifieldRegA ( UInt instr ) { + return toUChar( IFIELD( instr, 16, 5 ) ); +} + +/* Extract RB (2nd source register) field, instr[15:11] */ +static UChar ifieldRegB ( UInt instr ) { + return toUChar( IFIELD( instr, 11, 5 ) ); } -/* Extract RA (first source register) field, instr[20:16] */ -static UInt ifieldRA ( UInt instr ) { - return (instr >> 16) & 0x1F; +/* Extract RC (3rd source register) field, instr[10:6] */ +static UChar ifieldRegC ( UInt instr ) { + return toUChar( IFIELD( instr, 6, 5 ) ); } -/* Extract RB (first source register) field, instr[15:11] */ -static UInt ifieldRB ( UInt instr ) { - return (instr >> 11) & 0x1F; +/* Extract 2nd lowest bit, instr[1] */ +static UChar ifieldBIT10 ( UInt instr ) { + return toUChar( IFIELD( instr, 10, 1 ) ); } -/* Extract bottom bit (Rc?) from instr */ -static UInt ifieldBIT0 ( UInt instr ) { - return instr & 1; +/* Extract 2nd lowest bit, instr[1] */ +static UChar ifieldBIT1 ( UInt instr ) { + return toUChar( IFIELD( instr, 1, 1 ) ); } -/* Extract lower half of instruction and sign extent to 32 bits */ +/* Extract lowest bit, instr[0] */ +static UChar ifieldBIT0 ( UInt instr ) { + return toUChar( instr & 0x1 ); +} + +/* Extract unsigned bottom half, instr[15:0] */ +static UInt ifieldUIMM16 ( UInt instr ) { + return instr & 0xFFFF; +} + +/* Extract bottom half, instr[15:0], and sign extent to 32 bits */ static Int ifieldSIMM16 ( UInt instr ) { Int i = instr & 0xFFFF; return (i << 16) >> 16; } +/* Extract bottom 26 bits, instr[25:0], and sign extent to 32 bits */ +static Int ifieldSIMM26 ( UInt instr ) { + Int i = instr & 0x3FFFFFF; + return (i << 6) >> 6; +} + //zz /*------------------------------------------------------------*/ //zz /*--- Abstract register interface (non-gpr|fpr) --- */ @@ -293,22 +352,6 @@ static UInt MASK( UInt begin, UInt end ) return mask; } -#if PPC32_TOIR_DEBUG -static void vex_printf_binary( UInt x, UInt len, Bool spaces ) -{ - UInt i; - vassert(len > 0 && len <= 32); - - for (i=len; i>0; i--) { - vex_printf("%d", ((x & (1<<(len-1))) != 0) ); - x = x << 1; - if (((i-1)%4)==0 && (i > 1) && spaces) { - vex_printf(" "); - } - } -} -#endif - /*------------------------------------------------------------*/ /*--- Helper bits and pieces for deconstructing the ---*/ @@ -345,11 +388,6 @@ static UInt extend_s_16to32 ( UInt x ) return (UInt)((((Int)x) << 16) >> 16); } -static UInt extend_s_26to32 ( UInt x ) -{ - return (UInt)((((Int)x) << 6) >> 6); -} - /* Do a big-endian load of a 32-bit word, regardless of the endianness of the underlying host. */ static UInt getUIntBigendianly ( UChar* p ) @@ -1168,7 +1206,7 @@ static void set_XER_OV( UInt op, IRExpr* res, = AND3( XOR3(argL,argR,mkU32(-1)), XOR2(argL,res), mkU32(INT32_MIN) ); - /* xer_ov can only be 0 or 1<<31 */ + /* xer_ov can only be 0 or 1<<31 */ xer_ov = binop(Iop_Shr32, xer_ov, mkU8(31) ); break; @@ -1224,7 +1262,7 @@ static void set_XER_OV( UInt op, IRExpr* res, = AND3( XOR3(NOT(argL),argR,mkU32(-1)), XOR2(NOT(argL),res), mkU32(INT32_MIN) ); - /* xer_ov can only be 0 or 1<<31 */ + /* xer_ov can only be 0 or 1<<31 */ xer_ov = binop(Iop_Shr32, xer_ov, mkU8(31) ); break; @@ -1321,7 +1359,7 @@ static void set_XER_CA( UInt op, /* The shift amount is guaranteed to be in 0 .. 63 inclusive. If it is <= 31, behave like SRAWI; else XER.CA is the sign bit of argL. */ - /* This term valid for shift amount < 32 only */ + /* This term valid for shift amount < 32 only */ xer_ca = binop( Iop_And32, @@ -1451,11 +1489,11 @@ static IRExpr* getReg_masked ( PPC32SPR reg, UInt mask ) /* all masks now refer to valid fields */ /* Vex-generated code expects to run with the FPSCR set as follows: - all exceptions masked, round-to-nearest. - This corresponds to a FPSCR value of 0x0. */ + all exceptions masked, round-to-nearest. + This corresponds to a FPSCR value of 0x0. */ /* We're only keeping track of the rounding mode, - so if the mask isn't asking for this, just return 0x0 */ + so if the mask isn't asking for this, just return 0x0 */ if (mask & 0x3) { assign( val, IRExpr_Get(OFFB_FPROUND, Ity_I32) ); } else { @@ -1681,90 +1719,81 @@ static void putReg_bit ( PPC32SPR reg, IRExpr* src, UInt bit_idx ) */ static Bool dis_int_arith ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - - /* D-Form */ - UInt SIMM_16 = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - /* XO-Form */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar flag_OE = toUChar((theInstr >> 10) & 1); /* theInstr[10] */ - UInt opc2 = (theInstr >> 1) & 0x1FF; /* theInstr[1:9] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - UInt EXTS_SIMM = 0; - - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); - IRTemp Rd = newTemp(Ity_I32); + /* D-Form, XO-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + Int simm16 = ifieldSIMM16(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UChar flag_OE = ifieldBIT10(theInstr); + UInt opc2 = ifieldOPClo9(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); + + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); + IRTemp rD = newTemp(Ity_I32); IRTemp res64 = newTemp(Ity_I64); // multiplies need this. -//zz UInt flag_op = PPC32G_FLAG_OP_NUMBER; Bool do_rc = False; - assign( Ra, getIReg(Ra_addr) ); - assign( Rb, getIReg(Rb_addr) ); // XO-Form: Rd, Ra, Rb - EXTS_SIMM = extend_s_16to32(SIMM_16); // D-Form: Rd, Ra, EXTS(SIMM) - -//zz assign( xer_ca, getReg_bit( PPC32_SPR_XER, SHIFT_XER_CA ) ); + assign( rA, getIReg(rA_addr) ); + assign( rB, getIReg(rB_addr) ); // XO-Form: rD, rA, rB switch (opc1) { /* D-Form */ case 0x0C: // addic (Add Immediate Carrying, PPC32 p351 - DIP("addic r%d,r%d,0x%x\n", Rd_addr, Ra_addr, EXTS_SIMM); - assign( Rd, binop( Iop_Add32, mkexpr(Ra), mkU32(EXTS_SIMM) ) ); + DIP("addic r%d,r%d,%d\n", rD_addr, rA_addr, simm16); + assign( rD, binop( Iop_Add32, mkexpr(rA), mkU32(simm16) ) ); set_XER_CA( PPC32G_FLAG_OP_ADD, - mkexpr(Rd), mkexpr(Ra), mkU32(EXTS_SIMM), + mkexpr(rD), mkexpr(rA), mkU32(simm16), mkU32(0)/*old xer.ca, which is ignored*/ ); break; case 0x0D: // addic. (Add Immediate Carrying and Record, PPC32 p352) - DIP("addic. r%d,r%d,0x%x\n", Rd_addr, Ra_addr, EXTS_SIMM); - assign( Rd, binop( Iop_Add32, mkexpr(Ra), mkU32(EXTS_SIMM) ) ); + DIP("addic. r%d,r%d,%d\n", rD_addr, rA_addr, simm16); + assign( rD, binop( Iop_Add32, mkexpr(rA), mkU32(simm16) ) ); set_XER_CA( PPC32G_FLAG_OP_ADD, - mkexpr(Rd), mkexpr(Ra), mkU32(EXTS_SIMM), + mkexpr(rD), mkexpr(rA), mkU32(simm16), mkU32(0)/*old xer.ca, which is ignored*/ ); do_rc = True; // Always record to CR - flag_Rc = 1; + flag_rC = 1; break; case 0x0E: // addi (Add Immediate, PPC32 p350) // li rD,val == addi rD,0,val // la disp(rA) == addi rD,rA,disp - if ( Ra_addr == 0 ) { - DIP("li r%d,%d\n", Rd_addr, (Int)EXTS_SIMM); - assign( Rd, mkU32(EXTS_SIMM) ); + if ( rA_addr == 0 ) { + DIP("li r%d,%d\n", rD_addr, simm16); + assign( rD, mkU32(simm16) ); } else { - DIP("addi r%d,r%d,0x%x\n", Rd_addr, Ra_addr, (Int)SIMM_16); - assign( Rd, binop( Iop_Add32, mkexpr(Ra), mkU32(EXTS_SIMM) ) ); + DIP("addi r%d,r%d,%d\n", rD_addr, rA_addr, simm16); + assign( rD, binop( Iop_Add32, mkexpr(rA), mkU32(simm16) ) ); } break; case 0x0F: // addis (Add Immediate Shifted, PPC32 p353) // lis rD,val == addis rD,0,val - if ( Ra_addr == 0 ) { - DIP("lis r%d,%d\n", Rd_addr, (Int)SIMM_16); - assign( Rd, mkU32(SIMM_16 << 16) ); + if ( rA_addr == 0 ) { + DIP("lis r%d,%d\n", rD_addr, simm16); + assign( rD, mkU32(simm16 << 16) ); } else { - DIP("addis r%d,r%d,0x%x\n", Rd_addr, Ra_addr, SIMM_16); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkU32(SIMM_16 << 16)) ); + DIP("addis r%d,r%d,0x%x\n", rD_addr, rA_addr, simm16); + assign( rD, binop(Iop_Add32, mkexpr(rA), mkU32(simm16 << 16)) ); } break; case 0x07: // mulli (Multiply Low Immediate, PPC32 p490) - DIP("mulli r%d,r%d,0x%x\n", Rd_addr, Ra_addr, SIMM_16); - assign( res64, binop(Iop_MullS32, mkexpr(Ra), mkU32(EXTS_SIMM)) ); - assign( Rd, unop(Iop_64to32, mkexpr(res64)) ); + DIP("mulli r%d,r%d,%d\n", rD_addr, rA_addr, simm16); + assign( res64, binop(Iop_MullS32, mkexpr(rA), mkU32(simm16)) ); + assign( rD, unop(Iop_64to32, mkexpr(res64)) ); break; case 0x08: // subfic (Subtract from Immediate Carrying, PPC32 p540) - DIP("subfic r%d,r%d,0x%x\n", Rd_addr, Ra_addr, SIMM_16); - // rD = exts_simm - rA - assign( Rd, binop(Iop_Sub32, mkU32(EXTS_SIMM), mkexpr(Ra)) ); + DIP("subfic r%d,r%d,%d\n", rD_addr, rA_addr, simm16); + // rD = simm16 - rA + assign( rD, binop(Iop_Sub32, mkU32(simm16), mkexpr(rA)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFI, - mkexpr(Rd), mkexpr(Ra), mkU32(EXTS_SIMM), + mkexpr(rD), mkexpr(rA), mkU32(simm16), mkU32(0)/*old xer.ca, which is ignored*/ ); break; @@ -1775,118 +1804,118 @@ static Bool dis_int_arith ( UInt theInstr ) switch (opc2) { case 0x10A: // add (Add, PPC32 p347) DIP("add%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) ); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( rD, binop(Iop_Add32, mkexpr(rA), mkexpr(rB)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADD, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x00A: // addc (Add Carrying, PPC32 p348) DIP("addc%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) ); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( rD, binop(Iop_Add32, mkexpr(rA), mkexpr(rB)) ); set_XER_CA( PPC32G_FLAG_OP_ADD, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), + mkexpr(rD), mkexpr(rA), mkexpr(rB), mkU32(0)/*old xer.ca, which is ignored*/ ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADD, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x08A: { // adde (Add Extended, PPC32 p349) IRTemp old_xer_ca = newTemp(Ity_I32); DIP("adde%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = rA + rB + XER[CA] assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), - binop(Iop_Add32, mkexpr(Rb), mkexpr(old_xer_ca))) ); + assign( rD, binop(Iop_Add32, mkexpr(rA), + binop(Iop_Add32, mkexpr(rB), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), + mkexpr(rD), mkexpr(rA), mkexpr(rB), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; } case 0x0EA: { // addme (Add to Minus One Extended, PPC32 p354) IRTemp old_xer_ca = newTemp(Ity_I32); - if (Rb_addr != 0) { - vex_printf("dis_int_arith(PPC32)(addme,Rb_addr)\n"); + if (rB_addr != 0) { + vex_printf("dis_int_arith(PPC32)(addme,rB_addr)\n"); return False; } DIP("addme%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = rA + (-1) + XER[CA] // => Just another form of adde assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), + assign( rD, binop(Iop_Add32, mkexpr(rA), binop(Iop_Add32, mkU32(-1), mkexpr(old_xer_ca)) )); set_XER_CA( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkU32(-1), + mkexpr(rD), mkexpr(rA), mkU32(-1), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkU32(-1) ); + mkexpr(rD), mkexpr(rA), mkU32(-1) ); } break; } case 0x0CA: { // addze (Add to Zero Extended, PPC32 p355) IRTemp old_xer_ca = newTemp(Ity_I32); - if (Rb_addr != 0) { - vex_printf("dis_int_arith(PPC32)(addze,Rb_addr)\n"); + if (rB_addr != 0) { + vex_printf("dis_int_arith(PPC32)(addze,rB_addr)\n"); return False; } DIP("addze%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = rA + (0) + XER[CA] // => Just another form of adde assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(old_xer_ca)) ); + assign( rD, binop(Iop_Add32, mkexpr(rA), mkexpr(old_xer_ca)) ); set_XER_CA( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkU32(0), + mkexpr(rD), mkexpr(rA), mkU32(0), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, - mkexpr(Rd), mkexpr(Ra), mkU32(0) ); + mkexpr(rD), mkexpr(rA), mkU32(0) ); } break; } case 0x1EB: // divw (Divide Word, PPC32 p388) DIP("divw%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( Rd, binop(Iop_DivS32, mkexpr(Ra), mkexpr(Rb)) ); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( rD, binop(Iop_DivS32, mkexpr(rA), mkexpr(rB)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_DIVW, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } /* Note: if (0x8000_0000 / -1) or (x / 0) - => Rd=undef, if(flag_Rc) CR7=undef, if(flag_OE) XER_OV=1 + => rD=undef, if(flag_rC) CR7=undef, if(flag_OE) XER_OV=1 => But _no_ exception raised. */ break; case 0x1CB: // divwu (Divide Word Unsigned, PPC32 p389) DIP("divwu%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( Rd, binop(Iop_DivU32, mkexpr(Ra), mkexpr(Rb)) ); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( rD, binop(Iop_DivU32, mkexpr(rA), mkexpr(rB)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_DIVWU, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } /* Note: ditto comment divw, for (x / 0) */ break; @@ -1896,10 +1925,10 @@ static Bool dis_int_arith ( UInt theInstr ) vex_printf("dis_int_arith(PPC32)(mulhw,flag_OE)\n"); return False; } - DIP("mulhw%s r%d,r%d,r%d\n", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( res64, binop(Iop_MullS32, mkexpr(Ra), mkexpr(Rb)) ); - assign( Rd, unop(Iop_64HIto32, mkexpr(res64)) ); + DIP("mulhw%s r%d,r%d,r%d\n", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( res64, binop(Iop_MullS32, mkexpr(rA), mkexpr(rB)) ); + assign( rD, unop(Iop_64HIto32, mkexpr(res64)) ); break; case 0x00B: // mulhwu (Multiply High Word Unsigned, PPC32 p489) @@ -1907,131 +1936,131 @@ static Bool dis_int_arith ( UInt theInstr ) vex_printf("dis_int_arith(PPC32)(mulhwu,flag_OE)\n"); return False; } - DIP("mulhwu%s r%d,r%d,r%d\n", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( res64, binop(Iop_MullU32, mkexpr(Ra), mkexpr(Rb)) ); - assign( Rd, unop(Iop_64HIto32, mkexpr(res64)) ); + DIP("mulhwu%s r%d,r%d,r%d\n", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( res64, binop(Iop_MullU32, mkexpr(rA), mkexpr(rB)) ); + assign( rD, unop(Iop_64HIto32, mkexpr(res64)) ); break; case 0x0EB: // mullw (Multiply Low Word, PPC32 p491) DIP("mullw%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); - assign( res64, binop(Iop_MullU32, mkexpr(Ra), mkexpr(Rb)) ); - assign( Rd, unop(Iop_64to32, mkexpr(res64)) ); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); + assign( res64, binop(Iop_MullU32, mkexpr(rA), mkexpr(rB)) ); + assign( rD, unop(Iop_64to32, mkexpr(res64)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_MULLW, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x068: // neg (Negate, PPC32 p493) - if (Rb_addr != 0) { - vex_printf("dis_int_arith(PPC32)(neg,Rb_addr)\n"); + if (rB_addr != 0) { + vex_printf("dis_int_arith(PPC32)(neg,rB_addr)\n"); return False; } DIP("neg%s%s r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr); // rD = (log not)rA + 1 - assign( Rd, binop(Iop_Add32, - unop(Iop_Not32, mkexpr(Ra)), mkU32(1)) ); + assign( rD, binop(Iop_Add32, + unop(Iop_Not32, mkexpr(rA)), mkU32(1)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_NEG, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x028: // subf (Subtract From, PPC32 p537) DIP("subf%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = rB - rA - assign( Rd, binop(Iop_Sub32, mkexpr(Rb), mkexpr(Ra)) ); + assign( rD, binop(Iop_Sub32, mkexpr(rB), mkexpr(rA)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBF, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x008: // subfc (Subtract from Carrying, PPC32 p538) DIP("subfc%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = rB - rA - assign( Rd, binop(Iop_Sub32, mkexpr(Rb), mkexpr(Ra)) ); + assign( rD, binop(Iop_Sub32, mkexpr(rB), mkexpr(rA)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFC, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), + mkexpr(rD), mkexpr(rA), mkexpr(rB), mkU32(0)/*old xer.ca, which is ignored*/ ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFC, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; case 0x088: {// subfe (Subtract from Extended, PPC32 p539) IRTemp old_xer_ca = newTemp(Ity_I32); DIP("subfe%s%s r%d,r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr, Rb_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr, rB_addr); // rD = (log not)rA + rB + XER[CA] assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), - binop(Iop_Add32, mkexpr(Rb), mkexpr(old_xer_ca))) ); + assign( rD, binop(Iop_Add32, unop(Iop_Not32, mkexpr(rA)), + binop(Iop_Add32, mkexpr(rB), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), + mkexpr(rD), mkexpr(rA), mkexpr(rB), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); + mkexpr(rD), mkexpr(rA), mkexpr(rB) ); } break; } case 0x0E8: { // subfme (Subtract from Minus One Extended, PPC32 p541) IRTemp old_xer_ca = newTemp(Ity_I32); - if (Rb_addr != 0) { - vex_printf("dis_int_arith(PPC32)(subfme,Rb_addr)\n"); + if (rB_addr != 0) { + vex_printf("dis_int_arith(PPC32)(subfme,rB_addr)\n"); return False; } DIP("subfme%s%s r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr); // rD = (log not)rA + (-1) + XER[CA] // => Just another form of subfe assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), + assign( rD, binop(Iop_Add32, unop(Iop_Not32, mkexpr(rA)), binop(Iop_Add32, mkU32(-1), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkU32(-1), + mkexpr(rD), mkexpr(rA), mkU32(-1), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkU32(-1) ); + mkexpr(rD), mkexpr(rA), mkU32(-1) ); } break; } case 0x0C8: { // subfze (Subtract from Zero Extended, PPC32 p542) IRTemp old_xer_ca = newTemp(Ity_I32); - if (Rb_addr != 0) { - vex_printf("dis_int_arith(PPC32)(subfze,Rb_addr)\n"); + if (rB_addr != 0) { + vex_printf("dis_int_arith(PPC32)(subfze,rB_addr)\n"); return False; } DIP("subfze%s%s r%d,r%d\n", - flag_OE ? "o" : "", flag_Rc ? "." : "", - Rd_addr, Ra_addr); + flag_OE ? "o" : "", flag_rC ? "." : "", + rD_addr, rA_addr); // rD = (log not)rA + (0) + XER[CA] // => Just another form of subfe assign( old_xer_ca, get_XER_CA() ); - assign( Rd, binop(Iop_Add32, - unop(Iop_Not32, mkexpr(Ra)), mkexpr(old_xer_ca)) ); + assign( rD, binop(Iop_Add32, + unop(Iop_Not32, mkexpr(rA)), mkexpr(old_xer_ca)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkU32(0), + mkexpr(rD), mkexpr(rA), mkU32(0), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, - mkexpr(Rd), mkexpr(Ra), mkU32(0) ); + mkexpr(rD), mkexpr(rA), mkU32(0) ); } break; } @@ -2046,9 +2075,10 @@ static Bool dis_int_arith ( UInt theInstr ) return False; } - putIReg( Rd_addr, mkexpr(Rd) ); - if (do_rc && flag_Rc) { - set_CR0( mkexpr(Rd) ); + putIReg( rD_addr, mkexpr(rD) ); + + if (do_rc && flag_rC) { + set_CR0( mkexpr(rD) ); } return True; } @@ -2060,56 +2090,46 @@ static Bool dis_int_arith ( UInt theInstr ) */ static Bool dis_int_cmp ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ - UChar b9 = toUChar((theInstr >> 22) & 0x1); /* theInstr[22] */ - UChar flag_L = toUChar((theInstr >> 21) & 0x1); /* theInstr[21] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - - /* D-Form */ - UInt UIMM_16 = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - /* X-Form */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - UInt EXTS_SIMM = 0; - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); -//uu IRTemp xer_so = newTemp(Ity_I32); -//uu IRTemp cr7 = newTemp(Ity_I32); -//uu IRTemp mux1 = newTemp(Ity_I32); -//uu IRTemp mux2 = newTemp(Ity_I32); -//uu IRExpr* irx_cmp_lt; -//uu IRExpr* irx_cmp_eq; - - assign( Ra, getIReg(Ra_addr) ); + /* D-Form, X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); + UChar b22 = toUChar( IFIELD( theInstr, 22, 1 ) ); + UChar flag_L = toUChar( IFIELD( theInstr, 21, 1 ) ); + UChar rA_addr = ifieldRegA(theInstr); + UInt UIMM_16 = ifieldUIMM16(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); + + Int EXTS_SIMM = extend_s_16to32(UIMM_16); + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); + + assign( rA, getIReg(rA_addr) ); if (flag_L==1) { // L==1 invalid for 32 bit. vex_printf("dis_int_cmp(PPC32)(flag_L)\n"); return False; } - if (b9 != 0) { - vex_printf("dis_int_cmp(PPC32)(b9)\n"); + if (b22 != 0) { + vex_printf("dis_int_cmp(PPC32)(b22)\n"); return False; } switch (opc1) { case 0x0B: // cmpi (Compare Immediate, PPC32 p368) - EXTS_SIMM = extend_s_16to32(UIMM_16); - DIP("cmp cr%d,r%d,%d\n", crfD, Ra_addr, (Int)EXTS_SIMM); + DIP("cmp cr%d,r%d,%d\n", crfD, rA_addr, EXTS_SIMM); putCR321( crfD, unop(Iop_32to8, - binop(Iop_CmpORD32S, mkexpr(Ra), + binop(Iop_CmpORD32S, mkexpr(rA), mkU32(EXTS_SIMM))) ); putCR0( crfD, getXER_SO() ); break; case 0x0A: // cmpli (Compare Logical Immediate, PPC32 p370) - DIP("cmpli cr%d,r%d,0x%x\n", crfD, Ra_addr, UIMM_16); + DIP("cmpli cr%d,r%d,0x%x\n", crfD, rA_addr, UIMM_16); putCR321( crfD, unop(Iop_32to8, - binop(Iop_CmpORD32U, mkexpr(Ra), + binop(Iop_CmpORD32U, mkexpr(rA), mkU32(UIMM_16))) ); putCR0( crfD, getXER_SO() ); break; @@ -2120,21 +2140,20 @@ static Bool dis_int_cmp ( UInt theInstr ) vex_printf("dis_int_cmp(PPC32)(0x1F,b0)\n"); return False; } - assign( Rb, getIReg(Rb_addr) ); -//zz irx_cmp_eq = binop(Iop_CmpEQ32, mkexpr(Ra), mkexpr(Rb)); + assign( rB, getIReg(rB_addr) ); switch (opc2) { case 0x000: // cmp (Compare, PPC32 p367) - DIP("cmp cr%d,r%d,r%d\n", crfD, Ra_addr, Rb_addr); + DIP("cmp cr%d,r%d,r%d\n", crfD, rA_addr, rB_addr); putCR321( crfD, unop(Iop_32to8, - binop(Iop_CmpORD32S, mkexpr(Ra), mkexpr(Rb))) ); + binop(Iop_CmpORD32S, mkexpr(rA), mkexpr(rB))) ); putCR0( crfD, getXER_SO() ); break; case 0x020: // cmpl (Compare Logical, PPC32 p369) - DIP("cmpl cr%d,r%d,r%d\n", crfD, Ra_addr, Rb_addr); + DIP("cmpl cr%d,r%d,r%d\n", crfD, rA_addr, rB_addr); putCR321( crfD, unop(Iop_32to8, - binop(Iop_CmpORD32U, mkexpr(Ra), mkexpr(Rb))) ); + binop(Iop_CmpORD32U, mkexpr(rA), mkexpr(rB))) ); putCR0( crfD, getXER_SO() ); break; @@ -2149,19 +2168,6 @@ static Bool dis_int_cmp ( UInt theInstr ) return False; } -//zz irx_cmp_lt = unop(Iop_1Uto8, irx_cmp_lt); -//zz irx_cmp_eq = unop(Iop_1Uto8, irx_cmp_eq); -//zz -//zz // mux_shift_bit = (argL < argR) ? LT : GT (or EQ...) -//zz assign( mux1, IRExpr_Mux0X( irx_cmp_lt, mkU32(SHIFT_CR_GT), mkU32(SHIFT_CR_LT) )); -//zz -//zz // mux_shift_bit = (argL == argR) ? EQ : GT|LT -//zz assign( mux2, IRExpr_Mux0X( irx_cmp_eq, mkexpr(mux1), mkU32(SHIFT_CR_EQ) )); -//zz -//zz assign( xer_so, getReg_bit( PPC32_SPR_XER, SHIFT_XER_SO ) ); -//zz assign( cr7, binop(Iop_Or32, mkexpr(mux2), mkexpr(xer_so)) ); -//zz putReg_field( PPC32_SPR_CR, mkexpr(cr7), 7-crfD ); -//zz return True; return True; } @@ -2171,62 +2177,58 @@ static Bool dis_int_cmp ( UInt theInstr ) */ static Bool dis_int_logic ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - - /* D-Form */ - UInt UIMM_16 = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - /* X-Form */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + /* D-Form, X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar rS_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UInt UIMM_16 = ifieldUIMM16(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); Bool do_rc = False; - IRTemp Rs = newTemp(Ity_I32); - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); -//uu IRTemp Sign = newTemp(Ity_I32); + IRTemp rS = newTemp(Ity_I32); + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); IRExpr* irx; - assign( Rs, getIReg(Rs_addr) ); - assign( Rb, getIReg(Rb_addr) ); + assign( rS, getIReg(rS_addr) ); + assign( rB, getIReg(rB_addr) ); switch (opc1) { case 0x1C: // andi. (AND Immediate, PPC32 p358) - DIP("andi. r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_And32, mkexpr(Rs), mkU32(UIMM_16)) ); + DIP("andi. r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_And32, mkexpr(rS), mkU32(UIMM_16)) ); do_rc = True; // Always record to CR - flag_Rc = 1; + flag_rC = 1; break; case 0x1D: // andis. (AND Immediate Shifted, PPC32 p359) - DIP("andis r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_And32, mkexpr(Rs), mkU32(UIMM_16 << 16)) ); + DIP("andis r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_And32, mkexpr(rS), mkU32(UIMM_16 << 16)) ); do_rc = True; // Always record to CR - flag_Rc = 1; + flag_rC = 1; break; case 0x18: // ori (OR Immediate, PPC32 p497) - DIP("ori r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_Or32, mkexpr(Rs), mkU32(UIMM_16)) ); + DIP("ori r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_Or32, mkexpr(rS), mkU32(UIMM_16)) ); break; case 0x19: // oris (OR Immediate Shifted, PPC32 p498) - DIP("oris r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_Or32, mkexpr(Rs), mkU32(UIMM_16 << 16)) ); + DIP("oris r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_Or32, mkexpr(rS), mkU32(UIMM_16 << 16)) ); break; case 0x1A: // xori (XOR Immediate, PPC32 p550) - DIP("xori r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_Xor32, mkexpr(Rs), mkU32(UIMM_16)) ); + DIP("xori r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_Xor32, mkexpr(rS), mkU32(UIMM_16)) ); break; case 0x1B: // xoris (XOR Immediate Shifted, PPC32 p551) - DIP("xoris r%d,r%d,0x%x\n", Ra_addr, Rs_addr, UIMM_16); - assign( Ra, binop(Iop_Xor32, mkexpr(Rs), mkU32(UIMM_16 << 16)) ); + DIP("xoris r%d,r%d,0x%x\n", rA_addr, rS_addr, UIMM_16); + assign( rA, binop(Iop_Xor32, mkexpr(rS), mkU32(UIMM_16 << 16)) ); break; /* X Form */ @@ -2236,96 +2238,96 @@ static Bool dis_int_logic ( UInt theInstr ) switch (opc2) { case 0x01C: // and (AND, PPC32 p356) DIP("and%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign(Ra, binop(Iop_And32, mkexpr(Rs), mkexpr(Rb))); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign(rA, binop(Iop_And32, mkexpr(rS), mkexpr(rB))); break; case 0x03C: // andc (AND with Complement, PPC32 p357) DIP("andc%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign(Ra, binop(Iop_And32, mkexpr(Rs), - unop(Iop_Not32, mkexpr(Rb)))); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign(rA, binop(Iop_And32, mkexpr(rS), + unop(Iop_Not32, mkexpr(rB)))); break; case 0x01A: // cntlzw (Count Leading Zeros Word, PPC32 p371) - if (Rb_addr!=0) { - vex_printf("dis_int_logic(PPC32)(cntlzw,Rb_addr)\n"); + if (rB_addr!=0) { + vex_printf("dis_int_logic(PPC32)(cntlzw,rB_addr)\n"); return False; } DIP("cntlzw%s r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr); + flag_rC ? "." : "", rA_addr, rS_addr); // Iop_Clz32 undefined for arg==0, so deal with that case: - irx = binop(Iop_CmpNE32, mkexpr(Rs), mkU32(0)); - assign(Ra, IRExpr_Mux0X( unop(Iop_1Uto8, irx), + irx = binop(Iop_CmpNE32, mkexpr(rS), mkU32(0)); + assign(rA, IRExpr_Mux0X( unop(Iop_1Uto8, irx), mkU32(32), - unop(Iop_Clz32, mkexpr(Rs)) )); - // alternatively: assign(Ra, verbose_Clz32(Rs)); + unop(Iop_Clz32, mkexpr(rS)) )); + // alternatively: assign(rA, verbose_Clz32(rS)); break; case 0x11C: // eqv (Equivalent, PPC32 p396) DIP("eqv%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, unop(Iop_Not32, binop(Iop_Xor32, - mkexpr(Rs), mkexpr(Rb))) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, unop(Iop_Not32, binop(Iop_Xor32, + mkexpr(rS), mkexpr(rB))) ); break; case 0x3BA: // extsb (Extend Sign Byte, PPC32 p397 - if (Rb_addr!=0) { - vex_printf("dis_int_logic(PPC32)(extsb,Rb_addr)\n"); + if (rB_addr!=0) { + vex_printf("dis_int_logic(PPC32)(extsb,rB_addr)\n"); return False; } DIP("extsb%s r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr); - assign( Ra, unop(Iop_8Sto32, unop(Iop_32to8, mkexpr(Rs))) ); + flag_rC ? "." : "", rA_addr, rS_addr); + assign( rA, unop(Iop_8Sto32, unop(Iop_32to8, mkexpr(rS))) ); break; case 0x39A: // extsh (Extend Sign Half Word, PPC32 p398) - if (Rb_addr!=0) { - vex_printf("dis_int_logic(PPC32)(extsh,Rb_addr)\n"); + if (rB_addr!=0) { + vex_printf("dis_int_logic(PPC32)(extsh,rB_addr)\n"); return False; } DIP("extsh%s r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr); - assign( Ra, unop(Iop_16Sto32, unop(Iop_32to16, mkexpr(Rs))) ); + flag_rC ? "." : "", rA_addr, rS_addr); + assign( rA, unop(Iop_16Sto32, unop(Iop_32to16, mkexpr(rS))) ); break; case 0x1DC: // nand (NAND, PPC32 p492) DIP("nand%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, unop(Iop_Not32, - binop(Iop_And32, mkexpr(Rs), mkexpr(Rb))) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, unop(Iop_Not32, + binop(Iop_And32, mkexpr(rS), mkexpr(rB))) ); break; case 0x07C: // nor (NOR, PPC32 p494) DIP("nor%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, unop(Iop_Not32, - binop(Iop_Or32, mkexpr(Rs), mkexpr(Rb))) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, unop(Iop_Not32, + binop(Iop_Or32, mkexpr(rS), mkexpr(rB))) ); break; case 0x1BC: // or (OR, PPC32 p495) - if ((!flag_Rc) && Rs_addr == Rb_addr) { - DIP("mr r%d,r%d\n", Ra_addr, Rs_addr); - assign( Ra, mkexpr(Rs) ); + if ((!flag_rC) && rS_addr == rB_addr) { + DIP("mr r%d,r%d\n", rA_addr, rS_addr); + assign( rA, mkexpr(rS) ); } else { DIP("or%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, binop(Iop_Or32, mkexpr(Rs), mkexpr(Rb)) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, binop(Iop_Or32, mkexpr(rS), mkexpr(rB)) ); } break; case 0x19C: // orc (OR with Complement, PPC32 p496) DIP("orc%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, binop(Iop_Or32, mkexpr(Rs), - unop(Iop_Not32, mkexpr(Rb))) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, binop(Iop_Or32, mkexpr(rS), + unop(Iop_Not32, mkexpr(rB))) ); break; case 0x13C: // xor (XOR, PPC32 p549) DIP("xor%s r%d,r%d,r%d\n", - flag_Rc ? "." : "", Ra_addr, Rs_addr, Rb_addr); - assign( Ra, binop(Iop_Xor32, mkexpr(Rs), mkexpr(Rb)) ); + flag_rC ? "." : "", rA_addr, rS_addr, rB_addr); + assign( rA, binop(Iop_Xor32, mkexpr(rS), mkexpr(rB)) ); break; default: @@ -2339,9 +2341,10 @@ static Bool dis_int_logic ( UInt theInstr ) return False; } - putIReg( Ra_addr, mkexpr(Ra) ); - if (do_rc && flag_Rc) { - set_CR0( mkexpr(Ra) ); + putIReg( rA_addr, mkexpr(rA) ); + + if (do_rc && flag_rC) { + set_CR0( mkexpr(rA) ); } return True; } @@ -2354,33 +2357,33 @@ static Bool dis_int_logic ( UInt theInstr ) static Bool dis_int_rot ( UInt theInstr ) { /* M-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar sh_imm = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar MaskBegin = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ - UChar MaskEnd = toUChar((theInstr >> 1) & 0x1F); /* theInstr[1:5] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - + UChar opc1 = ifieldOPC(theInstr); + UChar rS_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UChar sh_imm = rB_addr; + UChar MaskBegin = toUChar( IFIELD( theInstr, 6, 5 ) ); + UChar MaskEnd = toUChar( IFIELD( theInstr, 1, 5 ) ); + UChar flag_rC = ifieldBIT0(theInstr); + UInt mask = MASK(31-MaskEnd, 31-MaskBegin); - IRTemp Rs = newTemp(Ity_I32); - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); + IRTemp rS = newTemp(Ity_I32); + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); - assign( Rs, getIReg(Rs_addr) ); - assign( Rb, getIReg(Rb_addr) ); + assign( rS, getIReg(rS_addr) ); + assign( rB, getIReg(rB_addr) ); switch (opc1) { case 0x14: // rlwimi (Rotate Left Word Immediate then Mask Insert, PPC32 p500) - DIP("rlwimi%s r%d,r%d,%d,%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, sh_imm, MaskBegin, MaskEnd); - // Ra = (ROTL(Rs, Imm) & mask) | (Ra & ~mask); - assign( Ra, binop(Iop_Or32, + DIP("rlwimi%s r%d,r%d,%d,%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, sh_imm, MaskBegin, MaskEnd); + // rA = (ROTL(rS, Imm) & mask) | (rA & ~mask); + assign( rA, binop(Iop_Or32, binop(Iop_And32, mkU32(mask), - ROTL32(mkexpr(Rs), mkU32(sh_imm))), - binop(Iop_And32, getIReg(Ra_addr), mkU32(~mask))) ); + ROTL32(mkexpr(rS), mkU32(sh_imm))), + binop(Iop_And32, getIReg(rA_addr), mkU32(~mask))) ); break; case 0x15: @@ -2392,35 +2395,35 @@ static Bool dis_int_rot ( UInt theInstr ) if (MaskBegin == 0 && sh_imm+MaskEnd == 31) { /* Special-case the ,n,0,31-n form as that is just n-bit shift left (PPC32 p501) */ - DIP("slwi%s r%d,r%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, sh_imm); - assign( Ra, binop(Iop_Shl32, mkexpr(Rs), mkU8(sh_imm)) ); + DIP("slwi%s r%d,r%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, sh_imm); + assign( rA, binop(Iop_Shl32, mkexpr(rS), mkU8(sh_imm)) ); } else if (MaskEnd == 31 && sh_imm+MaskBegin == 32) { /* Special-case the ,32-n,n,31 form as that is just n-bit unsigned shift right (PPC32 p501) */ - DIP("srwi%s r%d,r%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, sh_imm); - assign( Ra, binop(Iop_Shr32, mkexpr(Rs), mkU8(MaskBegin)) ); + DIP("srwi%s r%d,r%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, sh_imm); + assign( rA, binop(Iop_Shr32, mkexpr(rS), mkU8(MaskBegin)) ); } else { /* General case. */ - DIP("rlwinm%s r%d,r%d,%d,%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, sh_imm, MaskBegin, MaskEnd); - // Ra = ROTL(Rs, Imm) & mask - assign( Ra, binop(Iop_And32, ROTL32(mkexpr(Rs), mkU32(sh_imm)), + DIP("rlwinm%s r%d,r%d,%d,%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, sh_imm, MaskBegin, MaskEnd); + // rA = ROTL(rS, Imm) & mask + assign( rA, binop(Iop_And32, ROTL32(mkexpr(rS), mkU32(sh_imm)), mkU32(mask)) ); } break; case 0x17: // rlwnm (Rotate Left Word then AND with Mask, PPC32 p503 - DIP("rlwnm%s r%d,r%d,r%d,%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, Rb_addr, MaskBegin, MaskEnd); - // Ra = ROTL(Rs, Rb[0-4]) & mask + DIP("rlwnm%s r%d,r%d,r%d,%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, rB_addr, MaskBegin, MaskEnd); + // rA = ROTL(rS, rB[0-4]) & mask // note, ROTL32 does the masking, so we don't do it here - assign( Ra, binop(Iop_And32, ROTL32(mkexpr(Rs), mkexpr(Rb)), + assign( rA, binop(Iop_And32, ROTL32(mkexpr(rS), mkexpr(rB)), mkU32(mask)) ); break; @@ -2429,9 +2432,10 @@ static Bool dis_int_rot ( UInt theInstr ) return False; } - putIReg( Ra_addr, mkexpr(Ra) ); - if (flag_Rc) { - set_CR0( mkexpr(Ra) ); + putIReg( rA_addr, mkexpr(rA) ); + + if (flag_rC) { + set_CR0( mkexpr(rA) ); } return True; } @@ -2443,98 +2447,93 @@ static Bool dis_int_rot ( UInt theInstr ) */ static Bool dis_int_load ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - - /* D-Form */ - UInt d_imm = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - /* X-Form */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - UInt exts_d_imm = extend_s_16to32(d_imm); - - IRTemp Ra_or_0 = newTemp(Ity_I32); + /* D-Form, X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + Int d_simm16 = ifieldSIMM16(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); + + IRTemp rA_or_0 = newTemp(Ity_I32); IRTemp EA_imm = newTemp(Ity_I32); IRTemp EA_reg = newTemp(Ity_I32); - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); - assign( Ra, getIReg(Ra_addr) ); - assign( Rb, getIReg(Rb_addr) ); + assign( rA, getIReg(rA_addr) ); + assign( rB, getIReg(rB_addr) ); - assign( Ra_or_0, ea_rA_or_zero(Ra_addr)); + assign( rA_or_0, ea_rA_or_zero(rA_addr)); - assign( EA_imm, binop(Iop_Add32, mkexpr(Ra_or_0), mkU32(exts_d_imm)) ); + assign( EA_imm, binop(Iop_Add32, mkexpr(rA_or_0), mkU32(d_simm16)) ); switch (opc1) { case 0x22: // lbz (Load B & Zero, PPC32 p433) - DIP("lbz r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_8Uto32, + DIP("lbz r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_8Uto32, loadBE(Ity_I8, mkexpr(EA_imm))) ); break; case 0x23: // lbzu (Load B & Zero with Update, PPC32 p434) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lbzu,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lbzu,rA_addr|rD_addr)\n"); return False; } - DIP("lbzu r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_8Uto32, + DIP("lbzu r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_8Uto32, loadBE(Ity_I8, mkexpr(EA_imm))) ); - putIReg( Ra_addr, mkexpr(EA_imm) ); + putIReg( rA_addr, mkexpr(EA_imm) ); break; case 0x2A: // lha (Load HW Algebraic, PPC32 p445) - DIP("lha r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_16Sto32, + DIP("lha r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_16Sto32, loadBE(Ity_I16, mkexpr(EA_imm))) ); break; case 0x2B: // lhau (Load HW Algebraic with Update, PPC32 p446) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lhau,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lhau,rA_addr|rD_addr)\n"); return False; } - DIP("lhau r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_16Sto32, + DIP("lhau r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_16Sto32, loadBE(Ity_I16, mkexpr(EA_imm))) ); - putIReg( Ra_addr, mkexpr(EA_imm) ); + putIReg( rA_addr, mkexpr(EA_imm) ); break; case 0x28: // lhz (Load HW & Zero, PPC32 p450) - DIP("lhz r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_16Uto32, + DIP("lhz r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_16Uto32, loadBE(Ity_I16, mkexpr(EA_imm))) ); break; case 0x29: // lhzu (Load HW & and Zero with Update, PPC32 p451) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lhzu,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lhzu,rA_addr|rD_addr)\n"); return False; } - DIP("lhzu r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, unop(Iop_16Uto32, + DIP("lhzu r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, unop(Iop_16Uto32, loadBE(Ity_I16, mkexpr(EA_imm))) ); - putIReg( Ra_addr, mkexpr(EA_imm) ); + putIReg( rA_addr, mkexpr(EA_imm) ); break; case 0x20: // lwz (Load W & Zero, PPC32 p460) - DIP("lwz r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA_imm)) ); + DIP("lwz r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, loadBE(Ity_I32, mkexpr(EA_imm)) ); break; case 0x21: // lwzu (Load W & Zero with Update, PPC32 p461)) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lwzu,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lwzu,rA_addr|rD_addr)\n"); return False; } - DIP("lwzu r%d,%d(r%d)\n", Rd_addr, (Int)exts_d_imm, Ra_addr); - putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA_imm)) ); - putIReg( Ra_addr, mkexpr(EA_imm) ); + DIP("lwzu r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + putIReg( rD_addr, loadBE(Ity_I32, mkexpr(EA_imm)) ); + putIReg( rA_addr, mkexpr(EA_imm) ); break; /* X Form */ @@ -2543,73 +2542,73 @@ static Bool dis_int_load ( UInt theInstr ) vex_printf("dis_int_load(PPC32)(Ox1F,b0)\n"); return False; } - assign( EA_reg, binop(Iop_Add32, mkexpr(Ra_or_0), mkexpr(Rb)) ); + assign( EA_reg, binop(Iop_Add32, mkexpr(rA_or_0), mkexpr(rB)) ); switch (opc2) { case 0x077: // lbzux (Load B & Zero with Update Indexed, PPC32 p435) - DIP("lbzux r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lwzux,Ra_addr|Rd_addr)\n"); + DIP("lbzux r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lwzux,rA_addr|rD_addr)\n"); return False; } - putIReg( Rd_addr, unop(Iop_8Uto32, + putIReg( rD_addr, unop(Iop_8Uto32, loadBE(Ity_I8, mkexpr(EA_reg))) ); - putIReg( Ra_addr, mkexpr(EA_reg) ); + putIReg( rA_addr, mkexpr(EA_reg) ); break; case 0x057: // lbzx (Load B & Zero Indexed, PPC32 p436) - DIP("lbzx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, unop(Iop_8Uto32, + DIP("lbzx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, unop(Iop_8Uto32, loadBE(Ity_I8, mkexpr(EA_reg))) ); break; case 0x177: // lhaux (Load HW Algebraic with Update Indexed, PPC32 p447) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lhaux,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lhaux,rA_addr|rD_addr)\n"); return False; } - DIP("lhaux r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, unop(Iop_16Sto32, + DIP("lhaux r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, unop(Iop_16Sto32, loadBE(Ity_I16, mkexpr(EA_reg))) ); - putIReg( Ra_addr, mkexpr(EA_reg) ); + putIReg( rA_addr, mkexpr(EA_reg) ); break; case 0x157: // lhax (Load HW Algebraic Indexed, PPC32 p448) - DIP("lhax r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, unop(Iop_16Sto32, + DIP("lhax r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, unop(Iop_16Sto32, loadBE(Ity_I16, mkexpr(EA_reg))) ); break; case 0x137: // lhzux (Load HW & Zero with Update Indexed, PPC32 p452) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lhzux,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == rD_addr) { + vex_printf("dis_int_load(PPC32)(lhzux,rA_addr|rD_addr)\n"); return False; } - DIP("lhzux r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, unop(Iop_16Uto32, + DIP("lhzux r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, unop(Iop_16Uto32, loadBE(Ity_I16, mkexpr(EA_reg))) ); - putIReg( Ra_addr, mkexpr(EA_reg) ); + putIReg( rA_addr, mkexpr(EA_reg) ); break; case 0x117: // lhzx (Load HW & Zero Indexed, PPC32 p453) - DIP("lhzx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, unop(Iop_16Uto32, + DIP("lhzx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, unop(Iop_16Uto32, loadBE(Ity_I16, mkexpr(EA_reg))) ); break; case 0x037: // lwzux (Load W & Zero with Update Indexed, PPC32 p462) - if (Ra_addr == 0 || Ra_addr == Rd_addr) { - vex_printf("dis_int_load(PPC32)(lwzux,Ra_addr|Rd_addr)\n"); + if (rA_addr == 0 || rA_addr == 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) ); + 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; case 0x017: // lwzx (Load W & Zero Indexed, PPC32 p463) - DIP("lwzx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA_reg)) ); + DIP("lwzx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + putIReg( rD_addr, loadBE(Ity_I32, mkexpr(EA_reg)) ); break; default: @@ -2631,74 +2630,71 @@ static Bool dis_int_load ( UInt theInstr ) */ static Bool dis_int_store ( UInt theInstr ) { - UInt opc1 = ifieldOPC(theInstr); /* theInstr[26:31] */ - UInt Rs_addr = ifieldRD(theInstr); /* theInstr[21:25] */ - UInt Ra_addr = ifieldRA(theInstr); /* theInstr[16:20] */ - - /* D-Form */ - Int simm16 = ifieldSIMM16(theInstr); /* theInstr[0:15] */ - - /* X-Form */ - UInt Rb_addr = ifieldRB(theInstr); /* theInstr[11:15] */ - UInt opc2 = ifieldOPClo10(theInstr); /* theInstr[1:10] */ - UInt b0 = ifieldBIT0(theInstr); /* theInstr[0] */ - - IRTemp Ra_or_0 = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); - IRTemp Rs = newTemp(Ity_I32); + /* D-Form, X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UInt rS_addr = ifieldRegDS(theInstr); + UInt rA_addr = ifieldRegA(theInstr); + Int simm16 = ifieldSIMM16(theInstr); + UInt rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); + + IRTemp rA_or_0 = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); + IRTemp rS = newTemp(Ity_I32); IRTemp EA_imm = newTemp(Ity_I32); IRTemp EA_reg = newTemp(Ity_I32); - assign( Rb, getIReg(Rb_addr) ); - assign( Rs, getIReg(Rs_addr) ); + assign( rB, getIReg(rB_addr) ); + assign( rS, getIReg(rS_addr) ); - assign( Ra_or_0, ea_rA_or_zero(Ra_addr) ); - assign( EA_imm, binop(Iop_Add32, mkexpr(Ra_or_0), mkU32(simm16)) ); + assign( rA_or_0, ea_rA_or_zero(rA_addr) ); + assign( EA_imm, binop(Iop_Add32, mkexpr(rA_or_0), mkU32(simm16)) ); switch (opc1) { case 0x26: // stb (Store B, PPC32 p509) - DIP("stb r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - storeBE( mkexpr(EA_imm), unop(Iop_32to8, mkexpr(Rs)) ); + DIP("stb r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + storeBE( mkexpr(EA_imm), unop(Iop_32to8, mkexpr(rS)) ); break; case 0x27: // stbu (Store B with Update, PPC32 p510) - if (Ra_addr == 0 ) { - vex_printf("dis_int_store(PPC32)(stbu,Ra_addr)\n"); + if (rA_addr == 0 ) { + vex_printf("dis_int_store(PPC32)(stbu,rA_addr)\n"); return False; } - DIP("stbu r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - putIReg( Ra_addr, mkexpr(EA_imm) ); - storeBE( mkexpr(EA_imm), unop(Iop_32to8, mkexpr(Rs)) ); + DIP("stbu r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + putIReg( rA_addr, mkexpr(EA_imm) ); + storeBE( mkexpr(EA_imm), unop(Iop_32to8, mkexpr(rS)) ); break; case 0x2C: // sth (Store HW, PPC32 p522) - DIP("sth r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - storeBE( mkexpr(EA_imm), unop(Iop_32to16, mkexpr(Rs)) ); + DIP("sth r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + storeBE( mkexpr(EA_imm), unop(Iop_32to16, mkexpr(rS)) ); break; case 0x2D: // sthu (Store HW with Update, PPC32 p524) - if (Ra_addr == 0) { - vex_printf("dis_int_store(PPC32)(sthu,Ra_addr)\n"); + if (rA_addr == 0) { + vex_printf("dis_int_store(PPC32)(sthu,rA_addr)\n"); return False; } - DIP("sthu r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - putIReg( Ra_addr, mkexpr(EA_imm) ); - storeBE( mkexpr(EA_imm), unop(Iop_32to16, mkexpr(Rs)) ); + DIP("sthu r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + putIReg( rA_addr, mkexpr(EA_imm) ); + storeBE( mkexpr(EA_imm), unop(Iop_32to16, mkexpr(rS)) ); break; case 0x24: // stw (Store W, PPC32 p530) - DIP("stw r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - storeBE( mkexpr(EA_imm), mkexpr(Rs) ); + DIP("stw r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + storeBE( mkexpr(EA_imm), mkexpr(rS) ); break; case 0x25: // stwu (Store W with Update, PPC32 p534) - if (Ra_addr == 0) { - vex_printf("dis_int_store(PPC32)(stwu,Ra_addr)\n"); + if (rA_addr == 0) { + vex_printf("dis_int_store(PPC32)(stwu,rA_addr)\n"); return False; } - DIP("stwu r%u,%d(r%u)\n", Rs_addr, simm16, Ra_addr); - putIReg( Ra_addr, mkexpr(EA_imm) ); - storeBE( mkexpr(EA_imm), mkexpr(Rs) ); + DIP("stwu r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); + putIReg( rA_addr, mkexpr(EA_imm) ); + storeBE( mkexpr(EA_imm), mkexpr(rS) ); break; /* X Form */ @@ -2707,52 +2703,52 @@ static Bool dis_int_store ( UInt theInstr ) vex_printf("dis_int_store(PPC32)(0x1F,b0)\n"); return False; } - assign( EA_reg, binop(Iop_Add32, mkexpr(Ra_or_0), mkexpr(Rb)) ); + assign( EA_reg, binop(Iop_Add32, mkexpr(rA_or_0), mkexpr(rB)) ); switch (opc2) { case 0x0F7: // stbux (Store B with Update Indexed, PPC32 p511) - if (Ra_addr == 0) { - vex_printf("dis_int_store(PPC32)(stbux,Ra_addr)\n"); + if (rA_addr == 0) { + vex_printf("dis_int_store(PPC32)(stbux,rA_addr)\n"); return False; } - DIP("stbux r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - putIReg( Ra_addr, mkexpr(EA_reg) ); - storeBE( mkexpr(EA_reg), unop(Iop_32to8, mkexpr(Rs)) ); + DIP("stbux r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + putIReg( rA_addr, mkexpr(EA_reg) ); + storeBE( mkexpr(EA_reg), unop(Iop_32to8, mkexpr(rS)) ); break; case 0x0D7: // stbx (Store B Indexed, PPC32 p512) - DIP("stbx r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - storeBE( mkexpr(EA_reg), unop(Iop_32to8, mkexpr(Rs)) ); + DIP("stbx r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + storeBE( mkexpr(EA_reg), unop(Iop_32to8, mkexpr(rS)) ); break; case 0x1B7: // sthux (Store HW with Update Indexed, PPC32 p525) - if (Ra_addr == 0) { - vex_printf("dis_int_store(PPC32)(sthux,Ra_addr)\n"); + if (rA_addr == 0) { + vex_printf("dis_int_store(PPC32)(sthux,rA_addr)\n"); return False; } - DIP("sthux r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - putIReg( Ra_addr, mkexpr(EA_reg) ); - storeBE( mkexpr(EA_reg), unop(Iop_32to16, mkexpr(Rs)) ); + DIP("sthux r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + putIReg( rA_addr, mkexpr(EA_reg) ); + storeBE( mkexpr(EA_reg), unop(Iop_32to16, mkexpr(rS)) ); break; case 0x197: // sthx (Store HW Indexed, PPC32 p526) - DIP("sthx r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - storeBE( mkexpr(EA_reg), unop(Iop_32to16, mkexpr(Rs)) ); + DIP("sthx r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + storeBE( mkexpr(EA_reg), unop(Iop_32to16, mkexpr(rS)) ); break; case 0x0B7: // stwux (Store W with Update Indexed, PPC32 p535) - if (Ra_addr == 0) { - vex_printf("dis_int_store(PPC32)(stwux,Ra_addr)\n"); + if (rA_addr == 0) { + vex_printf("dis_int_store(PPC32)(stwux,rA_addr)\n"); return False; } - DIP("stwux r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - putIReg( Ra_addr, mkexpr(EA_reg) ); - storeBE( mkexpr(EA_reg), mkexpr(Rs) ); + DIP("stwux r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + putIReg( rA_addr, mkexpr(EA_reg) ); + storeBE( mkexpr(EA_reg), mkexpr(rS) ); break; case 0x097: // stwx (Store W Indexed, PPC32 p536) - DIP("stwx r%u,r%u,r%u\n", Rs_addr, Ra_addr, Rb_addr); - storeBE( mkexpr(EA_reg), mkexpr(Rs) ); + DIP("stwx r%u,r%u,r%u\n", rS_addr, rA_addr, rB_addr); + storeBE( mkexpr(EA_reg), mkexpr(rS) ); break; default: @@ -2775,36 +2771,34 @@ static Bool dis_int_store ( UInt theInstr ) static Bool dis_int_ldst_mult ( UInt theInstr ) { /* D-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UInt d_imm = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - UInt exts_d_imm = extend_s_16to32(d_imm); - UInt reg_idx = 0; - UInt offset = 0; + UChar opc1 = ifieldOPC(theInstr); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rS_addr = rD_addr; + UChar rA_addr = ifieldRegA(theInstr); + Int d_simm16 = ifieldSIMM16(theInstr); - IRTemp Ra = newTemp(Ity_I32); - IRTemp EA = newTemp(Ity_I32); + UInt reg_idx = 0; + UInt offset = 0; + IRTemp rA = newTemp(Ity_I32); + IRTemp EA = newTemp(Ity_I32); IRExpr* irx_addr; - if (Ra_addr == 0) { - assign( EA, binop(Iop_Add32, mkU32(0), mkU32(exts_d_imm)) ); + if (rA_addr == 0) { + assign( EA, binop(Iop_Add32, mkU32(0), mkU32(d_simm16)) ); } else { - assign( Ra, getIReg(Ra_addr) ); - assign( EA, binop(Iop_Add32, mkexpr(Ra), mkU32(exts_d_imm)) ); + assign( rA, getIReg(rA_addr) ); + assign( EA, binop(Iop_Add32, mkexpr(rA), mkU32(d_simm16)) ); } switch (opc1) { case 0x2E: // lmw (Load Multiple Word, PPC32 p454) - if (Ra_addr >= Rd_addr) { - vex_printf("dis_int_ldst_mult(PPC32)(lmw,Ra_addr)\n"); + if (rA_addr >= 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 = Rd_addr; reg_idx <= 31; reg_idx++) { + DIP("lmw r%d,%d(r%d)\n", rD_addr, d_simm16, rA_addr); + for (reg_idx = rD_addr; reg_idx <= 31; reg_idx++) { irx_addr = binop(Iop_Add32, mkexpr(EA), mkU32(offset)); putIReg( reg_idx, loadBE(Ity_I32, irx_addr ) ); offset += 4; @@ -2812,8 +2806,8 @@ static Bool dis_int_ldst_mult ( UInt theInstr ) break; 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 = Rs_addr; reg_idx <= 31; reg_idx++) { + DIP("stmw r%d,%d(r%d)\n", rS_addr, d_simm16, rA_addr); + for (reg_idx = rS_addr; reg_idx <= 31; reg_idx++) { irx_addr = binop(Iop_Add32, mkexpr(EA), mkU32(offset)); storeBE( irx_addr, getIReg(reg_idx) ); offset += 4; @@ -2913,14 +2907,14 @@ void generate_stsw_sequence ( IRTemp tNBytes, // # bytes, :: Ity_I32 static Bool dis_int_ldst_str ( UInt theInstr, /*OUT*/Bool* stopHere ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar NumBytes = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rS_addr = rD_addr; + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UChar NumBytes = rB_addr; + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp t_EA = newTemp(Ity_I32); IRTemp t_nbytes = IRTemp_INVALID; @@ -2936,19 +2930,19 @@ static Bool dis_int_ldst_str ( UInt theInstr, /*OUT*/Bool* stopHere ) case 0x255: // lswi (Load String Word Immediate, PPC32 p455) /* NB: does not reject the case where RA is in the range of registers to be loaded. It should. */ - DIP("lswi r%d,r%d,%d\n", Rd_addr, Ra_addr, NumBytes); - assign( t_EA, ea_rA_or_zero(Ra_addr) ); + DIP("lswi r%d,r%d,%d\n", rD_addr, rA_addr, NumBytes); + assign( t_EA, ea_rA_or_zero(rA_addr) ); if (NumBytes == 8) { /* Special case hack */ - /* Rd = Mem[EA]; (Rd+1)%32 = Mem[EA+4] */ - putIReg( Rd_addr, + /* rD = Mem[EA]; (rD+1)%32 = Mem[EA+4] */ + putIReg( rD_addr, loadBE(Ity_I32, mkexpr(t_EA)) ); - putIReg( (Rd_addr+1) % 32, + putIReg( (rD_addr+1) % 32, loadBE(Ity_I32, binop(Iop_Add32, mkexpr(t_EA), mkU32(4))) ); } else { t_nbytes = newTemp(Ity_I32); - assign( t_nbytes, mkU32(NumBytes==0 ? 32 : NumBytes) ); - generate_lsw_sequence( t_nbytes, t_EA, Rd_addr, + assign( t_nbytes, mkU32(NumBytes==0 ? 32 : NumBytes) ); + generate_lsw_sequence( t_nbytes, t_EA, rD_addr, 32, guest_CIA_curr_instr+4 ); *stopHere = True; } @@ -2959,46 +2953,46 @@ static Bool dis_int_ldst_str ( UInt theInstr, /*OUT*/Bool* stopHere ) registers to be loaded. It should. Although considering that that can only be detected at run time, it's not easy to do so. */ - if (Rd_addr == Ra_addr || Rd_addr == Rb_addr) + if (rD_addr == rA_addr || rD_addr == rB_addr) return False; - if (Rd_addr == 0 && Ra_addr == 0) + if (rD_addr == 0 && rA_addr == 0) return False; - DIP("lswx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); + DIP("lswx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); t_nbytes = newTemp(Ity_I32); - assign( t_EA, ea_standard(Ra_addr,Rb_addr) ); + assign( t_EA, ea_standard(rA_addr,rB_addr) ); assign( t_nbytes, unop( Iop_8Uto32, IRExpr_Get( OFFB_XER_BC, Ity_I8 ))); - generate_lsw_sequence( t_nbytes, t_EA, Rd_addr, + generate_lsw_sequence( t_nbytes, t_EA, rD_addr, 128, guest_CIA_curr_instr+4 ); *stopHere = True; return True; case 0x2D5: // stswi (Store String Word Immediate, PPC32 p528) - DIP("stswi r%d,r%d,%d\n", Rs_addr, Ra_addr, NumBytes); - assign( t_EA, ea_rA_or_zero(Ra_addr) ); + DIP("stswi r%d,r%d,%d\n", rS_addr, rA_addr, NumBytes); + assign( t_EA, ea_rA_or_zero(rA_addr) ); if (NumBytes == 8) { /* Special case hack */ - /* Mem[EA] = Rd; Mem[EA+4] = (Rd+1)%32 */ - storeBE( mkexpr(t_EA), - getIReg(Rd_addr) ); - storeBE( binop(Iop_Add32, mkexpr(t_EA), mkU32(4)), - getIReg((Rd_addr+1) % 32) ); + /* Mem[EA] = rD; Mem[EA+4] = (rD+1)%32 */ + storeBE( mkexpr(t_EA), + getIReg(rD_addr) ); + storeBE( binop(Iop_Add32, mkexpr(t_EA), mkU32(4)), + getIReg((rD_addr+1) % 32) ); } else { t_nbytes = newTemp(Ity_I32); - assign( t_nbytes, mkU32(NumBytes==0 ? 32 : NumBytes) ); - generate_stsw_sequence( t_nbytes, t_EA, Rd_addr, + assign( t_nbytes, mkU32(NumBytes==0 ? 32 : NumBytes) ); + generate_stsw_sequence( t_nbytes, t_EA, rD_addr, 32, guest_CIA_curr_instr+4 ); *stopHere = True; } return True; case 0x295: // stswx (Store String Word Indexed, PPC32 p529) - DIP("stswx r%d,r%d,r%d\n", Rs_addr, Ra_addr, Rb_addr); + DIP("stswx r%d,r%d,r%d\n", rS_addr, rA_addr, rB_addr); t_nbytes = newTemp(Ity_I32); - assign( t_EA, ea_standard(Ra_addr,Rb_addr) ); + assign( t_EA, ea_standard(rA_addr,rB_addr) ); assign( t_nbytes, unop( Iop_8Uto32, IRExpr_Get( OFFB_XER_BC, Ity_I8 ))); - generate_stsw_sequence( t_nbytes, t_EA, Rs_addr, + generate_stsw_sequence( t_nbytes, t_EA, rS_addr, 128, guest_CIA_curr_instr+4 ); *stopHere = True; return True; @@ -3067,7 +3061,7 @@ static IRExpr* /* :: Ity_I32 */ branch_cond_ok( UInt BO, UInt BI ) } else { /* We have to invert the sense of the information held in cr_bi. For that we need to know which bit - getCRbit_somewhere regards as significant. */ + getCRbit_anywhere regards as significant. */ assign( res, binop(Iop_Xor32, mkexpr(cr_bi), mkU32(1<> 26) & 0x3F); /* theInstr[26:31] */ - UChar BO = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar BI = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UInt BD = (theInstr >> 2) & 0x3FFF; /* theInstr[2:15] */ - UChar b11to15 = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UInt LI_24 = (theInstr >> 2) & 0xFFFFFF; /* theInstr[2:25] */ - UChar flag_AA = toUChar((theInstr >> 1) & 1); /* theInstr[1] */ - UChar flag_LK = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - Int exts_BD = (Int)extend_s_16to32(BD << 2); - Int exts_LI = (Int)extend_s_26to32(LI_24 << 2); + UChar opc1 = ifieldOPC(theInstr); + UChar BO = ifieldRegDS(theInstr); + UChar BI = ifieldRegA(theInstr); + Int BD_s16 = ifieldSIMM16(theInstr) & 0xFFFFFFFC; /* mask off */ + UChar b11to15 = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + Int LI_s26 = ifieldSIMM26(theInstr) & 0xFFFFFFFC; /* mask off */ + UChar flag_AA = ifieldBIT1(theInstr); + UChar flag_LK = ifieldBIT0(theInstr); Addr32 nia = 0; @@ -3115,9 +3106,9 @@ static Bool dis_branch ( UInt theInstr, switch (opc1) { case 0x12: // b (Branch, PPC32 p360) if (flag_AA) { - nia = (UInt)exts_LI; + nia = (UInt)LI_s26; } else { - nia = (UInt)((Int)guest_CIA_curr_instr + exts_LI); + nia = (UInt)((Int)guest_CIA_curr_instr + LI_s26); } DIP("b%s%s 0x%x\n", flag_LK ? "l" : "", flag_AA ? "a" : "", nia); @@ -3136,7 +3127,7 @@ static Bool dis_branch ( UInt theInstr, case 0x10: // bc (Branch Conditional, PPC32 p361) DIP("bc%s%s 0x%x, 0x%x, 0x%x\n", - flag_LK ? "l" : "", flag_AA ? "a" : "", BO, BI, exts_BD); + flag_LK ? "l" : "", flag_AA ? "a" : "", BO, BI, BD_s16); if (!(BO & 0x4)) { putSPR( PPC32_SPR_CTR, @@ -3144,19 +3135,19 @@ static Bool dis_branch ( UInt theInstr, } /* This is a bit subtle. ctr_ok is either all 0s or all 1s. - cond_ok is either zero or nonzero, since that's the cheapest - way to compute it. Anding them together gives a value which - is either zero or non zero and so that's what we must test - for in the IRStmt_Exit. */ + cond_ok is either zero or nonzero, since that's the cheapest + way to compute it. Anding them together gives a value which + is either zero or non zero and so that's what we must test + for in the IRStmt_Exit. */ assign( ctr_ok, branch_ctr_ok( BO ) ); assign( cond_ok, branch_cond_ok( BO, BI ) ); assign( do_branch, binop(Iop_And32, mkexpr(cond_ok), mkexpr(ctr_ok)) ); if (flag_AA) { - nia = (UInt)exts_BD; + nia = (UInt)BD_s16; } else { - nia = (UInt)((Int)guest_CIA_curr_instr + exts_BD); + nia = (UInt)((Int)guest_CIA_curr_instr + BD_s16); } if (flag_LK) { putSPR( PPC32_SPR_LR, mkU32(guest_CIA_curr_instr + 4) ); @@ -3265,14 +3256,14 @@ static Bool dis_branch ( UInt theInstr, static Bool dis_cond_logic ( UInt theInstr ) { /* XL-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar crbD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar crfD_addr = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ - UChar crbA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar crfS_addr = toUChar((theInstr >> 18) & 0x7); /* theInstr[18:20] */ - UChar crbB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar crbD_addr = ifieldRegDS(theInstr); + UChar crfD_addr = toUChar( IFIELD(theInstr, 23, 3) ); + UChar crbA_addr = ifieldRegA(theInstr); + UChar crfS_addr = toUChar( IFIELD(theInstr, 18, 3) ); + UChar crbB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp crbD = newTemp(Ity_I32); IRTemp crbA = newTemp(Ity_I32); @@ -3285,8 +3276,10 @@ static Bool dis_cond_logic ( UInt theInstr ) if (opc2 == 0) { // mcrf (Move Cond Reg Field, PPC32 p464) if (((crbD_addr & 0x3) != 0) || - ((crbA_addr & 0x3) != 0) || (crbB_addr != 0)) + ((crbA_addr & 0x3) != 0) || (crbB_addr != 0)) { + vex_printf("dis_cond_logic(PPC32)(crbD|crbA|crbB != 0)\n"); return False; + } DIP("mcrf cr%d,cr%d\n", crfD_addr, crfS_addr); putCR0( crfD_addr, getCR0( crfS_addr) ); putCR321( crfD_addr, getCR321(crfS_addr) ); @@ -3378,17 +3371,17 @@ static Bool dis_syslink ( UInt theInstr, DisResult* dres ) static Bool dis_memsync ( UInt theInstr ) { /* X-Form, XL-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UInt b11to25 = (theInstr >> 11) & 0x7FFF; /* theInstr[11:25] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UInt b11to25 = IFIELD(theInstr, 11, 15); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rS_addr = rD_addr; + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp EA = newTemp(Ity_I32); - IRTemp Rs = newTemp(Ity_I32); + IRTemp rS = newTemp(Ity_I32); switch (opc1) { /* XL-Form */ @@ -3423,10 +3416,10 @@ static Bool dis_memsync ( UInt theInstr ) vex_printf("dis_int_memsync(PPC32)(lwarx,b0)\n"); return False; } - DIP("lwarx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); - assign( EA, ea_standard(Ra_addr, Rb_addr) ); - putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA)) ); - /* Take a reservation */ + DIP("lwarx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); + assign( EA, ea_standard(rA_addr, rB_addr) ); + putIReg( rD_addr, loadBE(Ity_I32, mkexpr(EA)) ); + /* Take a reservation */ stmt( IRStmt_Put( OFFB_RESVN, mkexpr(EA) )); break; @@ -3437,21 +3430,21 @@ static Bool dis_memsync ( UInt theInstr ) vex_printf("dis_int_memsync(PPC32)(stwcx.,b0)\n"); return False; } - DIP("stwcx. r%d,r%d,r%d\n", Rs_addr, Ra_addr, Rb_addr); - assign( Rs, getIReg(Rs_addr) ); - assign( EA, ea_standard(Ra_addr, Rb_addr) ); + DIP("stwcx. r%d,r%d,r%d\n", rS_addr, rA_addr, rB_addr); + assign( rS, getIReg(rS_addr) ); + assign( EA, ea_standard(rA_addr, rB_addr) ); - /* First set up as if the reservation failed */ + /* First set up as if the reservation failed */ // Set CR0[LT GT EQ S0] = 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) ); + /* 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. */ + /* Skip the rest if the reservation really did fail. */ stmt( IRStmt_Exit( binop(Iop_CmpNE32, mkexpr(resaddr), mkexpr(EA)), @@ -3460,8 +3453,8 @@ static Bool dis_memsync ( UInt theInstr ) ) ); - /* Success? Do the store */ - storeBE( mkexpr(EA), mkexpr(Rs) ); + /* Success? Do the store */ + storeBE( mkexpr(EA), mkexpr(rS) ); // Set CR0[LT GT EQ S0] = 0b001 || XER[SO] putCR321(0, mkU8(1<<1)); @@ -3500,107 +3493,107 @@ static Bool dis_memsync ( UInt theInstr ) static Bool dis_int_shift ( UInt theInstr ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar sh_imm = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - + UChar opc1 = ifieldOPC(theInstr); + UChar rS_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UChar sh_imm = rB_addr; + UInt opc2 = ifieldOPClo10(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); + IRTemp sh_amt = newTemp(Ity_I8); - IRTemp Rs = newTemp(Ity_I32); - IRTemp Ra = newTemp(Ity_I32); - IRTemp Rb = newTemp(Ity_I32); + IRTemp rS = newTemp(Ity_I32); + IRTemp rA = newTemp(Ity_I32); + IRTemp rB = newTemp(Ity_I32); IRTemp sh_amt32 = newTemp(Ity_I32); IRTemp outofrange = newTemp(Ity_I8); - assign( Rs, getIReg(Rs_addr) ); - assign( Rb, getIReg(Rb_addr) ); + assign( rS, getIReg(rS_addr) ); + assign( rB, getIReg(rB_addr) ); if (opc1 == 0x1F) { switch (opc2) { case 0x018: // slw (Shift Left Word, PPC32 p505) - DIP("slw%s r%d,r%d,r%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, Rb_addr); - /* Ra = Rs << Rb */ - /* ppc32 semantics are: + DIP("slw%s r%d,r%d,r%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, rB_addr); + /* rA = rS << rB */ + /* ppc32 semantics are: slw(x,y) = (x << (y & 31)) -- primary result & ~((y << 26) >>s 31) -- make result 0 for y in 32 .. 63 */ - assign(Ra, + assign(rA, binop( Iop_And32, binop( Iop_Shl32, - mkexpr(Rs), + mkexpr(rS), unop( Iop_32to8, - binop(Iop_And32, mkexpr(Rb), mkU32(31)))), + binop(Iop_And32, mkexpr(rB), mkU32(31)))), unop( Iop_Not32, binop( Iop_Sar32, - binop(Iop_Shl32, mkexpr(Rb), mkU8(26)), + binop(Iop_Shl32, mkexpr(rB), mkU8(26)), mkU8(31)))) - ); + ); break; case 0x318: // sraw (Shift Right Algebraic Word, PPC32 p506) - DIP("sraw%s r%d,r%d,r%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, Rb_addr); + DIP("sraw%s r%d,r%d,r%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, rB_addr); - /* JRS: my reading of the (poorly worded) PPC32 doc p506 is: - amt = Rb & 63 - Ra = Sar32( Rs, amt > 31 ? 31 : amt ) - XER.CA = amt > 31 ? sign-of-Rs : (computation as per srawi) - */ - assign( sh_amt32, binop(Iop_And32, mkU32(0x3F), mkexpr(Rb)) ); - assign( outofrange, + /* JRS: my reading of the (poorly worded) PPC32 doc p506 is: + amt = rB & 63 + rA = Sar32( rS, amt > 31 ? 31 : amt ) + XER.CA = amt > 31 ? sign-of-rS : (computation as per srawi) + */ + assign( sh_amt32, binop(Iop_And32, mkU32(0x3F), mkexpr(rB)) ); + assign( outofrange, unop( Iop_1Uto8, binop(Iop_CmpLT32U, mkU32(31), mkexpr(sh_amt32)) )); - assign( Ra, + assign( rA, binop( Iop_Sar32, - mkexpr(Rs), + mkexpr(rS), unop( Iop_32to8, IRExpr_Mux0X( mkexpr(outofrange), mkexpr(sh_amt32), mkU32(31)) )) ); set_XER_CA( PPC32G_FLAG_OP_SRAW, - mkexpr(Ra), mkexpr(Rs), mkexpr(sh_amt32), + mkexpr(rA), mkexpr(rS), mkexpr(sh_amt32), get_XER_CA() ); break; case 0x338: // srawi (Shift Right Algebraic Word Immediate, PPC32 p507) - DIP("srawi%s r%d,r%d,%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, sh_imm); - vassert(sh_imm < 32); + DIP("srawi%s r%d,r%d,%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, sh_imm); + vassert(sh_imm < 32); assign( sh_amt, mkU8(sh_imm) ); - assign( Ra, binop(Iop_Sar32, mkexpr(Rs), mkexpr(sh_amt)) ); + assign( rA, binop(Iop_Sar32, mkexpr(rS), mkexpr(sh_amt)) ); set_XER_CA( PPC32G_FLAG_OP_SRAWI, - mkexpr(Ra), mkexpr(Rs), mkU32(sh_imm), + mkexpr(rA), mkexpr(rS), mkU32(sh_imm), get_XER_CA() ); break; case 0x218: // srw (Shift Right Word, PPC32 p508) - DIP("srw%s r%d,r%d,r%d\n", flag_Rc ? "." : "", - Ra_addr, Rs_addr, Rb_addr); - /* Ra = Rs >>u Rb */ - /* ppc32 semantics are: + DIP("srw%s r%d,r%d,r%d\n", flag_rC ? "." : "", + rA_addr, rS_addr, rB_addr); + /* rA = rS >>u rB */ + /* ppc32 semantics are: slw(x,y) = (x >>u (y & 31)) -- primary result & ~((y << 26) >>s 31) -- make result 0 for y in 32 .. 63 */ - assign(Ra, + assign(rA, binop( Iop_And32, binop( Iop_Shr32, - mkexpr(Rs), + mkexpr(rS), unop( Iop_32to8, - binop(Iop_And32, mkexpr(Rb), mkU32(31)))), + binop(Iop_And32, mkexpr(rB), mkU32(31)))), unop( Iop_Not32, binop( Iop_Sar32, - binop(Iop_Shl32, mkexpr(Rb), mkU8(26)), + binop(Iop_Shl32, mkexpr(rB), mkU8(26)), mkU8(31)))) - ); + ); break; default: @@ -3612,10 +3605,10 @@ static Bool dis_int_shift ( UInt theInstr ) return False; } - putIReg( Ra_addr, mkexpr(Ra) ); + putIReg( rA_addr, mkexpr(rA) ); - if (flag_Rc) { - set_CR0( mkexpr(Ra) ); + if (flag_rC) { + set_CR0( mkexpr(rA) ); } return True; } @@ -3645,13 +3638,13 @@ static IRExpr* /* :: Ity_I32 */ gen_byterev32 ( IRTemp t ) static Bool dis_int_ldst_rev ( UInt theInstr ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar rD_addr = ifieldRegDS(theInstr); + UChar rS_addr = rD_addr; + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp EA = newTemp(Ity_I32); IRTemp w1 = newTemp(Ity_I32); @@ -3662,35 +3655,35 @@ static Bool dis_int_ldst_rev ( UInt theInstr ) return False; } - assign( EA, ea_standard(Ra_addr, Rb_addr) ); + assign( EA, ea_standard(rA_addr, rB_addr) ); switch (opc2) { //zz case 0x316: // lhbrx (Load Half Word Byte-Reverse Indexed, PPC32 p449) //zz vassert(0); //zz -//zz DIP("lhbrx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); +//zz DIP("lhbrx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); //zz assign( byte0, loadBE(Ity_I8, mkexpr(EA)) ); //zz assign( byte1, loadBE(Ity_I8, binop(Iop_Add32, mkexpr(EA),mkU32(1))) ); -//zz assign( Rd, binop(Iop_Or32, +//zz assign( rD, binop(Iop_Or32, //zz binop(Iop_Shl32, mkexpr(byte1), mkU8(8)), //zz mkexpr(byte0)) ); -//zz putIReg( Rd_addr, mkexpr(Rd)); +//zz putIReg( rD_addr, mkexpr(rD)); //zz break; case 0x216: // lwbrx (Load Word Byte-Reverse Indexed, PPC32 p459) - DIP("lwbrx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr); + DIP("lwbrx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr); assign( w1, loadBE(Ity_I32, mkexpr(EA)) ); assign( w2, gen_byterev32(w1) ); - putIReg( Rd_addr, mkexpr(w2)); + putIReg( rD_addr, mkexpr(w2)); break; //zz case 0x396: // sthbrx (Store Half Word Byte-Reverse Indexed, PPC32 p523) //zz vassert(0); //zz -//zz DIP("sthbrx r%d,r%d,r%d\n", Rs_addr, Ra_addr, Rb_addr); -//zz assign( Rs, getIReg(Rs_addr) ); -//zz assign( byte0, binop(Iop_And32, mkexpr(Rs), mkU32(0x00FF)) ); -//zz assign( byte1, binop(Iop_And32, mkexpr(Rs), mkU32(0xFF00)) ); +//zz DIP("sthbrx r%d,r%d,r%d\n", rS_addr, rA_addr, rB_addr); +//zz assign( rS, getIReg(rS_addr) ); +//zz assign( byte0, binop(Iop_And32, mkexpr(rS), mkU32(0x00FF)) ); +//zz assign( byte1, binop(Iop_And32, mkexpr(rS), mkU32(0xFF00)) ); //zz //zz assign( tmp16, //zz unop(Iop_32to16, @@ -3701,8 +3694,8 @@ static Bool dis_int_ldst_rev ( UInt theInstr ) //zz break; case 0x296: // stwbrx (Store Word Byte-Reverse Indexed, PPC32 p531) - DIP("stwbrx r%d,r%d,r%d\n", Rs_addr, Ra_addr, Rb_addr); - assign( w1, getIReg(Rs_addr) ); + DIP("stwbrx r%d,r%d,r%d\n", rS_addr, rA_addr, rB_addr); + assign( w1, getIReg(rS_addr) ); storeBE( mkexpr(EA), gen_byterev32(w1) ); break; @@ -3720,34 +3713,33 @@ static Bool dis_int_ldst_rev ( UInt theInstr ) */ static Bool dis_proc_ctl ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ + UChar opc1 = ifieldOPC(theInstr); /* X-Form */ - UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ - UChar b21to22 = toUChar((theInstr >> 21) & 0x3); /* theInstr[21:22] */ - UChar Rd_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UInt b11to20 = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ - + UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); + UChar b21to22 = toUChar( IFIELD( theInstr, 21, 2 ) ); + UChar rD_addr = ifieldRegDS(theInstr); + UInt b11to20 = IFIELD( theInstr, 11, 10 ); + /* XFX-Form */ - UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UInt SPR = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ - UInt TBR = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ - UChar b20 = toUChar((theInstr >> 11) & 0x1); /* theInstr[11] */ - UInt CRM = (theInstr >> 12) & 0xFF; /* theInstr[12:19] */ - UChar b11 = toUChar((theInstr >> 11) & 0x1); /* theInstr[20] */ - - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - UInt SPR_flipped = ((SPR & 0x1F) << 5) | ((SPR >> 5) & 0x1F); + UChar rS_addr = rD_addr; + UInt SPR = b11to20; + UInt TBR = SPR; + UChar b20 = toUChar( IFIELD( theInstr, 20, 1 ) ); + UInt CRM = IFIELD( theInstr, 12, 8 ); + UChar b11 = toUChar( IFIELD( theInstr, 11, 1 ) ); + + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); - IRTemp Rs = newTemp(Ity_I32); -//uu IRTemp tmp = newTemp(Ity_I32); + /* Reorder SPR field as per PPC32 p470 */ + SPR = ((SPR & 0x1F) << 5) | ((SPR >> 5) & 0x1F); /* Reorder TBR field as per PPC32 p475 */ TBR = ((TBR & 31) << 5) | ((TBR >> 5) & 31); - assign( Rs, getIReg(Rs_addr) ); + IRTemp rS = newTemp(Ity_I32); + assign( rS, getIReg(rS_addr) ); if (opc1 != 0x1F || b0 != 0) { vex_printf("dis_proc_ctl(PPC32)(opc1|b0)\n"); @@ -3811,20 +3803,20 @@ static Bool dis_proc_ctl ( UInt theInstr ) vex_printf("dis_proc_ctl(PPC32)(mfcr,b11to20)\n"); return False; } - DIP("mfcr r%d\n", Rd_addr); - putIReg( Rd_addr, getEntireCR() ); + DIP("mfcr r%d\n", rD_addr); + putIReg( rD_addr, getEntireCR() ); break; /* XFX-Form */ case 0x153: // mfspr (Move from Special-Purpose Register, PPC32 p470) - switch (SPR_flipped) { // Choose a register... + switch (SPR) { // Choose a register... case 0x1: - DIP("mfxer r%d\n", Rd_addr); + DIP("mfxer r%d\n", rD_addr); /* sheesh [kebab] */ putIReg( - Rd_addr, + rD_addr, binop( Iop_Or32, binop( @@ -3860,16 +3852,16 @@ static Bool dis_proc_ctl ( UInt theInstr ) break; case 0x8: - DIP("mflr r%d\n", Rd_addr); - putIReg( Rd_addr, getSPR( PPC32_SPR_LR ) ); + DIP("mflr r%d\n", rD_addr); + putIReg( rD_addr, getSPR( PPC32_SPR_LR ) ); break; case 0x9: - DIP("mfctr r%d\n", Rd_addr); - putIReg( Rd_addr, getSPR( PPC32_SPR_CTR ) ); + DIP("mfctr r%d\n", rD_addr); + putIReg( rD_addr, getSPR( PPC32_SPR_CTR ) ); break; case 0x100: - DIP("mfvrsave r%d\n", Rd_addr); - putIReg( Rd_addr, getSPR( PPC32_SPR_VRSAVE ) ); + DIP("mfvrsave r%d\n", rD_addr); + putIReg( rD_addr, getSPR( PPC32_SPR_VRSAVE ) ); break; case 0x012: case 0x013: case 0x016: @@ -3886,8 +3878,8 @@ static Bool dis_proc_ctl ( UInt theInstr ) return False; default: - vex_printf("dis_proc_ctl(PPC32)(mfspr,SPR_flipped)(0x%x)\n", - SPR_flipped); + vex_printf("dis_proc_ctl(PPC32)(mfspr,SPR)(0x%x)\n", + SPR); return False; } break; @@ -3907,12 +3899,12 @@ static Bool dis_proc_ctl ( UInt theInstr ) switch (TBR) { case 269: - putIReg( Rd_addr, unop(Iop_64HIto32, mkexpr(val)) ); - DIP("mftbu r%d", Rd_addr); + putIReg( rD_addr, unop(Iop_64HIto32, mkexpr(val)) ); + DIP("mftbu r%d", rD_addr); break; case 268: - putIReg( Rd_addr, unop(Iop_64to32, mkexpr(val)) ); - DIP("mftb r%d", Rd_addr); + putIReg( rD_addr, unop(Iop_64to32, mkexpr(val)) ); + DIP("mftb r%d", rD_addr); break; default: return False; /* illegal instruction */ @@ -3925,53 +3917,53 @@ static Bool dis_proc_ctl ( UInt theInstr ) vex_printf("dis_proc_ctl(PPC32)(mtcrf,b11|b20)\n"); return False; } - DIP("mtcrf 0x%x,r%d\n", CRM, Rs_addr); - putCRfields ( mkexpr(Rs), CRM ); + DIP("mtcrf 0x%x,r%d\n", CRM, rS_addr); + putCRfields ( mkexpr(rS), CRM ); break; case 0x1D3: // mtspr (Move to Special-Purpose Register, PPC32 p483) - switch (SPR_flipped) { // Choose a register... + switch (SPR) { // Choose a register... case 0x1: - DIP("mtxer r%d\n", Rs_addr); + DIP("mtxer r%d\n", rS_addr); stmt(IRStmt_Put( OFFB_XER_SO, unop( Iop_32to8, binop( Iop_And32, - binop(Iop_Shr32, mkexpr(Rs), mkU8(31)), + binop(Iop_Shr32, mkexpr(rS), mkU8(31)), mkU32(1)) ) )); stmt(IRStmt_Put( OFFB_XER_OV, unop( Iop_32to8, binop( Iop_And32, - binop(Iop_Shr32, mkexpr(Rs), mkU8(30)), + binop(Iop_Shr32, mkexpr(rS), mkU8(30)), mkU32(1)) ) )); stmt(IRStmt_Put( OFFB_XER_CA, unop( Iop_32to8, binop( Iop_And32, - binop(Iop_Shr32, mkexpr(Rs), mkU8(29)), + binop(Iop_Shr32, mkexpr(rS), mkU8(29)), mkU32(1)) ) )); stmt(IRStmt_Put( OFFB_XER_BC, unop( Iop_32to8, - binop( Iop_And32, mkexpr(Rs), mkU32(0xFF)) ) + binop( Iop_And32, mkexpr(rS), mkU32(0xFF)) ) )); break; case 0x8: - DIP("mtlr r%d\n", Rs_addr); - putSPR( PPC32_SPR_LR, mkexpr(Rs) ); + DIP("mtlr r%d\n", rS_addr); + putSPR( PPC32_SPR_LR, mkexpr(rS) ); break; case 0x9: - DIP("mtctr r%d\n", Rs_addr); - putSPR( PPC32_SPR_CTR, mkexpr(Rs) ); + DIP("mtctr r%d\n", rS_addr); + putSPR( PPC32_SPR_CTR, mkexpr(rS) ); break; case 0x100: - DIP("mtvrsave r%d\n", Rs_addr); - putSPR( PPC32_SPR_VRSAVE, mkexpr(Rs) ); + DIP("mtvrsave r%d\n", rS_addr); + putSPR( PPC32_SPR_VRSAVE, mkexpr(rS) ); break; //zz //zz case 0x012: case 0x013: case 0x016: @@ -3988,8 +3980,8 @@ static Bool dis_proc_ctl ( UInt theInstr ) //zz return False; default: - vex_printf("dis_proc_ctl(PPC32)(mtspr,SPR_flipped)(%u)\n", - SPR_flipped); + vex_printf("dis_proc_ctl(PPC32)(mtspr,SPR)(%u)\n", + SPR); return False; } break; @@ -4010,12 +4002,12 @@ static Bool dis_cache_manage ( UInt theInstr, VexArchInfo* guest_archinfo ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar b21to25 = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar b21to25 = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); Int lineszB = guest_archinfo->ppc32_cache_line_szB; if (opc1 != 0x1F || b21to25 != 0 || b0 != 0) { @@ -4029,28 +4021,28 @@ static Bool dis_cache_manage ( UInt theInstr, switch (opc2) { //zz case 0x2F6: // dcba (Data Cache Block Allocate, PPC32 p380) //zz vassert(0); /* AWAITING TEST CASE */ -//zz DIP("dcba r%d,r%d\n", Ra_addr, Rb_addr); +//zz DIP("dcba r%d,r%d\n", rA_addr, rB_addr); //zz if (0) vex_printf("vex ppc32->IR: kludged dcba\n"); //zz break; case 0x056: // dcbf (Data Cache Block Flush, PPC32 p382) - DIP("dcbf r%d,r%d\n", Ra_addr, Rb_addr); + DIP("dcbf r%d,r%d\n", rA_addr, rB_addr); /* nop as far as vex is concerned */ if (0) vex_printf("vex ppc32->IR: kludged dcbf\n"); break; case 0x036: // dcbst (Data Cache Block Store, PPC32 p384) - DIP("dcbst r%d,r%d\n", Ra_addr, Rb_addr); + DIP("dcbst r%d,r%d\n", rA_addr, rB_addr); /* nop as far as vex is concerned */ break; case 0x116: // dcbt (Data Cache Block Touch, PPC32 p385) - DIP("dcbt r%d,r%d\n", Ra_addr, Rb_addr); + DIP("dcbt r%d,r%d\n", rA_addr, rB_addr); /* nop as far as vex is concerned */ break; case 0x0F6: // dcbtst (Data Cache Block Touch for Store, PPC32 p386) - DIP("dcbtst r%d,r%d\n", Ra_addr, Rb_addr); + DIP("dcbtst r%d,r%d\n", rA_addr, rB_addr); /* nop as far as vex is concerned */ break; @@ -4060,17 +4052,17 @@ static Bool dis_cache_manage ( UInt theInstr, IRTemp addr = newTemp(Ity_I32); IRExpr* irx_addr; UInt i; - DIP("dcbz r%d,r%d\n", Ra_addr, Rb_addr); + DIP("dcbz r%d,r%d\n", rA_addr, rB_addr); assign( EA, - binop( Iop_Add32, - getIReg(Rb_addr), - Ra_addr==0 ? mkU32(0) : getIReg(Ra_addr)) ); + binop( Iop_Add32, + getIReg(rB_addr), + rA_addr==0 ? mkU32(0) : getIReg(rA_addr)) ); /* Round EA down to the start of the containing block. */ assign( addr, - binop( Iop_And32, - mkexpr(EA), - mkU32( ~(lineszB-1) )) ); + binop( Iop_And32, + mkexpr(EA), + mkU32( ~(lineszB-1) )) ); for (i = 0; i < lineszB / 4; i++) { irx_addr = binop( Iop_Add32, mkexpr(addr), mkU32(i*4) ); @@ -4084,12 +4076,12 @@ static Bool dis_cache_manage ( UInt theInstr, /* Invalidate all translations containing code from the cache block at (rA|0) + rB. */ IRTemp addr = newTemp(Ity_I32); - DIP("icbi r%d,r%d\n", Ra_addr, Rb_addr); + DIP("icbi r%d,r%d\n", rA_addr, rB_addr); assign( addr, binop( Iop_Add32, - getIReg(Rb_addr), - Ra_addr==0 ? mkU32(0) : getIReg(Ra_addr)) ); + getIReg(rB_addr), + rA_addr==0 ? mkU32(0) : getIReg(rA_addr)) ); /* Round addr down to the start of the containing block. */ stmt( IRStmt_Put( @@ -4170,18 +4162,14 @@ static IRExpr* roundToSgl ( IRExpr* src ) */ static Bool dis_fp_load ( UInt theInstr ) { - /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar rA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar rB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - /* D-Form */ - UInt d_imm = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - Int exts_d_imm = extend_s_16to32(d_imm); + /* X-Form, D-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar frD_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); + Int d_simm16 = ifieldSIMM16(theInstr); IRTemp EA = newTemp(Ity_I32); IRTemp rA = newTemp(Ity_I32); @@ -4194,8 +4182,8 @@ static Bool dis_fp_load ( UInt theInstr ) switch(opc1) { case 0x30: // lfs (Load Float Single, PPC32 p441) - DIP("lfs fr%d,%d(r%d)\n", frD_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA_or_0)) ); + DIP("lfs fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA))) ); break; @@ -4204,15 +4192,15 @@ static Bool dis_fp_load ( UInt theInstr ) //zz vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n"); //zz return False; //zz } -//zz DIP("lfsu fr%d,%d(r%d)\n", frD_addr, exts_d_imm, rA_addr); -//zz assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA)) ); +//zz DIP("lfsu fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); +//zz assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); //zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA))) ); //zz putIReg( rA_addr, mkexpr(EA) ); //zz break; case 0x32: // lfd (Load Float Double, PPC32 p437) - DIP("lfd fr%d,%d(r%d)\n", frD_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA_or_0)) ); + DIP("lfd fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) ); break; @@ -4221,8 +4209,8 @@ static Bool dis_fp_load ( UInt theInstr ) vex_printf("dis_fp_load(PPC32)(instr,lfdu)\n"); return False; } - DIP("lfdu fr%d,%d(r%d)\n", frD_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA)) ); + DIP("lfdu fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) ); putIReg( rA_addr, mkexpr(EA) ); break; @@ -4289,18 +4277,14 @@ static Bool dis_fp_load ( UInt theInstr ) */ static Bool dis_fp_store ( UInt theInstr ) { - /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frS_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar rA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar rB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - - /* D-Form */ - UInt d_imm = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ - - Int exts_d_imm = extend_s_16to32(d_imm); + /* X-Form, D-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar frS_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); + Int d_simm16 = ifieldSIMM16(theInstr); IRTemp EA = newTemp(Ity_I32); IRTemp frS = newTemp(Ity_F64); @@ -4316,8 +4300,8 @@ static Bool dis_fp_store ( UInt theInstr ) switch(opc1) { case 0x34: // stfs (Store Float Single, PPC32 p518) - DIP("stfs fr%d,%d(r%d)\n", frS_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA_or_0)) ); + DIP("stfs fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); storeBE( mkexpr(EA), binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); break; @@ -4327,16 +4311,16 @@ static Bool dis_fp_store ( UInt theInstr ) //zz vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n"); //zz return False; //zz } -//zz DIP("stfsu fr%d,%d(r%d)\n", frS_addr, exts_d_imm, rA_addr); -//zz assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA)) ); +//zz DIP("stfsu fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); +//zz assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); //zz storeBE( mkexpr(EA), //zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); //zz putIReg( rA_addr, mkexpr(EA) ); //zz break; case 0x36: // stfd (Store Float Double, PPC32 p513) - DIP("stfd fr%d,%d(r%d)\n", frS_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA_or_0)) ); + DIP("stfd fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); storeBE( mkexpr(EA), mkexpr(frS) ); break; @@ -4345,8 +4329,8 @@ static Bool dis_fp_store ( UInt theInstr ) vex_printf("dis_fp_store(PPC32)(instr,stfdu)\n"); return False; } - DIP("stfdu fr%d,%d(r%d)\n", frS_addr, exts_d_imm, rA_addr); - assign( EA, binop(Iop_Add32, mkU32(exts_d_imm), mkexpr(rA)) ); + DIP("stfdu fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); storeBE( mkexpr(EA), mkexpr(frS) ); putIReg( rA_addr, mkexpr(EA) ); break; @@ -4422,14 +4406,14 @@ static Bool dis_fp_store ( UInt theInstr ) static Bool dis_fp_arith ( UInt theInstr ) { /* A-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar frA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar frC_addr = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ - UChar opc2 = toUChar((theInstr >> 1) & 0x1F); /* theInstr[1:5] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ - // Note: flag_Rc ignored as fp exceptions not supported. + UChar opc1 = ifieldOPC(theInstr); + UChar frD_addr = ifieldRegDS(theInstr); + UChar frA_addr = ifieldRegA(theInstr); + UChar frB_addr = ifieldRegB(theInstr); + UChar frC_addr = ifieldRegC(theInstr); + UChar opc2 = ifieldOPClo5(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); + // Note: flag_rC ignored as fp exceptions not supported. IRTemp frD = newTemp(Ity_F64); IRTemp frA = newTemp(Ity_F64); @@ -4448,7 +4432,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fdivs)\n"); return False; } - DIP("fdivs%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fdivs%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, roundToSgl( binop(Iop_DivF64, mkexpr(frA), mkexpr(frB)) )); break; @@ -4458,7 +4442,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fsubs)\n"); return False; } - DIP("fsubs%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fsubs%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, roundToSgl( binop(Iop_SubF64, mkexpr(frA), mkexpr(frB)) )); @@ -4469,7 +4453,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fadds)\n"); return False; } - DIP("fadds%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fadds%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, roundToSgl( binop(Iop_AddF64, mkexpr(frA), mkexpr(frB)) )); @@ -4480,7 +4464,7 @@ static Bool dis_fp_arith ( UInt theInstr ) //zz vex_printf("dis_fp_arith(PPC32)(instr,fsqrts)\n"); //zz return False; //zz } -//zz DIP("fsqrts%s fr%d,fr%d\n", flag_Rc ? "." : "", +//zz DIP("fsqrts%s fr%d,fr%d\n", flag_rC ? "." : "", //zz frD_addr, frB_addr); //zz assign( frD, roundToSgl( unop(Iop_SqrtF64, mkexpr(frB)) )); //zz break; @@ -4490,7 +4474,7 @@ static Bool dis_fp_arith ( UInt theInstr ) //zz vex_printf("dis_fp_arith(PPC32)(instr,fres)\n"); //zz return False; //zz } -//zz DIP("fres%s fr%d,fr%d\n", flag_Rc ? "." : "", +//zz DIP("fres%s fr%d,fr%d\n", flag_rC ? "." : "", //zz frD_addr, frB_addr); //zz DIP(" => not implemented\n"); //zz // CAB: Can we use one of the 128 bit SIMD Iop_Recip32F ops? @@ -4501,7 +4485,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fmuls)\n"); return False; } - DIP("fmuls%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmuls%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr); assign( frD, roundToSgl( binop(Iop_MulF64, mkexpr(frA), mkexpr(frC)) )); break; @@ -4519,7 +4503,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fdiv)\n"); return False; } - DIP("fdiv%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fdiv%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, binop( Iop_DivF64, mkexpr(frA), mkexpr(frB) ) ); break; @@ -4529,7 +4513,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fsub)\n"); return False; } - DIP("fsub%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fsub%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, binop( Iop_SubF64, mkexpr(frA), mkexpr(frB) ) ); break; @@ -4539,7 +4523,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fadd)\n"); return False; } - DIP("fadd%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fadd%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frB_addr); assign( frD, binop( Iop_AddF64, mkexpr(frA), mkexpr(frB) ) ); break; @@ -4549,7 +4533,7 @@ static Bool dis_fp_arith ( UInt theInstr ) //zz vex_printf("dis_fp_arith(PPC32)(instr,fsqrt)\n"); //zz return False; //zz } -//zz DIP("fsqrt%s fr%d,fr%d\n", flag_Rc ? "." : "", +//zz DIP("fsqrt%s fr%d,fr%d\n", flag_rC ? "." : "", //zz frD_addr, frB_addr); //zz assign( frD, unop( Iop_SqrtF64, mkexpr(frB) ) ); //zz break; @@ -4558,7 +4542,7 @@ static Bool dis_fp_arith ( UInt theInstr ) IRTemp cc = newTemp(Ity_I32); IRTemp cc_b0 = newTemp(Ity_I32); - DIP("fsel%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fsel%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); // cc: UN == 0x41, LT == 0x01, GT == 0x00, EQ == 0x40 @@ -4582,7 +4566,7 @@ static Bool dis_fp_arith ( UInt theInstr ) vex_printf("dis_fp_arith(PPC32)(instr,fmul)\n"); return False; } - DIP("fmul%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmul%s fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr); assign( frD, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) ) ); break; @@ -4592,7 +4576,7 @@ static Bool dis_fp_arith ( UInt theInstr ) //zz vex_printf("dis_fp_arith(PPC32)(instr,frsqrte)\n"); //zz return False; //zz } -//zz DIP("frsqrte%s fr%d,fr%d\n", flag_Rc ? "." : "", +//zz DIP("frsqrte%s fr%d,fr%d\n", flag_rC ? "." : "", //zz frD_addr, frB_addr); //zz DIP(" => not implemented\n"); //zz // CAB: Iop_SqrtF64, then one of the 128 bit SIMD Iop_Recip32F ops? @@ -4621,13 +4605,13 @@ static Bool dis_fp_arith ( UInt theInstr ) static Bool dis_fp_multadd ( UInt theInstr ) { /* A-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar frA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar frC_addr = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ - UChar opc2 = toUChar((theInstr >> 1) & 0x1F); /* theInstr[1:5] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar frD_addr = ifieldRegDS(theInstr); + UChar frA_addr = ifieldRegA(theInstr); + UChar frB_addr = ifieldRegB(theInstr); + UChar frC_addr = ifieldRegC(theInstr); + UChar opc2 = ifieldOPClo5(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); IRTemp frD = newTemp(Ity_F64); IRTemp frA = newTemp(Ity_F64); @@ -4642,7 +4626,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) case 0x3B: switch (opc2) { case 0x1C: // fmsubs (Floating Mult-Subtr Single, PPC32 p412) - DIP("fmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, roundToSgl( binop( Iop_SubF64, @@ -4651,7 +4635,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1D: // fmadds (Floating Mult-Add Single, PPC32 p409) - DIP("fmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, roundToSgl( binop( Iop_AddF64, @@ -4660,7 +4644,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1E: // fnmsubs (Float Neg Mult-Subtr Single, PPC32 p420) - DIP("fnmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fnmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, roundToSgl( unop(Iop_NegF64, @@ -4670,7 +4654,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1F: // fnmadds (Floating Negative Multiply-Add Single, PPC32 p418) - DIP("fnmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fnmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, roundToSgl( unop(Iop_NegF64, @@ -4688,7 +4672,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) case 0x3F: switch (opc2) { case 0x1C: // fmsub (Float Mult-Subtr (Double Precision), PPC32 p411) - DIP("fmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, binop( Iop_SubF64, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) ), @@ -4696,7 +4680,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1D: // fmadd (Float Mult-Add (Double Precision), PPC32 p408) - DIP("fmadd%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fmadd%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, binop( Iop_AddF64, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) ), @@ -4704,7 +4688,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1E: // fnmsub (Float Neg Mult-Subtr (Double Precision), PPC32 p419) - DIP("fnmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fnmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, unop( Iop_NegF64, binop( Iop_SubF64, @@ -4713,7 +4697,7 @@ static Bool dis_fp_multadd ( UInt theInstr ) break; case 0x1F: // fnmadd (Float Neg Mult-Add (Double Precision), PPC32 p417) - DIP("fnmadd%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "", + DIP("fnmadd%s fr%d,fr%d,fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frA_addr, frC_addr, frB_addr); assign( frD, unop( Iop_NegF64, binop( Iop_AddF64, @@ -4744,27 +4728,19 @@ static Bool dis_fp_multadd ( UInt theInstr ) static Bool dis_fp_cmp ( UInt theInstr ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ - UChar b21to22 = toUChar((theInstr >> 21) & 0x3); /* theInstr[21:22] */ - UChar frA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); + UChar b21to22 = toUChar( IFIELD( theInstr, 21, 2 ) ); + UChar frA_addr = ifieldRegA(theInstr); + UChar frB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp ccIR = newTemp(Ity_I32); IRTemp ccPPC32 = newTemp(Ity_I32); -#if 0 - IRTemp cc_lt = newTemp(Ity_I32); - IRTemp cc_gt = newTemp(Ity_I32); - IRTemp cc_eq = newTemp(Ity_I32); - IRTemp cc_un = newTemp(Ity_I32); -#endif - IRTemp frA = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); -// IRExpr* irx; if (opc1 != 0x3F || b21to22 != 0 || b0 != 0) { vex_printf("dis_fp_cmp(PPC32)(instr)\n"); @@ -4810,7 +4786,6 @@ static Bool dis_fp_cmp ( UInt theInstr ) // Note: Differences between fcmpu and fcmpo are only // in exception flag settings, which aren't supported anyway... - opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ switch (opc2) { case 0x000: // fcmpu (Floating Compare Unordered, PPC32 p403) DIP("fcmpu crf%d,fr%d,fr%d\n", crfD, frA_addr, frB_addr); @@ -4834,12 +4809,12 @@ static Bool dis_fp_cmp ( UInt theInstr ) static Bool dis_fp_round ( UInt theInstr ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar b16to20 = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar frD_addr = ifieldRegDS(theInstr); + UChar b16to20 = ifieldRegA(theInstr); + UChar frB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); IRTemp frD = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); @@ -4852,24 +4827,22 @@ static Bool dis_fp_round ( UInt theInstr ) assign( frB, getFReg(frB_addr)); - opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - switch (opc2) { case 0x00C: // frsp (Floating Round to Single, PPC32 p423) - DIP("frsp%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("frsp%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( frD, roundToSgl( mkexpr(frB) )); break; case 0x00E: // fctiw (Floating Conv to Int, PPC32 p404) - DIP("fctiw%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fctiw%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( r_tmp, binop(Iop_F64toI32, get_roundingmode(), mkexpr(frB)) ); assign( frD, unop( Iop_ReinterpI64asF64, unop( Iop_32Uto64, mkexpr(r_tmp)))); break; case 0x00F: // fctiwz (Floating Conv to Int, Round to Zero, PPC32 p405) - DIP("fctiwz%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fctiwz%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( r_tmp, binop(Iop_F64toI32, mkU32(0x3), mkexpr(frB)) ); assign( frD, unop( Iop_ReinterpI64asF64, unop( Iop_32Uto64, mkexpr(r_tmp)))); @@ -4892,12 +4865,12 @@ static Bool dis_fp_round ( UInt theInstr ) static Bool dis_fp_move ( UInt theInstr ) { /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar b16to20 = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + UChar opc1 = ifieldOPC(theInstr); + UChar frD_addr = ifieldRegDS(theInstr); + UChar b16to20 = ifieldRegA(theInstr); + UChar frB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); IRTemp frD = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); @@ -4909,27 +4882,25 @@ static Bool dis_fp_move ( UInt theInstr ) assign( frB, getFReg(frB_addr)); - opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - switch (opc2) { case 0x028: // fneg (Floating Negate, PPC32 p416) - DIP("fneg%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fneg%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( frD, unop( Iop_NegF64, mkexpr(frB) )); break; case 0x048: // fmr (Floating Move Register, PPC32 p410) - DIP("fmr%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fmr%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( frD, mkexpr(frB) ); break; case 0x088: // fnabs (Floating Negative Absolute Value, PPC32 p415) - DIP("fnabs%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fnabs%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( frD, unop( Iop_NegF64, unop( Iop_AbsF64, mkexpr(frB) ))); break; case 0x108: // fabs (Floating Absolute Value, PPC32 p399) - DIP("fabs%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_addr); + DIP("fabs%s fr%d,fr%d\n", flag_rC ? "." : "", frD_addr, frB_addr); assign( frD, unop( Iop_AbsF64, mkexpr(frB) )); break; @@ -4949,11 +4920,10 @@ static Bool dis_fp_move ( UInt theInstr ) */ static Bool dis_fp_scr ( UInt theInstr ) { - /* X-Form */ - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - /* Too many forms - see each switch case */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + /* Many forms - see each switch case */ + UChar opc1 = ifieldOPC(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar flag_rC = ifieldBIT0(theInstr); if (opc1 != 0x3F) { vex_printf("dis_fp_scr(PPC32)(instr)\n"); @@ -4963,27 +4933,27 @@ static Bool dis_fp_scr ( UInt theInstr ) switch (opc2) { //zz case 0x026: { // mtfsb1 (Move to FPSCR Bit 1, PPC32 p479) //zz // Bit crbD of the FPSCR is set. -//zz UChar crbD = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ -//zz UInt b11to20 = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ +//zz UChar crbD = ifieldRegDS(theInstr); +//zz UInt b11to20 = IFIELD(theInstr, 11, 10); //zz //zz if (b11to20 != 0) { //zz vex_printf("dis_fp_scr(PPC32)(instr,mtfsb1)\n"); //zz return False; //zz } -//zz DIP("mtfsb1%s crb%d \n", flag_Rc ? "." : "", crbD); +//zz DIP("mtfsb1%s crb%d \n", flag_rC ? "." : "", crbD); //zz putReg_bit( PPC32_SPR_FPSCR, mkU32(1), 31-crbD ); //zz break; //zz } //zz //zz case 0x040: { // mcrfs (Move to Condition Register from FPSCR, PPC32 p465) -//zz UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ -//zz UChar b21to22 = toUChar((theInstr >> 21) & 0x3); /* theInstr[21:22] */ -//zz UChar crfS = toUChar((theInstr >> 18) & 0x7); /* theInstr[18:20] */ -//zz UChar b11to17 = toUChar((theInstr >> 11) & 0x7F); /* theInstr[11:17] */ +//zz UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); +//zz UChar b21to22 = toUChar( IFIELD( theInstr, 21, 2 ) ); +//zz UChar crfS = toUChar( IFIELD( theInstr, 18, 3 ) ); +//zz UChar b11to17 = toUChar( IFIELD( theInstr, 11, 7 ) ); //zz //zz IRTemp tmp = newTemp(Ity_I32); //zz -//zz if (b21to22 != 0 || b11to17 != 0 || flag_Rc != 0) { +//zz if (b21to22 != 0 || b11to17 != 0 || flag_rC != 0) { //zz vex_printf("dis_fp_scr(PPC32)(instr,mcrfs)\n"); //zz return False; //zz } @@ -4995,42 +4965,42 @@ static Bool dis_fp_scr ( UInt theInstr ) case 0x046: { // mtfsb0 (Move to FPSCR Bit 0, PPC32 p478) // Bit crbD of the FPSCR is cleared. - UChar crbD = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UInt b11to20 = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ + UChar crbD = ifieldRegDS(theInstr); + UInt b11to20 = IFIELD(theInstr, 11, 10); if (b11to20 != 0) { vex_printf("dis_fp_scr(PPC32)(instr,mtfsb0)\n"); return False; } - DIP("mtfsb0%s crb%d\n", flag_Rc ? "." : "", crbD); + DIP("mtfsb0%s crb%d\n", flag_rC ? "." : "", crbD); putReg_bit( PPC32_SPR_FPSCR, mkU32(0), 31-crbD ); break; } case 0x086: { // mtfsfi (Move to FPSCR Field Immediate, PPC32 p481) - UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ - UChar b16to22 = toUChar((theInstr >> 16) & 0x7F); /* theInstr[16:22] */ - UChar IMM = toUChar((theInstr >> 12) & 0xF); /* theInstr[11:15] */ - UChar b11 = toUChar((theInstr >> 11) & 0x1); /* theInstr[11] */ + UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); + UChar b16to22 = toUChar( IFIELD( theInstr, 16, 7 ) ); + UChar IMM = toUChar( IFIELD( theInstr, 12, 4 ) ); + UChar b11 = toUChar( IFIELD( theInstr, 11, 1 ) ); if (b16to22 != 0 || b11 != 0) { vex_printf("dis_fp_scr(PPC32)(instr,mtfsfi)\n"); return False; } - DIP("mtfsfi%s crf%d,%d\n", flag_Rc ? "." : "", crfD, IMM); + DIP("mtfsfi%s crf%d,%d\n", flag_rC ? "." : "", crfD, IMM); putReg_field( PPC32_SPR_FPSCR, mkU32(IMM), 7-crfD ); break; } case 0x247: { // mffs (Move from FPSCR, PPC32 p468) - UChar frD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UInt b11to20 = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ + UChar frD_addr = ifieldRegDS(theInstr); + UInt b11to20 = IFIELD(theInstr, 11, 10); if (b11to20 != 0) { vex_printf("dis_fp_scr(PPC32)(instr,mffs)\n"); return False; } - DIP("mffs%s fr%d\n", flag_Rc ? "." : "", frD_addr); + DIP("mffs%s fr%d\n", flag_rC ? "." : "", frD_addr); putFReg( frD_addr, unop( Iop_ReinterpI64asF64, unop( Iop_32Uto64, getReg_masked( PPC32_SPR_FPSCR, 0x3 ) ))); @@ -5038,24 +5008,24 @@ static Bool dis_fp_scr ( UInt theInstr ) } case 0x2C7: { // mtfsf (Move to FPSCR Fields, PPC32 p480) - UChar b25 = toUChar((theInstr >> 25) & 0x1); /* theInstr[25] */ - UChar FM = toUChar((theInstr >> 17) & 0xFF); /* theInstr[17:24] */ - UChar b16 = toUChar((theInstr >> 16) & 0x1); /* theInstr[16] */ - UChar frB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - IRTemp frB = newTemp(Ity_F64); + UChar b25 = toUChar( IFIELD(theInstr, 25, 1) ); + UChar FM = toUChar( IFIELD(theInstr, 17, 8) ); + UChar b16 = toUChar( IFIELD(theInstr, 16, 1) ); + UChar frB_addr = ifieldRegB(theInstr); + IRTemp frB = newTemp(Ity_F64); IRTemp rB_32 = newTemp(Ity_I32); - Int mask = 0; - Int i = 0; + Int i, mask; if (b25 != 0 || b16 != 0) { vex_printf("dis_fp_scr(PPC32)(instr,mtfsf)\n"); return False; } - DIP("mtfsf%s %d,fr%d\n", flag_Rc ? "." : "", FM, frB_addr); + DIP("mtfsf%s %d,fr%d\n", flag_rC ? "." : "", FM, frB_addr); assign( frB, getFReg(frB_addr)); assign( rB_32, unop( Iop_64to32, unop( Iop_ReinterpF64asI64, mkexpr(frB) ))); // Build 32bit mask from FM: + mask = 0; for (i=0; i<8; i++) { if ((FM & (1<<(7-i))) == 1) { mask |= 0xF << (7-i); @@ -5083,15 +5053,16 @@ static Bool dis_fp_scr ( UInt theInstr ) */ static Bool dis_av_datastream ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar flag_T = toUChar((theInstr >> 25) & 0x1); /* theInstr[25] */ - UChar flag_A = toUChar((theInstr >> 25) & 0x1); /* theInstr[25] */ - UChar b23to24 = toUChar((theInstr >> 23) & 0x3); /* theInstr[23:24] */ - UChar STRM = toUChar((theInstr >> 21) & 0x3); /* theInstr[21:22] */ - UChar rA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar rB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + /* X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar flag_T = toUChar( IFIELD( theInstr, 25, 1 ) ); + UChar flag_A = flag_T; + UChar b23to24 = toUChar( IFIELD( theInstr, 23, 2 ) ); + UChar STRM = toUChar( IFIELD( theInstr, 21, 2 ) ); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); if (opc1 != 0x1F || b23to24 != 0 || b0 != 0) { vex_printf("dis_av_datastream(PPC32)(instr)\n"); @@ -5135,11 +5106,12 @@ static Bool dis_av_datastream ( UInt theInstr ) */ static Bool dis_av_procctl ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); if (opc1 != 0x4) { vex_printf("dis_av_procctl(PPC32)(instr)\n"); @@ -5179,12 +5151,13 @@ static Bool dis_av_procctl ( UInt theInstr ) */ static Bool dis_av_load ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar rA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar rB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + /* X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp EA = newTemp(Ity_I32); IRTemp EA_aligned = newTemp(Ity_I32); @@ -5291,12 +5264,13 @@ static Bool dis_av_load ( UInt theInstr ) */ static Bool dis_av_store ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vS_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar rA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar rB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ - UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ + /* X-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vS_addr = ifieldRegDS(theInstr); + UChar rA_addr = ifieldRegA(theInstr); + UChar rB_addr = ifieldRegB(theInstr); + UInt opc2 = ifieldOPClo10(theInstr); + UChar b0 = ifieldBIT0(theInstr); IRTemp vS = newTemp(Ity_V128); IRTemp EA = newTemp(Ity_I32); @@ -5380,11 +5354,12 @@ static Bool dis_av_store ( UInt theInstr ) */ static Bool dis_av_arith ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -5829,11 +5804,12 @@ static Bool dis_av_arith ( UInt theInstr ) */ static Bool dis_av_logic ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -5854,7 +5830,7 @@ static Bool dis_av_logic ( UInt theInstr ) case 0x444: // vandc (And, AV p148) DIP("vandc v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr); putVReg( vD_addr, binop(Iop_AndV128, mkexpr(vA), - unop(Iop_NotV128, mkexpr(vB))) ); + unop(Iop_NotV128, mkexpr(vB))) ); break; case 0x484: // vor (Or, AV p217) @@ -5885,12 +5861,13 @@ static Bool dis_av_logic ( UInt theInstr ) */ static Bool dis_av_cmp ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar flag_Rc = toUChar((theInstr >> 10) & 0x1); /* theInstr[10] */ - UInt opc2 = (theInstr >> 0) & 0x3FF; /* theInstr[0:9] */ + /* VXR-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UChar flag_rC = ifieldBIT10(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 10 ); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -5905,47 +5882,47 @@ static Bool dis_av_cmp ( UInt theInstr ) switch (opc2) { case 0x006: // vcmpequb (Compare Equal-to Unsigned B, AV p160) - DIP("vcmpequb%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpequb%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpEQ8x16, mkexpr(vA), mkexpr(vB)) ); break; case 0x046: // vcmpequh (Compare Equal-to Unsigned HW, AV p161) - DIP("vcmpequh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpequh%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpEQ16x8, mkexpr(vA), mkexpr(vB)) ); break; case 0x086: // vcmpequw (Compare Equal-to Unsigned W, AV p162) - DIP("vcmpequw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpequw%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpEQ32x4, mkexpr(vA), mkexpr(vB)) ); break; case 0x206: // vcmpgtub (Compare Greater-than Unsigned B, AV p168) - DIP("vcmpgtub%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtub%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT8Ux16, mkexpr(vA), mkexpr(vB)) ); break; case 0x246: // vcmpgtuh (Compare Greater-than Unsigned HW, AV p169) - DIP("vcmpgtuh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtuh%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT16Ux8, mkexpr(vA), mkexpr(vB)) ); break; case 0x286: // vcmpgtuw (Compare Greater-than Unsigned W, AV p170) - DIP("vcmpgtuw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtuw%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT32Ux4, mkexpr(vA), mkexpr(vB)) ); break; case 0x306: // vcmpgtsb (Compare Greater-than Signed B, AV p165) - DIP("vcmpgtsb%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtsb%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT8Sx16, mkexpr(vA), mkexpr(vB)) ); break; case 0x346: // vcmpgtsh (Compare Greater-than Signed HW, AV p166) - DIP("vcmpgtsh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtsh%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT16Sx8, mkexpr(vA), mkexpr(vB)) ); break; case 0x386: // vcmpgtsw (Compare Greater-than Signed W, AV p167) - DIP("vcmpgtsw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtsw%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT32Sx4, mkexpr(vA), mkexpr(vB)) ); break; @@ -5956,7 +5933,7 @@ static Bool dis_av_cmp ( UInt theInstr ) putVReg( vD_addr, mkexpr(vD) ); - if (flag_Rc) { + if (flag_rC) { set_AV_CR6( mkexpr(vD), True ); } return True; @@ -5967,12 +5944,13 @@ static Bool dis_av_cmp ( UInt theInstr ) */ static Bool dis_av_multarith ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar vC_addr = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ - UChar opc2 = toUChar((theInstr >> 0) & 0x3F); /* theInstr[0:5] */ + /* VA-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UChar vC_addr = ifieldRegC(theInstr); + UChar opc2 = toUChar( IFIELD( theInstr, 0, 6 ) ); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -6220,11 +6198,12 @@ static Bool dis_av_multarith ( UInt theInstr ) */ static Bool dis_av_shift ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -6356,18 +6335,18 @@ static Bool dis_av_shift ( UInt theInstr ) */ static Bool dis_av_permute ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar UIMM_5 = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar SIMM_5 = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar vC_addr = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ - UChar b10 = toUChar((theInstr >> 10) & 0x1); /* theInstr[10] */ - UChar SHB_uimm4 = toUChar((theInstr >> 6) & 0xF); /* theInstr[6:9] */ - UInt opc2 = (theInstr >> 0) & 0x3F; /* theInstr[0:5] */ - - UChar SIMM_8 = extend_s_5to8(SIMM_5); + /* VA-Form, VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar UIMM_5 = vA_addr; + UChar vB_addr = ifieldRegB(theInstr); + UChar vC_addr = ifieldRegC(theInstr); + UChar b10 = ifieldBIT10(theInstr); + UChar SHB_uimm4 = toUChar( IFIELD( theInstr, 6, 4 ) ); + UInt opc2 = toUChar( IFIELD( theInstr, 0, 6 ) ); + + UChar SIMM_8 = extend_s_5to8(UIMM_5); IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); @@ -6435,7 +6414,7 @@ static Bool dis_av_permute ( UInt theInstr ) break; // Fall through... } - opc2 = (theInstr) & 0x7FF; /* theInstr[0:10] */ + opc2 = IFIELD( theInstr, 0, 11 ); switch (opc2) { /* Merge */ @@ -6530,16 +6509,17 @@ static Bool dis_av_permute ( UInt theInstr ) */ static Bool dis_av_pack ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); IRTemp signs = IRTemp_INVALID; IRTemp zeros = IRTemp_INVALID; - IRTemp vA = newTemp(Ity_V128); - IRTemp vB = newTemp(Ity_V128); + IRTemp vA = newTemp(Ity_V128); + IRTemp vB = newTemp(Ity_V128); assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); @@ -6783,11 +6763,12 @@ static Bool dis_av_pack ( UInt theInstr ) */ static Bool dis_av_fp_arith ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar vC_addr = toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10] */ + /* VA-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UChar vC_addr = ifieldRegC(theInstr); UInt opc2=0; IRTemp vA = newTemp(Ity_V128); @@ -6802,7 +6783,7 @@ static Bool dis_av_fp_arith ( UInt theInstr ) return False; } - opc2 = (theInstr) & 0x3F; /* theInstr[0:5] */ + opc2 = IFIELD( theInstr, 0, 6 ); switch (opc2) { case 0x2E: // vmaddfp (Multiply Add FP, AV p177) DIP("vmaddfp v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vC_addr, vB_addr); @@ -6822,7 +6803,7 @@ static Bool dis_av_fp_arith ( UInt theInstr ) break; // Fall through... } - opc2 = (theInstr) & 0x7FF; /* theInstr[0:10] */ + opc2 = IFIELD( theInstr, 0, 11 ); switch (opc2) { case 0x00A: // vaddfp (Add FP, AV p137) DIP("vaddfp v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr); @@ -6887,12 +6868,13 @@ static Bool dis_av_fp_arith ( UInt theInstr ) */ static Bool dis_av_fp_cmp ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar vA_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UChar flag_Rc = toUChar((theInstr >> 10) & 0x1); /* theInstr[10] */ - UInt opc2 = (theInstr >> 0) & 0x3FF; /* theInstr[0:9] */ + /* VXR-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar vA_addr = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UChar flag_rC = ifieldBIT10(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 10 ); Bool cmp_bounds = False; @@ -6909,17 +6891,17 @@ static Bool dis_av_fp_cmp ( UInt theInstr ) switch (opc2) { case 0x0C6: // vcmpeqfp (Compare Equal-to FP, AV p159) - DIP("vcmpeqfp%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpeqfp%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpEQ32Fx4, mkexpr(vA), mkexpr(vB)) ); break; case 0x1C6: // vcmpgefp (Compare Greater-than-or-Equal-to FP, AV p163) - DIP("vcmpgefp%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgefp%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGE32Fx4, mkexpr(vA), mkexpr(vB)) ); break; case 0x2C6: // vcmpgtfp (Compare Greater-than FP, AV p164) - DIP("vcmpgtfp%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpgtfp%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); assign( vD, binop(Iop_CmpGT32Fx4, mkexpr(vA), mkexpr(vB)) ); break; @@ -6927,7 +6909,7 @@ static Bool dis_av_fp_cmp ( UInt theInstr ) IRTemp gt = newTemp(Ity_V128); IRTemp lt = newTemp(Ity_V128); IRTemp zeros = newTemp(Ity_V128); - DIP("vcmpbfp%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr); + DIP("vcmpbfp%s v%d,v%d,v%d\n", (flag_rC ? ".":""), vD_addr, vA_addr, vB_addr); cmp_bounds = True; assign( zeros, unop(Iop_Dup32x4, mkU32(0)) ); @@ -6962,7 +6944,7 @@ static Bool dis_av_fp_cmp ( UInt theInstr ) putVReg( vD_addr, mkexpr(vD) ); - if (flag_Rc) { + if (flag_rC) { set_AV_CR6( mkexpr(vD), !cmp_bounds ); } return True; @@ -6973,14 +6955,15 @@ static Bool dis_av_fp_cmp ( UInt theInstr ) */ static Bool dis_av_fp_convert ( UInt theInstr ) { - UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ - UChar vD_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ - UChar UIMM_5 = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ - UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ - UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */ - - IRTemp vB = newTemp(Ity_V128); - IRTemp vScale = newTemp(Ity_V128); + /* VX-Form */ + UChar opc1 = ifieldOPC(theInstr); + UChar vD_addr = ifieldRegDS(theInstr); + UChar UIMM_5 = ifieldRegA(theInstr); + UChar vB_addr = ifieldRegB(theInstr); + UInt opc2 = IFIELD( theInstr, 0, 11 ); + + IRTemp vB = newTemp(Ity_V128); + IRTemp vScale = newTemp(Ity_V128); IRTemp vInvScale = newTemp(Ity_V128); assign( vB, getVReg(vB_addr)); @@ -7142,18 +7125,9 @@ DisResult disInstr_PPC32_WRK ( } } - - opc1 = toUChar(ifieldOPC(theInstr)); + opc1 = ifieldOPC(theInstr); opc2 = ifieldOPClo10(theInstr); -#if 0 //PPC32_TOIR_DEBUG - vex_printf("\ndisInstr(ppc32): instr: 0x%x\n", theInstr); - vex_printf("disInstr(ppc32): instr: "); - vex_printf_binary( theInstr, 32, True ); - vex_printf("\n"); -#endif - - // Note: all 'reserved' bits must be cleared, else invalid switch (opc1) { @@ -7228,7 +7202,8 @@ DisResult disInstr_PPC32_WRK ( case 0x3B: if (!allow_FP) goto decode_failure; - opc2 = (theInstr >> 1) & 0x1F; /* theInstr[1:5] */ + + opc2 = IFIELD(theInstr, 1, 5); switch (opc2) { /* Floating Point Arith Instructions */ case 0x12: case 0x14: case 0x15: // fdivs, fsubs, fadds @@ -7252,7 +7227,7 @@ DisResult disInstr_PPC32_WRK ( /* Instrs using opc[1:5] never overlap with instrs using opc[1:10], so we can simply fall through the first switch statement */ - opc2 = (theInstr >> 1) & 0x1F; /* theInstr[1:5] */ + opc2 = IFIELD(theInstr, 1, 5); switch (opc2) { /* Floating Point Arith Instructions */ case 0x12: case 0x14: case 0x15: // fdiv, fsub, fadd @@ -7271,7 +7246,7 @@ DisResult disInstr_PPC32_WRK ( break; // Fall through } - opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ + opc2 = IFIELD(theInstr, 1, 10); switch (opc2) { /* Floating Point Compare Instructions */ case 0x000: // fcmpu @@ -7338,7 +7313,7 @@ DisResult disInstr_PPC32_WRK ( /* For arith instns, bit10 is the OE flag (overflow enable) */ - opc2 = (theInstr >> 1) & 0x1FF; /* theInstr[1:9] */ + opc2 = IFIELD(theInstr, 1, 9); switch (opc2) { /* Integer Arithmetic Instructions */ case 0x10A: case 0x00A: case 0x08A: // add, addc, adde @@ -7355,7 +7330,7 @@ DisResult disInstr_PPC32_WRK ( /* All remaining opcodes use full 10 bits. */ - opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ + opc2 = IFIELD(theInstr, 1, 10); switch (opc2) { /* Integer Compare Instructions */ case 0x000: case 0x020: // cmp, cmpl @@ -7486,7 +7461,7 @@ DisResult disInstr_PPC32_WRK ( case 0x04: /* AltiVec instructions */ - opc2 = (theInstr) & 0x3F; /* theInstr[0:5] */ + opc2 = IFIELD(theInstr, 0, 6); switch (opc2) { /* AV Mult-Add, Mult-Sum */ case 0x20: case 0x21: case 0x22: // vmhaddshs, vmhraddshs, vmladduhm @@ -7514,7 +7489,7 @@ DisResult disInstr_PPC32_WRK ( break; // Fall through... } - opc2 = (theInstr) & 0x7FF; /* theInstr[0:10] */ + opc2 = IFIELD(theInstr, 0, 11); switch (opc2) { /* AV Arithmetic */ case 0x180: // vaddcuw @@ -7608,7 +7583,7 @@ DisResult disInstr_PPC32_WRK ( break; // Fall through... } - opc2 = (theInstr) & 0x3FF; /* theInstr[0:9] (Bit 10 = Rc)*/ + opc2 = IFIELD(theInstr, 0, 10); switch (opc2) { /* AV Compare */