case 0x34: // stfs (Store Float Single, PPC32 p518)
DIP("stfs fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
assign( EA, ea_rAor0_simm(rA_addr, simm16) );
+ /* TODO
+ This implementation ends up rounding twice, losing accuracy.
+ - first via F64toF32, and then by the backend fp store (stfs)
+ */
storeBE( mkexpr(EA),
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
break;
}
DIP("stfsu fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
assign( EA, ea_rA_simm(rA_addr, simm16) );
+ /* This implementation loses accuracy - see note for stfs */
storeBE( mkexpr(EA),
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
putIReg( rA_addr, mkexpr(EA) );
case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521)
DIP("stfsx fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
assign( EA, ea_rAor0_idxd(rA_addr, rB_addr) );
+ /* This implementation loses accuracy - see note for stfs */
storeBE( mkexpr(EA),
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
break;
}
DIP("stfsux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
+ /* This implementation loses accuracy - see note for stfs */
storeBE( mkexpr(EA),
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
putIReg( rA_addr, mkexpr(EA) );
assign( frD, binop( Iop_AddF64, mkexpr(frA), mkexpr(frB) ) );
break;
-//zz case 0x16: // fsqrt (Floating SqRt (Double-Precision), PPC32 p427)
-//zz if (frA_addr != 0 || frC_addr != 0) {
-//zz vex_printf("dis_fp_arith(PPC32)(instr,fsqrt)\n");
-//zz return False;
-//zz }
-//zz DIP("fsqrt%s fr%u,fr%u\n", flag_rC ? "." : "",
-//zz frD_addr, frB_addr);
-//zz assign( frD, unop( Iop_SqrtF64, mkexpr(frB) ) );
-//zz break;
+ case 0x16: // fsqrt (Floating SqRt (Double-Precision), PPC32 p427)
+ if (frA_addr != 0 || frC_addr != 0) {
+ vex_printf("dis_fp_arith(PPC32)(instr,fsqrt)\n");
+ return False;
+ }
+ DIP("fsqrt%s fr%u,fr%u\n", flag_rC ? "." : "",
+ frD_addr, frB_addr);
+ assign( frD, unop( Iop_SqrtF64, mkexpr(frB) ) );
+ break;
case 0x17: { // fsel (Floating Select, PPC32 p426)
IRTemp cc = newTemp(Ity_I32);