|
From: <sv...@va...> - 2005-07-22 09:45:05
|
Author: sewardj
Date: 2005-07-22 10:39:02 +0100 (Fri, 22 Jul 2005)
New Revision: 1290
Log:
Partially successful effort to get FP working again.
Modified:
trunk/priv/guest-ppc32/toIR.c
Modified: trunk/priv/guest-ppc32/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc32/toIR.c 2005-07-22 09:38:21 UTC (rev 1289)
+++ trunk/priv/guest-ppc32/toIR.c 2005-07-22 09:39:02 UTC (rev 1290)
@@ -35,10 +35,12 @@
=20
/* TODO 2005 07 15:
=20
- make srawi etc use Sar32
+ Get rid of all vestiges of flag helper fns.
=20
- inline ppc32g_calculate_xer_ca; calling it out of line is a net
- performance loss and obscures from memcheck what's really happening
+ Spot rlwini cases which are simply left/right shifts and
+ emit Shl32/Shr32 accordingly.
+
+ Move mtxer/mfxer code into its own function.
*/
=20
=20
@@ -197,10 +199,10 @@
//zz #define SHIFT_CR_GT 4
//zz #define SHIFT_CR_EQ 2
//zz #define SHIFT_CR_SO 1
-//zz=20
-//zz #define SHIFT_FPSCR_RN 0
-//zz #define MASK_FPSCR_RN (3 << SHIFT_FPSCR_RN)
-//zz=20
+
+#define SHIFT_FPSCR_RN 0
+#define MASK_FPSCR_RN (3 << SHIFT_FPSCR_RN)
+
//zz #define SHIFT_VSCR_NJ 16
//zz #define SHIFT_VSCR_SAT 0
=20
@@ -212,10 +214,10 @@
PPC32_SPR_CTR, // Count Register
//zz PPC32_SPR_XER, // Summary Overflow
//zz PPC32_SPR_CR, // Condition Register
-//zz PPC32_SPR_FPSCR, // Floating Point Status/Control Register
+ PPC32_SPR_FPSCR, // Floating Point Status/Control Register
PPC32_SPR_VRSAVE, // Vector Save/Restore Register
//zz PPC32_SPR_VSCR, // Vector Status and Control Register
-//zz PPC32_SPR_MAX
+ PPC32_SPR_MAX
} PPC32SPR;
=20
//zz /*
@@ -252,13 +254,13 @@
static void putSPR ( PPC32SPR reg, IRExpr* src );
//zz static void putReg_field ( PPC32SPR reg, IRExpr* src, UInt field_i=
dx );
//zz static void putReg_bit ( PPC32SPR reg, IRExpr* src, UInt bit_idx=
);
-//zz=20
-//zz /* FP Helpers */
-//zz static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ );
=20
+/* FP Helpers */
+static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ );
=20
=20
=20
+
/*------------------------------------------------------------*/
/*--- Misc Helpers ---*/
/*------------------------------------------------------------*/
@@ -1190,75 +1192,37 @@
=20
=20
=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Abstract register interface --- */
-//zz /*------------------------------------------------------------*/
-//zz /* Most registers are represented directly in the cpu_state,
-//zz but CR is represented by a thunk */
-//zz=20
-//zz=20
-//zz /* Get a masked word from the given reg */
-//zz static IRExpr* getReg_masked ( PPC32SPR reg, UInt mask )
-//zz {
-//zz IRTemp val =3D newTemp(Ity_I32);
-//zz vassert( reg < PPC32_SPR_MAX );
-//zz =20
-//zz switch (reg) {
-//zz case PPC32_SPR_CIA:
-//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
-//zz assign( val, IRExpr_Get(OFFB_CIA, Ity_I32) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_LR:
-//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
-//zz assign( val, IRExpr_Get(OFFB_LR, Ity_I32) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_CTR:
-//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
-//zz assign( val, IRExpr_Get(OFFB_CTR, Ity_I32) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_XER:
-//zz // Bits 7-28 are 'Reserved'. Always return zero for these bi=
ts.
-//zz // (They may be written to, but reading them gives zero or un=
defined)
-//zz mask =3D mask & 0xE000007F;
-//zz assign( val, IRExpr_Get(OFFB_XER, Ity_I32) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_CR:
-//zz if ((mask & 0xF0000000) =3D=3D mask) { // CR7 only
-//zz // Call helper function to calculate latest CR7 from thunk=
:
-//zz assign( val, mk_ppc32g_calculate_cr7() );
-//zz }
-//zz else if ((mask & 0x0FFFFFFF) =3D=3D mask) { // CR0to6 only
-//zz assign( val, IRExpr_Get(OFFB_CR0to6, Ity_I32) );
-//zz }
-//zz else { // Both
-//zz assign( val, binop(Iop_Or32, mk_ppc32g_calculate_cr7(),
-//zz IRExpr_Get(OFFB_CR0to6, Ity_I32)) );
-//zz }
-//zz break;
-//zz=20
-//zz case PPC32_SPR_FPSCR: {
-//zz vassert((mask & 0x3) =3D=3D 0x3 || (mask & 0x3) =3D=3D=
0x0);
-//zz vassert((mask & 0xF000) =3D=3D 0xF000 || (mask & 0xF000) =3D=3D=
0x0);
-//zz /* all masks now refer to valid fields */
-//zz =20
-//zz /* Vex-generated code expects to run with the FPSCR set as fo=
llows:
-//zz all exceptions masked, round-to-nearest.
-//zz This corresponds to a FPSCR value of 0x0. */
-//zz=20
-//zz /* We're only keeping track of the rounding mode,
-//zz so if the mask isn't asking for this, just return 0x0 */
-//zz if (mask & 0x3) {
-//zz assign( val, IRExpr_Get(OFFB_FPROUND, Ity_I32) );
-//zz } else {
-//zz assign( val, mkU32(0x0) );
-//zz }
-//zz break; =20
-//zz }
-//zz=20
+/*------------------------------------------------------------*/
+/*--- Abstract register interface --- */
+/*------------------------------------------------------------*/
+
+/* Get a masked word from the given reg */
+static IRExpr* getReg_masked ( PPC32SPR reg, UInt mask )
+{
+ IRTemp val =3D newTemp(Ity_I32);
+ vassert( reg < PPC32_SPR_MAX );
+ =20
+ switch (reg) {
+
+ case PPC32_SPR_FPSCR: {
+ vassert((mask & 0x3) =3D=3D 0x3 || (mask & 0x3) =3D=3D 0x=
0);
+ vassert((mask & 0xF000) =3D=3D 0xF000 || (mask & 0xF000) =3D=3D 0x=
0);
+ /* all masks now refer to valid fields */
+ =20
+ /* 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. */
+
+ /* We're only keeping track of the rounding mode,
+ so if the mask isn't asking for this, just return 0x0 */
+ if (mask & 0x3) {
+ assign( val, IRExpr_Get(OFFB_FPROUND, Ity_I32) );
+ } else {
+ assign( val, mkU32(0x0) );
+ }
+ break; =20
+ }
+
//zz case PPC32_SPR_VRSAVE:
//zz assign( val, IRExpr_Get(OFFB_VRSAVE, Ity_I32) );
//zz break;
@@ -1268,18 +1232,18 @@
//zz mask =3D mask & 0x00010001;
//zz assign( val, IRExpr_Get(OFFB_VSCR, Ity_I32) );
//zz break;
-//zz=20
-//zz default:
-//zz vpanic("getReg(ppc32)");
-//zz }
-//zz=20
-//zz if (mask !=3D 0xFFFFFFFF) {
-//zz return binop(Iop_And32, mkexpr(val), mkU32(mask));
-//zz } else {
-//zz return mkexpr(val);
-//zz }
-//zz }
-//zz=20
+
+ default:
+ vpanic("getReg(ppc32)");
+ }
+
+ if (mask !=3D 0xFFFFFFFF) {
+ return binop(Iop_And32, mkexpr(val), mkU32(mask));
+ } else {
+ return mkexpr(val);
+ }
+}
+
//zz /* Get word from the given reg */
//zz static IRExpr* getReg ( PPC32SPR reg )
//zz {
@@ -1318,96 +1282,58 @@
//zz }
//zz return val;
//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /* Write masked src to the given reg */
-//zz static void putReg_masked ( PPC32SPR reg, IRExpr* src, UInt mask )
-//zz {
-//zz vassert( reg < PPC32_SPR_MAX );
-//zz vassert( typeOfIRExpr(irbb->tyenv,src ) =3D=3D Ity_I32 );
-//zz =20
-//zz switch (reg) {
+
+
+
+/* Write masked src to the given reg */
+static void putReg_masked ( PPC32SPR reg, IRExpr* src, UInt mask )
+{
+ vassert( reg < PPC32_SPR_MAX );
+ vassert( typeOfIRExpr(irbb->tyenv,src ) =3D=3D Ity_I32 );
+ =20
+ switch (reg) {
//zz case PPC32_SPR_CIA:
//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
//zz stmt( IRStmt_Put( OFFB_CIA, src ) );
//zz break;
-//zz=20
-//zz case PPC32_SPR_LR:
-//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
-//zz stmt( IRStmt_Put( OFFB_LR, src ) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_CTR:
-//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
-//zz stmt( IRStmt_Put( OFFB_CTR, src ) );
-//zz break;
-//zz=20
-//zz case PPC32_SPR_XER:
-//zz // Bits 7-28 are 'Reserved'. Ignoring writes these bits.
-//zz // (They may be written to, but reading them gives zero or un=
defined)
-//zz stmt( IRStmt_Put( OFFB_XER,
-//zz binop(Iop_Or32,
-//zz binop(Iop_And32, src, mkU32(mask & 0xE000007F)=
),
-//zz getReg_masked( PPC32_SPR_XER, (~mask & 0xE0000=
07F) ))));
-//zz break;
-//zz=20
-//zz case PPC32_SPR_CR: {
-//zz if (mask & 0xF0000000) { // CR field 7:
-//zz /* Set the CR7 flags thunk */
-//zz stmt( IRStmt_Put( OFFB_CC_OP, mkU32(1)/*set imm value DE=
P1*/ ) );
-//zz stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)/*=3Dunused*/ ) );
-//zz stmt( IRStmt_Put( OFFB_CC_DEP1,
-//zz binop(Iop_Or32,
-//zz binop(Iop_And32, src, mkU32(mask & 0xF00000=
00)),
-//zz getReg_masked( PPC32_SPR_CR, (~mask & 0xF00=
00000) ))));
-//zz }
-//zz if (mask & 0x0FFFFFFF) { // CR fields 0 to 6:
-//zz stmt( IRStmt_Put( OFFB_CR0to6,
-//zz binop(Iop_Or32,
-//zz binop(Iop_And32, src, mkU32(mask & 0x0FFFFF=
FF)),
-//zz getReg_masked( PPC32_SPR_CR, (~mask & 0x0FF=
FFFFF) ))));
-//zz }
-//zz break;
-//zz }
-//zz=20
-//zz case PPC32_SPR_FPSCR: {
-//zz vassert((mask & 0x3) =3D=3D 0x3 || (mask & 0x3) =3D=3D=
0x0);
-//zz vassert((mask & 0xF000) =3D=3D 0xF000 || (mask & 0xF000) =3D=3D=
0x0);
-//zz /* all masks now refer to valid fields */
-//zz=20
-//zz /* Allow writes to Rounding Mode */
-//zz if (mask & 0x3) {
-//zz stmt( IRStmt_Put( OFFB_FPROUND,
-//zz binop(Iop_And32, src, mkU32(0x3)) ));
-//zz }
-//zz=20
-//zz /*
-//zz Give EmWarn for attempted writes to:
-//zz - Exception Controls
-//zz - Non-IEEE Mode
-//zz */
-//zz if (mask & 0xFC) { // Exception Control, Non-IEE mode
-//zz VexEmWarn ew =3D EmWarn_PPC32exns;
-//zz=20
-//zz /* If any of the src::exception_control bits are actually =
set,
-//zz side-exit to the next insn, reporting the warning,
-//zz so that Valgrind's dispatcher sees the warning. */
-//zz put_emwarn( mkU32(ew) );
-//zz stmt(=20
-//zz IRStmt_Exit(
-//zz binop(Iop_CmpNE32, mkU32(ew), mkU32(EmWarn_NONE)),
-//zz Ijk_EmWarn,
-//zz IRConst_U32(guest_CIA_curr_instr + 4)
-//zz )
-//zz );
-//zz }
-//zz=20
-//zz /*
-//zz Ignore all other writes
-//zz */
-//zz break;
-//zz=20
+
+ case PPC32_SPR_FPSCR:
+ vassert((mask & 0x3) =3D=3D 0x3 || (mask & 0x3) =3D=3D 0x=
0);
+ vassert((mask & 0xF000) =3D=3D 0xF000 || (mask & 0xF000) =3D=3D 0x=
0);
+ /* all masks now refer to valid fields */
+
+ /* Allow writes to Rounding Mode */
+ if (mask & 0x3) {
+ stmt( IRStmt_Put( OFFB_FPROUND,
+ binop(Iop_And32, src, mkU32(0x3)) ));
+ }
+
+ /*
+ Give EmWarn for attempted writes to:
+ - Exception Controls
+ - Non-IEEE Mode
+ */
+ if (mask & 0xFC) { // Exception Control, Non-IEE mode
+ VexEmWarn ew =3D EmWarn_PPC32exns;
+
+ /* If any of the src::exception_control bits are actually set,
+ side-exit to the next insn, reporting the warning,
+ so that Valgrind's dispatcher sees the warning. */
+ put_emwarn( mkU32(ew) );
+ stmt(=20
+ IRStmt_Exit(
+ binop(Iop_CmpNE32, mkU32(ew), mkU32(EmWarn_NONE)),
+ Ijk_EmWarn,
+ IRConst_U32(guest_CIA_curr_instr + 4)
+ )
+ );
+ }
+
+ /*
+ Ignore all other writes
+ */
+ break;
+
//zz case PPC32_SPR_VRSAVE:
//zz vassert(mask =3D=3D 0xFFFFFFFF); // Only ever need whole r=
eg
//zz stmt( IRStmt_Put( OFFB_VRSAVE, src ) );
@@ -1423,12 +1349,12 @@
//zz getReg_masked( PPC32_SPR_VSCR, (~mask & 0x0001=
0001) ))));
//zz break;
//zz }
-//zz=20
-//zz default:
-//zz vpanic("putReg(ppc32)");
-//zz }
-//zz }
-//zz=20
+
+ default:
+ vpanic("putReg(ppc32)");
+ }
+}
+
//zz /* Write src to the given reg */
//zz static void putReg ( PPC32SPR reg, IRExpr* src )
//zz {
@@ -3135,11 +3061,11 @@
//zz assign( crbD, binop(Iop_And32, mkexpr(crbA),
//zz unop(Iop_Not32, mkexpr(crbB))) );
//zz break;
-//zz case 0x121: // creqv (Cond Reg Equivalent, PPC32 p374)
-//zz DIP("creqv crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, crb=
B_addr);
-//zz assign( crbD, unop(Iop_Not32,
-//zz binop(Iop_Xor32, mkexpr(crbA), mkexpr(c=
rbB))) );
-//zz break;
+ case 0x121: // creqv (Cond Reg Equivalent, PPC32 p374)
+ DIP("creqv crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, crbB_add=
r);
+ assign( crbD, unop(Iop_Not32,
+ binop(Iop_Xor32, mkexpr(crbA), mkexpr(crbB))=
) );
+ break;
//zz case 0x0E1: // crnand (Cond Reg NAND, PPC32 p375)
//zz DIP("crnand crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, cr=
bB_addr);
//zz assign( crbD, unop(Iop_Not32,
@@ -3885,49 +3811,50 @@
}
=20
=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Floating Point Helpers ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz /* --- Set the emulation-warning pseudo-register. --- */
-//zz=20
-//zz static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ )
-//zz {
-//zz stmt( IRStmt_Put( OFFB_EMWARN, e ) );
-//zz }
-//zz=20
-//zz /* --------- Synthesise a 2-bit FPU rounding mode. --------- */
-//zz /* Produces a value in 0 .. 3, which is encoded as per the type
-//zz IRRoundingMode. PPC32RoundingMode encoding is different to
-//zz IRRoundingMode, so need to map it.
-//zz */
-//zz static IRExpr* /* :: Ity_I32 */ get_roundingmode ( void )
-//zz {
-//zz /*=20
-//zz rounding mode | PPC | IR
-//zz ------------------------
-//zz to nearest | 00 | 00
-//zz to zero | 01 | 11
-//zz to +infinity | 10 | 10
-//zz to -infinity | 11 | 01
-//zz */
-//zz IRTemp rm_PPC32 =3D newTemp(Ity_I32);
-//zz assign( rm_PPC32, getReg_masked( PPC32_SPR_FPSCR, MASK_FPSCR_RN =
) );
-//zz=20
-//zz // rm_IR =3D XOR( rm_PPC32, (rm_PPC32 << 1) & 2)
-//zz return binop(Iop_Xor32, mkexpr(rm_PPC32),
-//zz binop(Iop_And32, mkU32(2),
-//zz binop(Iop_Shl32, mkexpr(rm_PPC32), mkU8(1))))=
;
-//zz }
-//zz=20
-//zz /* Round float to single precision
-//zz - returns type Ity_F64 */
-//zz static IRExpr* roundToSgl ( IRExpr* src )
-//zz {
-//zz return unop(Iop_F32toF64, binop(Iop_F64toF32, get_roundingmode()=
, src));
-//zz }
+/*------------------------------------------------------------*/
+/*--- Floating Point Helpers ---*/
+/*------------------------------------------------------------*/
=20
+/* --- Set the emulation-warning pseudo-register. --- */
=20
+static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ )
+{
+ vassert(typeOfIRExpr(irbb->tyenv,e) =3D=3D Ity_I32);
+ stmt( IRStmt_Put( OFFB_EMWARN, e ) );
+}
+
+/* --------- Synthesise a 2-bit FPU rounding mode. --------- */
+/* Produces a value in 0 .. 3, which is encoded as per the type
+ IRRoundingMode. PPC32RoundingMode encoding is different to
+ IRRoundingMode, so need to map it.
+*/
+static IRExpr* /* :: Ity_I32 */ get_roundingmode ( void )
+{
+/*=20
+ rounding mode | PPC | IR
+ ------------------------
+ to nearest | 00 | 00
+ to zero | 01 | 11
+ to +infinity | 10 | 10
+ to -infinity | 11 | 01
+*/
+ IRTemp rm_PPC32 =3D newTemp(Ity_I32);
+ assign( rm_PPC32, getReg_masked( PPC32_SPR_FPSCR, MASK_FPSCR_RN ) );
+
+ // rm_IR =3D XOR( rm_PPC32, (rm_PPC32 << 1) & 2)
+ return binop(Iop_Xor32, mkexpr(rm_PPC32),
+ binop(Iop_And32, mkU32(2),
+ binop(Iop_Shl32, mkexpr(rm_PPC32), mkU8(1))));
+}
+
+/* Round float to single precision
+ - returns type Ity_F64 */
+static IRExpr* roundToSgl ( IRExpr* src )
+{
+ return unop(Iop_F32toF64, binop(Iop_F64toF32, get_roundingmode(), src=
));
+}
+
+
/*------------------------------------------------------------*/
/*--- Floating Point Instruction Translation ---*/
/*------------------------------------------------------------*/
@@ -3960,12 +3887,12 @@
assign( rA_or_0, (rA_addr =3D=3D 0) ? mkU32(0) : mkexpr(rA) );
=20
switch(opc1) {
-//zz case 0x30: // lfs (Load Float Single, PPC32 p441)
-//zz DIP("lfs 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_or_=
0)) );
-//zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(=
EA))) );
-//zz break;
-//zz=20
+ 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)) )=
;
+ putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA)))=
);
+ break;
+
//zz case 0x31: // lfsu (Load Float Single with Update, PPC32 p442)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n");
@@ -3993,20 +3920,21 @@
//zz putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
//zz putIReg( rA_addr, mkexpr(EA) );
//zz break;
-//zz=20
-//zz case 0x1F:
-//zz if (b0 !=3D 0) {
-//zz vex_printf("dis_fp_load(PPC32)(instr,b0)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz switch(opc2) {
-//zz case 0x217: // lfsx (Load Float Single Indexed, PPC32 p444)
-//zz DIP("lfsx fr%d,r%d,r%d\n", frD_addr, rA_addr, rB_addr);
-//zz assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) =
);
-//zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkex=
pr(EA))) );
-//zz break;
-//zz=20
+
+ case 0x1F:
+ if (b0 !=3D 0) {
+ vex_printf("dis_fp_load(PPC32)(instr,b0)\n");
+ return False;
+ }
+
+ switch(opc2) {
+ case 0x217: // lfsx (Load Float Single Indexed, PPC32 p444)
+ DIP("lfsx fr%d,r%d,r%d\n", frD_addr, rA_addr, rB_addr);
+ assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) );
+ putFReg( frD_addr, unop( Iop_F32toF64,=20
+ loadBE(Ity_F32, mkexpr(EA))) );
+ break;
+
//zz case 0x237: // lfsux (Load Float Single with Update Indexed, =
PPC32 p443)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_load(PPC32)(instr,lfsux)\n");
@@ -4017,13 +3945,13 @@
//zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkex=
pr(EA))) );
//zz putIReg( rA_addr, mkexpr(EA) );
//zz break;
-//zz=20
-//zz case 0x257: // lfdx (Load Float Double Indexed, PPC32 p440)
-//zz DIP("lfdx fr%d,r%d,r%d\n", frD_addr, rA_addr, rB_addr);
-//zz assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) =
);
-//zz putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
-//zz break;
-//zz=20
+
+ case 0x257: // lfdx (Load Float Double Indexed, PPC32 p440)
+ DIP("lfdx fr%d,r%d,r%d\n", frD_addr, rA_addr, rB_addr);
+ assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) );
+ putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
+ break;
+
//zz case 0x277: // lfdux (Load Float Double with Update Indexed, =
PPC32 p439)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_load(PPC32)(instr,lfdux)\n");
@@ -4034,13 +3962,13 @@
//zz putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
//zz putIReg( rA_addr, mkexpr(EA) );
//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_load(PPC32)(opc2)\n");
-//zz return False;
-//zz }
-//zz break;
=20
+ default:
+ vex_printf("dis_fp_load(PPC32)(opc2)\n");
+ return False;
+ }
+ break;
+
default:
vex_printf("dis_fp_load(PPC32)(opc1)\n");
return False;
@@ -4080,13 +4008,14 @@
assign( rA_or_0, (rA_addr =3D=3D 0) ? mkU32(0) : mkexpr(rA) );
=20
switch(opc1) {
-//zz case 0x34: // stfs (Store Float Single, PPC32 p518)
-//zz DIP("stfs 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_or_=
0)) );
-//zz storeBE( mkexpr(EA),
-//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS))=
);
-//zz break;
-//zz=20
+
+ 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)) )=
;
+ storeBE( mkexpr(EA),
+ binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
+ break;
+
//zz case 0x35: // stfsu (Store Float Single with Update, PPC32 p519)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n");
@@ -4105,31 +4034,31 @@
storeBE( mkexpr(EA), mkexpr(frS) );
break;
=20
-//zz case 0x37: // stfdu (Store Float Double with Update, PPC32 p514)
-//zz if (rA_addr =3D=3D 0) {
-//zz vex_printf("dis_fp_store(PPC32)(instr,stfdu)\n");
-//zz return False;
-//zz }
-//zz DIP("stfdu 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 storeBE( mkexpr(EA), mkexpr(frS) );
-//zz putIReg( rA_addr, mkexpr(EA) );
-//zz break;
-//zz=20
-//zz case 0x1F:
-//zz if (b0 !=3D 0) {
-//zz vex_printf("dis_fp_store(PPC32)(instr,b0)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz switch(opc2) {
-//zz case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521)
-//zz DIP("stfsx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr);
-//zz assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) =
);
-//zz storeBE( mkexpr(EA),
-//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(fr=
S)) );
-//zz break;
-//zz=20
+ case 0x37: // stfdu (Store Float Double with Update, PPC32 p514)
+ if (rA_addr =3D=3D 0) {
+ 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)) );
+ storeBE( mkexpr(EA), mkexpr(frS) );
+ putIReg( rA_addr, mkexpr(EA) );
+ break;
+
+ case 0x1F:
+ if (b0 !=3D 0) {
+ vex_printf("dis_fp_store(PPC32)(instr,b0)\n");
+ return False;
+ }
+
+ switch(opc2) {
+ case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521)
+ DIP("stfsx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr);
+ assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) );
+ storeBE( mkexpr(EA),
+ binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)=
) );
+ break;
+
//zz case 0x2B7: // stfsux (Store Float Single with Update Indexed=
, PPC32 p520)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_store(PPC32)(instr,stfsux)\n");
@@ -4141,13 +4070,13 @@
//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(fr=
S)) );
//zz putIReg( rA_addr, mkexpr(EA) );
//zz break;
-//zz=20
-//zz case 0x2D7: // stfdx (Store Float Double Indexed, PPC32 p516)
-//zz DIP("stfdx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr);
-//zz assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) =
);
-//zz storeBE( mkexpr(EA), mkexpr(frS) );
-//zz break;
-//zz =20
+
+ case 0x2D7: // stfdx (Store Float Double Indexed, PPC32 p516)
+ DIP("stfdx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr);
+ assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) );
+ storeBE( mkexpr(EA), mkexpr(frS) );
+ break;
+ =20
//zz case 0x2F7: // stfdux (Store Float Double with Update Indexed=
, PPC32 p515)
//zz if (rA_addr =3D=3D 0) {
//zz vex_printf("dis_fp_store(PPC32)(instr,stfdux)\n");
@@ -4165,13 +4094,13 @@
//zz storeBE( mkexpr(EA),
//zz unop(Iop_64to32, unop(Iop_ReinterpF64asI64, mkexp=
r(frS))) );
//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_store(PPC32)(opc2)\n");
-//zz return False;
-//zz }
-//zz break;
=20
+ default:
+ vex_printf("dis_fp_store(PPC32)(opc2)\n");
+ return False;
+ }
+ break;
+
default:
vex_printf("dis_fp_store(PPC32)(opc1)\n");
return False;
@@ -4206,38 +4135,40 @@
assign( frC, getFReg(frC_addr));
=20
switch (opc1) {
-//zz case 0x3B:
-//zz switch (opc2) {
-//zz case 0x12: // fdivs (Floating Divide Single, PPC32 p407)
-//zz if (frC_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fdivs)\n");
-//zz return False;
-//zz }
-//zz DIP("fdivs%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frB_addr);
-//zz assign( frD, roundToSgl( binop(Iop_DivF64, mkexpr(frA), mk=
expr(frB)) ));
-//zz break;
-//zz=20
-//zz case 0x14: // fsubs (Floating Subtract Single, PPC32 p430)
-//zz if (frC_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fsubs)\n");
-//zz return False;
-//zz }
-//zz DIP("fsubs%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frB_addr);
-//zz assign( frD, roundToSgl( binop(Iop_SubF64, mkexpr(frA), mk=
expr(frB)) ));
-//zz break;
-//zz=20
-//zz case 0x15: // fadds (Floating Add Single, PPC32 p401)
-//zz if (frC_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fadds)\n");
-//zz return False;
-//zz }
-//zz DIP("fadds%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frB_addr);
-//zz assign( frD, roundToSgl( binop(Iop_AddF64, mkexpr(frA), mk=
expr(frB)) ));
-//zz break;
-//zz=20
+ case 0x3B:
+ switch (opc2) {
+ case 0x12: // fdivs (Floating Divide Single, PPC32 p407)
+ if (frC_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fdivs)\n");
+ return False;
+ }
+ 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;
+
+ case 0x14: // fsubs (Floating Subtract Single, PPC32 p430)
+ if (frC_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fsubs)\n");
+ return False;
+ }
+ DIP("fsubs%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
+ frD_addr, frA_addr, frB_addr);
+ assign( frD, roundToSgl(=20
+ binop(Iop_SubF64, mkexpr(frA), mkexpr(frB)) ));
+ break;
+
+ case 0x15: // fadds (Floating Add Single, PPC32 p401)
+ if (frC_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fadds)\n");
+ return False;
+ }
+ DIP("fadds%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
+ frD_addr, frA_addr, frB_addr);
+ assign( frD, roundToSgl(=20
+ binop(Iop_AddF64, mkexpr(frA), mkexpr(frB)) ));
+ break;
+
//zz case 0x16: // fsqrts (Floating SqRt (Single-Precision), PPC32=
p428)
//zz if (frA_addr !=3D 0 || frC_addr !=3D 0) {
//zz vex_printf("dis_fp_arith(PPC32)(instr,fsqrts)\n");
@@ -4247,7 +4178,7 @@
//zz frD_addr, frB_addr);
//zz assign( frD, roundToSgl( unop(Iop_SqrtF64, mkexpr(frB)) ))=
;
//zz break;
-//zz=20
+
//zz case 0x18: // fres (Floating Reciprocal Estimate Single, PPC3=
2 p421)
//zz if (frA_addr !=3D 0 || frC_addr !=3D 0) {
//zz vex_printf("dis_fp_arith(PPC32)(instr,fres)\n");
@@ -4258,45 +4189,45 @@
//zz DIP(" =3D> not implemented\n"); =20
//zz // CAB: Can we use one of the 128 bit SIMD Iop_Recip32F op=
s?
//zz return False;
-//zz=20
-//zz case 0x19: // fmuls (Floating Multiply Single, PPC32 p414)
-//zz if (frB_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fmuls)\n");
-//zz return False;
-//zz }
-//zz DIP("fmuls%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr);
-//zz assign( frD, roundToSgl( binop(Iop_MulF64, mkexpr(frA), mk=
expr(frC)) ));
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_arith(PPC32)(3B: opc2)\n");
-//zz return False;
-//zz }
-//zz break;
=20
+ case 0x19: // fmuls (Floating Multiply Single, PPC32 p414)
+ if (frB_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fmuls)\n");
+ return False;
+ }
+ 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;
+
+ default:
+ vex_printf("dis_fp_arith(PPC32)(3B: opc2)\n");
+ return False;
+ }
+ break;
+
case 0x3F:
switch (opc2) { =20
-//zz case 0x12: // fdiv (Floating Divide (Double-Precision), PPC32=
p406)
-//zz if (frC_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fdiv)\n");
-//zz return False;
-//zz }
-//zz DIP("fdiv%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frB_addr);
-//zz assign( frD, binop( Iop_DivF64, mkexpr(frA), mkexpr(frB) )=
);
-//zz break;
-//zz=20
-//zz case 0x14: // fsub (Floating Subtract (Double-Precision), PPC=
32 p429)
-//zz if (frC_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fsub)\n");
-//zz return False;
-//zz }
-//zz DIP("fsub%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frB_addr);
-//zz assign( frD, binop( Iop_SubF64, mkexpr(frA), mkexpr(frB) )=
);
-//zz break;
+ case 0x12: // fdiv (Floating Divide (Double-Precision), PPC32 p406=
)
+ if (frC_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fdiv)\n");
+ return False;
+ }
+ 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;
=20
+ case 0x14: // fsub (Floating Subtract (Double-Precision), PPC32 p4=
29)
+ if (frC_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fsub)\n");
+ return False;
+ }
+ 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;
+
case 0x15: // fadd (Floating Add (Double-Precision), PPC32 p400)
if (frC_addr !=3D 0) {
vex_printf("dis_fp_arith(PPC32)(instr,fadd)\n");
@@ -4316,40 +4247,40 @@
//zz frD_addr, frB_addr);
//zz assign( frD, unop( Iop_SqrtF64, mkexpr(frB) ) );
//zz break;
-//zz=20
-//zz case 0x17: { // fsel (Floating Select, PPC32 p426)
-//zz IRTemp cc =3D newTemp(Ity_I32);
-//zz IRTemp cc_b0 =3D newTemp(Ity_I32);
-//zz=20
-//zz DIP("fsel%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz=20
-//zz // cc: UN =3D=3D 0x41, LT =3D=3D 0x01, GT =3D=3D 0x00, EQ =
=3D=3D 0x40
-//zz // =3D> GT|EQ =3D=3D (cc & 0x1 =3D=3D 0)
-//zz assign( cc, binop(Iop_CmpF64, mkexpr(frA), IRExpr_Const(IR=
Const_F64(0))) );
-//zz assign( cc_b0, binop(Iop_And32, mkexpr(cc), mkU32(1)) );
-//zz=20
-//zz // frD =3D (frA >=3D 0.0) ? frC : frB
-//zz // =3D (cc_b0 =3D=3D 0) ? frC : frB
-//zz assign( frD,
-//zz IRExpr_Mux0X(
-//zz unop(Iop_1Uto8,
-//zz binop(Iop_CmpEQ32, mkexpr(cc_b0), mkU32(0)=
)),
-//zz mkexpr(frB),
-//zz mkexpr(frC) ));
-//zz break;
-//zz }
-//zz=20
-//zz case 0x19: // fmul (Floating Multiply (Double Precision), PPC=
32 p413)
-//zz if (frB_addr !=3D 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fmul)\n");
-//zz return False;
-//zz }
-//zz DIP("fmul%s fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr);
-//zz assign( frD, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) )=
);
-//zz break;
-//zz=20
+
+ case 0x17: { // fsel (Floating Select, PPC32 p426)
+ IRTemp cc =3D newTemp(Ity_I32);
+ IRTemp cc_b0 =3D newTemp(Ity_I32);
+
+ DIP("fsel%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
+ frD_addr, frA_addr, frC_addr, frB_addr);
+
+ // cc: UN =3D=3D 0x41, LT =3D=3D 0x01, GT =3D=3D 0x00, EQ =3D=3D=
0x40
+ // =3D> GT|EQ =3D=3D (cc & 0x1 =3D=3D 0)
+ assign( cc, binop(Iop_CmpF64, mkexpr(frA), IRExpr_Const(IRConst=
_F64(0))) );
+ assign( cc_b0, binop(Iop_And32, mkexpr(cc), mkU32(1)) );
+
+ // frD =3D (frA >=3D 0.0) ? frC : frB
+ // =3D (cc_b0 =3D=3D 0) ? frC : frB
+ assign( frD,
+ IRExpr_Mux0X(
+ unop(Iop_1Uto8,
+ binop(Iop_CmpEQ32, mkexpr(cc_b0), mkU32(0))),
+ mkexpr(frB),
+ mkexpr(frC) ));
+ break;
+ }
+
+ case 0x19: // fmul (Floating Multiply (Double Precision), PPC32 p4=
13)
+ if (frB_addr !=3D 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fmul)\n");
+ return False;
+ }
+ 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 case 0x1A: // frsqrte (Floating Reciprocal SqRt Estimate, PPC=
32 p424)
//zz if (frA_addr !=3D 0 || frC_addr !=3D 0) {
//zz vex_printf("dis_fp_arith(PPC32)(instr,frsqrte)\n");
@@ -4378,92 +4309,94 @@
=20
=20
=20
-//zz /*
-//zz Floating Point Mult-Add Instructions
-//zz */
-//zz static Bool dis_fp_multadd ( UInt theInstr )
-//zz {
-//zz /* A-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr=
[26:31] */
-//zz UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr=
[21:25] */
-//zz UChar frA_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr=
[16:20] */
-//zz UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr=
[11:15] */
-//zz UChar frC_addr =3D toUChar((theInstr >> 6) & 0x1F); /* theInstr=
[6:10] */
-//zz UChar opc2 =3D toUChar((theInstr >> 1) & 0x1F); /* theInstr=
[1:5] */
-//zz UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr=
[0] */
-//zz=20
-//zz IRTemp frD =3D newTemp(Ity_F64);
-//zz IRTemp frA =3D newTemp(Ity_F64);
-//zz IRTemp frB =3D newTemp(Ity_F64);
-//zz IRTemp frC =3D newTemp(Ity_F64);
-//zz=20
-//zz assign( frA, getFReg(frA_addr));
-//zz assign( frB, getFReg(frB_addr));
-//zz assign( frC, getFReg(frC_addr));
-//zz=20
-//zz switch (opc1) {
-//zz case 0x3B:
-//zz switch (opc2) {
-//zz case 0x1C: // fmsubs (Floating Mult-Subtr Single, PPC32 p412)
-//zz DIP("fmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, roundToSgl( binop(Iop_SubF64,
-//zz binop(Iop_MulF64, mkexpr(fr=
A), mkexpr(frC)),
-//zz mkexpr(frB)) ));
-//zz break;
-//zz=20
-//zz case 0x1D: // fmadds (Floating Mult-Add Single, PPC32 p409)
-//zz DIP("fmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, roundToSgl( binop(Iop_AddF64,
-//zz binop(Iop_MulF64, mkexpr(fr=
A), mkexpr(frC)),
-//zz mkexpr(frB)) ));
-//zz break;
-//zz=20
-//zz case 0x1E: // fnmsubs (Float Neg Mult-Subtr Single, PPC32 p42=
0)
-//zz DIP("fnmsubs%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, roundToSgl(
-//zz unop(Iop_NegF64,
-//zz binop(Iop_SubF64,
-//zz binop(Iop_MulF64, mkexpr(frA), mkexp=
r(frC)),
-//zz mkexpr(frB))) ));
-//zz break;
-//zz=20
-//zz case 0x1F: // fnmadds (Floating Negative Multiply-Add Single,=
PPC32 p418)
-//zz DIP("fnmadds%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, roundToSgl(
-//zz unop(Iop_NegF64,
-//zz binop(Iop_AddF64,
-//zz binop(Iop_MulF64, mkexpr(frA), mkexp=
r(frC)),
-//zz mkexpr(frB))) ));
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_multadd(PPC32)(3B: opc2)\n");
-//zz return False;
-//zz }
-//zz break;
-//zz=20
-//zz case 0x3F:
-//zz switch (opc2) { =20
-//zz case 0x1C: // fmsub (Float Mult-Subtr (Double Precision), PPC=
32 p411)
-//zz DIP("fmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, binop( Iop_SubF64,
-//zz binop( Iop_MulF64, mkexpr(frA), mkexpr=
(frC) ),
-//zz mkexpr(frB) ));
-//zz break;
-//zz=20
-//zz case 0x1D: // fmadd (Float Mult-Add (Double Precision), PPC32=
p408)
-//zz DIP("fmadd%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
-//zz frD_addr, frA_addr, frC_addr, frB_addr);
-//zz assign( frD, binop( Iop_AddF64,
-//zz binop( Iop_MulF64, mkexpr(frA), mkexpr=
(frC) ),
-//zz mkexpr(frB) ));
-//zz break;
-//zz=20
+/*
+ Floating Point Mult-Add Instructions
+*/
+static Bool dis_fp_multadd ( UInt theInstr )
+{
+ /* A-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:3=
1] */
+ UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:2=
5] */
+ UChar frA_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:2=
0] */
+ UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:1=
5] */
+ UChar frC_addr =3D toUChar((theInstr >> 6) & 0x1F); /* theInstr[6:10=
] */
+ UChar opc2 =3D toUChar((theInstr >> 1) & 0x1F); /* theInstr[1:5]=
*/
+ UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr[0] =
*/
+
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frA =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+ IRTemp frC =3D newTemp(Ity_F64);
+
+ assign( frA, getFReg(frA_addr));
+ assign( frB, getFReg(frB_addr));
+ assign( frC, getFReg(frC_addr));
+
+ switch (opc1) {
+ 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 ? "." : "",
+ frD_addr, frA_addr, frC_addr, frB_addr);
+ assign( frD, roundToSgl(=20
+ binop( Iop_SubF64,
+ binop(Iop_MulF64, mkexpr(frA), mkexpr(fr=
C)),
+ mkexpr(frB)) ));
+ break;
+
+ case 0x1D: // fmadds (Floating Mult-Add Single, PPC32 p409)
+ 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(=20
+ binop( Iop_AddF64,
+ binop(Iop_MulF64, mkexpr(frA), mkexpr(fr=
C)),
+ mkexpr(frB)) ));
+ 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 ? "." : "",
+ frD_addr, frA_addr, frC_addr, frB_addr);
+ assign( frD, roundToSgl(
+ unop(Iop_NegF64,
+ binop(Iop_SubF64,
+ binop(Iop_MulF64, mkexpr(frA), mkexpr(frC=
)),
+ mkexpr(frB))) ));
+ break;
+
+ case 0x1F: // fnmadds (Floating Negative Multiply-Add Single, PPC3=
2 p418)
+ 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,
+ binop(Iop_AddF64,
+ binop(Iop_MulF64, mkexpr(frA), mkexpr(frC=
)),
+ mkexpr(frB))) ));
+ break;
+
+ default:
+ vex_printf("dis_fp_multadd(PPC32)(3B: opc2)\n");
+ return False;
+ }
+ break;
+
+ case 0x3F:
+ switch (opc2) { =20
+ case 0x1C: // fmsub (Float Mult-Subtr (Double Precision), PPC32 p4=
11)
+ 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)=
),
+ mkexpr(frB) ));
+ 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 ? "." : "",
+ frD_addr, frA_addr, frC_addr, frB_addr);
+ assign( frD, binop( Iop_AddF64,
+ binop( Iop_MulF64, mkexpr(frA), mkexpr(frC)=
),
+ mkexpr(frB) ));
+ break;
+
//zz case 0x1E: // fnmsub (Float Neg Mult-Subtr (Double Precision)=
, PPC32 p419)
//zz DIP("fnmsub%s fr%d,fr%d,fr%d,fr%d\n", flag_Rc ? "." : "",
//zz frD_addr, frA_addr, frC_addr, frB_addr);
@@ -4481,239 +4414,247 @@
//zz binop( Iop_MulF64, mkexpr(frA), =
mkexpr(frC) ),
//zz mkexpr(frB) )));
//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_multadd(PPC32)(3F: opc2)\n");
-//zz return False;
-//zz }
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_multadd(PPC32)(opc1)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz putFReg( frD_addr, mkexpr(frD) );
-//zz return True;
-//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /*
-//zz Floating Point Compare Instructions
-//zz */
-//zz static Bool dis_fp_cmp ( UInt theInstr )
-//zz { =20
-//zz /* X-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr=
[26:31] */
-//zz UChar crfD =3D toUChar((theInstr >> 23) & 0x7); /* theInstr=
[23:25] */
-//zz UChar b21to22 =3D toUChar((theInstr >> 21) & 0x3); /* theInstr=
[21:22] */
-//zz UChar frA_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr=
[16:20] */
-//zz UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr=
[11:15] */ =20
-//zz UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr=
[1:10] */
-//zz UChar b0 =3D toUChar((theInstr >> 0) & 1); /* theInstr=
[0] */
-//zz=20
-//zz IRTemp ccIR =3D newTemp(Ity_I32);
-//zz IRTemp ccPPC32 =3D newTemp(Ity_I32);
-//zz=20
-//zz #if 0
-//zz IRTemp cc_lt =3D newTemp(Ity_I32);
-//zz IRTemp cc_gt =3D newTemp(Ity_I32);
-//zz IRTemp cc_eq =3D newTemp(Ity_I32);
-//zz IRTemp cc_un =3D newTemp(Ity_I32);
-//zz #endif
-//zz=20
-//zz IRTemp frA =3D newTemp(Ity_F64);
-//zz IRTemp frB =3D newTemp(Ity_F64);
-//zz // IRExpr* irx;
-//zz=20
-//zz if (opc1 !=3D 0x3F || b21to22 !=3D 0 || b0 !=3D 0) {
-//zz vex_printf("dis_fp_cmp(PPC32)(instr)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz assign( frA, getFReg(frA_addr));
-//zz assign( frB, getFReg(frB_addr));
-//zz=20
-//zz assign( ccIR, binop(Iop_CmpF64, mkexpr(frA), mkexpr(frB)) );
-//zz =20
-//zz /* Map compare result from IR to PPC32 */
-//zz /*
-//zz FP cmp result | PPC | IR
-//zz --------------------------
-//zz UN | 0x1 | 0x45
-//zz EQ | 0x2 | 0x40
-//zz GT | 0x4 | 0x00
-//zz LT | 0x8 | 0x01
-//zz */
-//zz=20
-//zz // ccPPC32 =3D Shl(1, (0x2 & ~(ccIR>>5)) || (0x1 & (XOR(ccIR, cc=
IR>>6))))
-//zz assign( ccPPC32,
-//zz binop(Iop_Shl32, mkU32(1),
-//zz unop(Iop_32to8,=20
-//zz binop(Iop_Or32,
-//zz binop(Iop_And32, mkU32(2),
-//zz unop(Iop_Not32,
-//zz binop(Iop_Shr32, mkexpr(ccIR=
), mkU8(5)))),
-//zz binop(Iop_And32, mkU32(1),
-//zz binop(Iop_Xor32, mkexpr(ccIR),
-//zz binop(Iop_Shr32, mkexpr(ccI=
R), mkU8(6))))))) );
-//zz=20
-//zz putReg_field( PPC32_SPR_CR, mkexpr(ccPPC32), 7-crfD );
-//zz=20
-//zz // CAB: Useful to support writing cc to FPSCR->FPCC ?
-//zz // putReg_field( PPC32_SPR_FPSCR, mkexpr(ccPPC32), 3 );
-//zz=20
-//zz // Note: Differences between fcmpu and fcmpo are only
-//zz // in exception flag settings, which aren't supported anyway...
-//zz opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */
-//zz switch (opc2) {
-//zz case 0x000: // fcmpu (Floating Compare Unordered, PPC32 p403)
-//zz DIP("fcmpu crf%d,fr%d,fr%d\n", crfD, frA_addr, frB_addr);
-//zz break;
-//zz=20
-//zz case 0x020: // fcmpo (Floating Compare Ordered, PPC32 p402)
-//zz DIP("fcmpo crf%d,fr%d,fr%d\n", crfD, frA_addr, frB_addr);
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_cmp(PPC32)(opc2)\n");
-//zz return False;
-//zz }
-//zz return True;
-//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /*
-//zz Floating Point Rounding/Conversion Instructions
-//zz */
-//zz static Bool dis_fp_round ( UInt theInstr )
-//zz {
-//zz /* X-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr=
[26:31] */
-//zz UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr=
[21:25] */
-//zz UChar b16to20 =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr=
[16:20] */
-//zz UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr=
[11:15] */
-//zz UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr=
[1:10] */
-//zz UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr=
[0] */
-//zz=20
-//zz IRTemp frD =3D newTemp(Ity_F64);
-//zz IRTemp frB =3D newTemp(Ity_F64);
-//zz IRTemp r_tmp =3D newTemp(Ity_I32);
-//zz=20
-//zz if (opc1 !=3D 0x3F || b16to20 !=3D 0) {
-//zz vex_printf("dis_fp_round(PPC32)(instr)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz assign( frB, getFReg(frB_addr));
-//zz=20
-//zz opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */
-//zz switch (opc2) {
-//zz case 0x00C: // frsp (Floating Round to Single, PPC32 p423)
-//zz DIP("frsp%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_a=
ddr);
-//zz assign( frD, roundToSgl( mkexpr(frB) ));
-//zz break;
-//zz=20
+
+ default:
+ vex_printf("dis_fp_multadd(PPC32)(3F: opc2)\n");
+ return False;
+ }
+ break;
+
+ default:
+ vex_printf("dis_fp_multadd(PPC32)(opc1)\n");
+ return False;
+ }
+
+ putFReg( frD_addr, mkexpr(frD) );
+ return True;
+}
+
+
+
+/*
+ Floating Point Compare Instructions
+*/
+static Bool dis_fp_cmp ( UInt theInstr )
+{ =20
+ /* X-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:3=
1] */
+ UChar crfD =3D toUChar((theInstr >> 23) & 0x7); /* theInstr[23:2=
5] */
+ UChar b21to22 =3D toUChar((theInstr >> 21) & 0x3); /* theInstr[21:2=
2] */
+ UChar frA_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:2=
0] */
+ UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:1=
5] */ =20
+ UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10=
] */
+ UChar b0 =3D toUChar((theInstr >> 0) & 1); /* theInstr[0] =
*/
+
+ IRTemp ccIR =3D newTemp(Ity_I32);
+ IRTemp ccPPC32 =3D newTemp(Ity_I32);
+
+#if 0
+ IRTemp cc_lt =3D newTemp(Ity_I32);
+ IRTemp cc_gt =3D newTemp(Ity_I32);
+ IRTemp cc_eq =3D newTemp(Ity_I32);
+ IRTemp cc_un =3D newTemp(Ity_I32);
+#endif
+
+ IRTemp frA =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+// IRExpr* irx;
+
+ if (opc1 !=3D 0x3F || b21to22 !=3D 0 || b0 !=3D 0) {
+ vex_printf("dis_fp_cmp(PPC32)(instr)\n");
+ return False;
+ }
+
+ assign( frA, getFReg(frA_addr));
+ assign( frB, getFReg(frB_addr));
+
+ assign( ccIR, binop(Iop_CmpF64, mkexpr(frA), mkexpr(frB)) );
+ =20
+ /* Map compare result from IR to PPC32 */
+ /*
+ FP cmp result | PPC | IR
+ --------------------------
+ UN | 0x1 | 0x45
+ EQ | 0x2 | 0x40
+ GT | 0x4 | 0x00
+ LT | 0x8 | 0x01
+ */
+
+ // ccPPC32 =3D Shl(1, (0x2 & ~(ccIR>>5)) || (0x1 & (XOR(ccIR, ccIR>>6=
))))
+ assign(
+ ccPPC32,
+ binop(Iop_Shl32, mkU32(1),
+ unop(Iop_32to8,=20
+ binop(Iop_Or32,
+ binop(Iop_And32, mkU32(2),
+ unop(Iop_Not32,
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(5)=
))),
+ binop(Iop_And32, mkU32(1),
+ binop(Iop_Xor32, mkexpr(ccIR),
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(6=
)))))))
+ );
+
+ putCR0( crfD, unop( Iop_32to8,=20
+ binop(Iop_And32, mkexpr(ccPPC32), mkU32(1))) );
+ putCR321( crfD, unop( Iop_32to8,=20
+ binop(Iop_And32, mkexpr(ccPPC32), mkU32(7<<1)))=
);
+
+ // CAB: Useful to support writing cc to FPSCR->FPCC ?
+ // putReg_field( PPC32_SPR_FPSCR, mkexpr(ccPPC32), 3 );
+
+ // Note: Differences between fcmpu and fcmpo are only
+ // in exception flag settings, which aren't supported anyway...
+ opc2 =3D (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);
+ break;
+
+ case 0x020: // fcmpo (Floating Compare Ordered, PPC32 p402)
+ DIP("fcmpo crf%d,fr%d,fr%d\n", crfD, frA_addr, frB_addr);
+ break;
+ default:
+ vex_printf("dis_fp_cmp(PPC32)(opc2)\n");
+ return False;
+ }
+ return True;
+}
+
+
+
+/*
+ Floating Point Rounding/Conversion Instructions
+*/
+static Bool dis_fp_round ( UInt theInstr )
+{
+ /* X-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:3=
1] */
+ UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:2=
5] */
+ UChar b16to20 =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:2=
0] */
+ UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:1=
5] */
+ UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10=
] */
+ UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr[0] =
*/
+
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+ IRTemp r_tmp =3D newTemp(Ity_I32);
+
+ if (opc1 !=3D 0x3F || b16to20 !=3D 0) {
+ vex_printf("dis_fp_round(PPC32)(instr)\n");
+ return False;
+ }
+
+ assign( frB, getFReg(frB_addr));
+
+ opc2 =3D (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_add=
r);
+ assign( frD, roundToSgl( mkexpr(frB) ));
+ break;
+
//zz case 0x00E: // fctiw (Floating Conv to Int, PPC32 p404)
//zz DIP("fctiw%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_=
addr);
//zz assign( r_tmp, binop(Iop_F64toI32, get_roundingmode(), mkexpr=
(frB)) );
//zz assign( frD, unop( Iop_ReinterpI64asF64,
//zz unop( Iop_32Uto64, mkexpr(r_tmp))));
//zz break;
-//zz=20
-//zz case 0x00F: // fctiwz (Floating Conv to Int, Round to Zero, PPC3=
2 p405)
-//zz DIP("fctiwz%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB=
_addr);
-//zz assign( r_tmp, binop(Iop_F64toI32, mkU32(0x3), mkexpr(frB)) )=
;
-//zz assign( frD, unop( Iop_ReinterpI64asF64,
-//zz unop( Iop_32Uto64, mkexpr(r_tmp))));
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_round(PPC32)(opc2)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz putFReg( frD_addr, mkexpr(frD) );
-//zz return True;
-//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /*
-//zz Floating Point Move Instructions
-//zz */
-//zz static Bool dis_fp_move ( UInt theInstr )
-//zz {
-//zz /* X-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr=
[26:31] */
-//zz UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr=
[21:25] */
-//zz UChar b16to20 =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr=
[16:20] */
-//zz UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr=
[11:15] */
-//zz UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr=
[1:10] */
-//zz UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr=
[0] */
-//zz=20
-//zz IRTemp frD =3D newTemp(Ity_F64);
-//zz IRTemp frB =3D newTemp(Ity_F64);
-//zz=20
-//zz if (opc1 !=3D 0x3F || b16to20 !=3D 0) {
-//zz vex_printf("dis_fp_move(PPC32)(instr)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz assign( frB, getFReg(frB_addr));
-//zz=20
-//zz opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */
-//zz switch (opc2) {
-//zz case 0x028: // fneg (Floating Negate, PPC32 p416)
-//zz DIP("fneg%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_a=
ddr);
-//zz assign( frD, unop( Iop_NegF64, mkexpr(frB) ));
-//zz break;
-//zz=20
-//zz case 0x048: // fmr (Floating Move Register, PPC32 p410)
-//zz DIP("fmr%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_ad=
dr);
-//zz assign( frD, mkexpr(frB) );
-//zz break;
-//zz=20
+
+ 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_a=
ddr);
+ assign( r_tmp, binop(Iop_F64toI32, mkU32(0x3), mkexpr(frB)) );
+ assign( frD, unop( Iop_ReinterpI64asF64,
+ unop( Iop_32Uto64, mkexpr(r_tmp))));
+ break;
+
+ default:
+ vex_printf("dis_fp_round(PPC32)(opc2)\n");
+ return False;
+ }
+
+ putFReg( frD_addr, mkexpr(frD) );
+ return True;
+}
+
+
+
+/*
+ Floating Point Move Instructions
+*/
+static Bool dis_fp_move ( UInt theInstr )
+{
+ /* X-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:3=
1] */
+ UChar frD_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:2=
5] */
+ UChar b16to20 =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:2=
0] */
+ UChar frB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:1=
5] */
+ UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10=
] */
+ UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr[0] =
*/
+
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+
+ if (opc1 !=3D 0x3F || b16to20 !=3D 0) {
+ vex_printf("dis_fp_move(PPC32)(instr)\n");
+ return False;
+ }
+
+ assign( frB, getFReg(frB_addr));
+
+ opc2 =3D (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_add=
r);
+ 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=
);
+ assign( frD, mkexpr(frB) );
+ break;
+
//zz case 0x088: // fnabs (Floating Negative Absolute Value, PPC32 p4=
15)
//zz DIP("fnabs%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_=
addr);
//zz assign( frD, unop( Iop_NegF64, unop( Iop_AbsF64, mkexpr(frB) =
)));
//zz break;
-//zz=20
-//zz case 0x108: // fabs (Floating Absolute Value, PPC32 p399)
-//zz DIP("fabs%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_a=
ddr);
-//zz assign( frD, unop( Iop_AbsF64, mkexpr(frB) ));
-//zz break;
-//zz=20
-//zz default:
-//zz vex_printf("dis_fp_move(PPC32)(opc2)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz putFReg( frD_addr, mkexpr(frD) );
-//zz return True;
-//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /*
-//zz Floating Point Status/Control Register Instructions
-//zz */
-//zz static Bool dis_fp_scr ( UInt theInstr )
-//zz {
-//zz /* X-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[=
26:31] */
-//zz /* Too many forms - see each switch case */
-//zz UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[=
1:10] */
-//zz UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr[=
0] */
-//zz=20
-//zz if (opc1 !=3D 0x3F) {
-//zz vex_printf("dis_fp_scr(PPC32)(instr)\n");
-//zz return False;
-//zz }
-//zz=20
-//zz switch (opc2) {
+
+ case 0x108: // fabs (Floating Absolute Value, PPC32 p399)
+ DIP("fabs%s fr%d,fr%d\n", flag_Rc ? "." : "", frD_addr, frB_add=
r);
+ assign( frD, unop( Iop_AbsF64, mkexpr(frB) ));
+ break;
+
+ default:
+ vex_printf("dis_fp_move(PPC32)(opc2)\n");
+ return False;
+ }
+
+ putFReg( frD_addr, mkexpr(frD) );
+ return True;
+}
+
+
+
+/*
+ Floating Point Status/Control Register Instructions
+*/
+static Bool dis_fp_scr ( UInt theInstr )
+{
+ /* X-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31=
] */
+ /* Too many forms - see each switch case */
+ UInt opc2 =3D (theInstr >> 1) & 0x3FF; /* theInstr[1:10]=
*/
+ UChar flag_Rc =3D toUChar((theInstr >> 0) & 1); /* theInstr[0] =
*/
+
+ if (opc1 !=3D 0x3F) {
+ vex_printf("dis_fp_scr(PPC32)(instr)\n");
+ return False;
+ }
+
+ switch (opc2) {
//zz case 0x026: { // mtfsb1 (Move to FPSCR Bit 1, PPC32 p479)
//zz // Bit crbD of the FPSCR is set.
//zz UChar crbD =3D toUChar((...
[truncated message content] |