- 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
+
*/
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. ---*/
/*--- Extract instruction fields --- */
/*------------------------------------------------------------*/
+/* Extract field from insn, given idx (zero = lsb) and field length */
+#define IFIELD( insn, idx, len ) ((insn >> idx) & ((1<<len)-1))
+
/* Extract primary opcode, instr[31:26] */
-static UInt ifieldOPC ( UInt instr ) {
- return (instr >> 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) --- */
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 ---*/
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 )
= 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;
= 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;
/* 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,
/* 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 {
*/
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;
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;
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)
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;
}
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;
}
*/
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;
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;
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;
}
*/
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 */
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:
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;
}
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:
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;
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;
}
*/
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 */
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:
*/
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 */
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:
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;
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;
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;
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;
}
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;
} 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<<where)) );
}
}
/*OUT*/DisResult* dres,
Bool (*resteerOkFn)(Addr64) )
{
- UChar opc1 = toUChar((theInstr >> 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;
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);
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,
}
/* 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) );
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);
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) );
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 */
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;
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)),
)
);
- /* 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));
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:
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;
}
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);
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,
//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;
*/
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");
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(
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:
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;
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 */
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:
//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;
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) {
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;
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) );
/* 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(
*/
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);
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;
//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;
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;
*/
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);
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;
//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;
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;
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);
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;
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)) ));
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)) ));
//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;
//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?
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;
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;
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;
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;
//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;
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
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;
//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?
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);
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,
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,
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,
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,
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) ),
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) ),
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,
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,
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");
// 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);
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);
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))));
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);
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;
*/
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");
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 }
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 ) )));
}
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);
*/
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");
*/
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");
*/
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);
*/
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);
*/
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);
*/
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);
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)
*/
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);
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;
putVReg( vD_addr, mkexpr(vD) );
- if (flag_Rc) {
+ if (flag_rC) {
set_AV_CR6( mkexpr(vD), True );
}
return True;
*/
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);
*/
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);
*/
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);
break; // Fall through...
}
- opc2 = (theInstr) & 0x7FF; /* theInstr[0:10] */
+ opc2 = IFIELD( theInstr, 0, 11 );
switch (opc2) {
/* Merge */
*/
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));
*/
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);
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);
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);
*/
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;
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;
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)) );
putVReg( vD_addr, mkexpr(vD) );
- if (flag_Rc) {
+ if (flag_rC) {
set_AV_CR6( mkexpr(vD), !cmp_bounds );
}
return True;
*/
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));
}
}
-
- 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) {
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
/* 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
break; // Fall through
}
- opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */
+ opc2 = IFIELD(theInstr, 1, 10);
switch (opc2) {
/* Floating Point Compare Instructions */
case 0x000: // fcmpu
/* 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
/* 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
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
break; // Fall through...
}
- opc2 = (theInstr) & 0x7FF; /* theInstr[0:10] */
+ opc2 = IFIELD(theInstr, 0, 11);
switch (opc2) {
/* AV Arithmetic */
case 0x180: // vaddcuw
break; // Fall through...
}
- opc2 = (theInstr) & 0x3FF; /* theInstr[0:9] (Bit 10 = Rc)*/
+ opc2 = IFIELD(theInstr, 0, 10);
switch (opc2) {
/* AV Compare */