assign( frD, roundToSgl( unop(Iop_SqrtF64, mkexpr(frB)) ));
break;
-//zz case 0x18: // fres (Floating Reciprocal Estimate Single, PPC32 p421)
-//zz if (frA_addr != 0 || frC_addr != 0) {
-//zz vex_printf("dis_fp_arith(ppc)(instr,fres)\n");
-//zz return False;
-//zz }
-//zz DIP("fres%s fr%u,fr%u\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?
-//zz return False;
+ case 0x18: // fres (Floating Reciprocal Estimate Single, PPC32 p421)
+ if (frA_addr != 0 || frC_addr != 0) {
+ vex_printf("dis_fp_arith(ppc)(instr,fres)\n");
+ return False;
+ }
+ DIP("fres%s fr%u,fr%u\n", flag_rC ? ".":"",
+ frD_addr, frB_addr);
+ assign( frD, unop(Iop_Est8FRecip, mkexpr(frB)) );
+ break;
case 0x19: // fmuls (Floating Multiply Single, PPC32 p414)
if (frB_addr != 0) {
assign( frD, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) ) );
break;
-//zz case 0x1A: // frsqrte (Floating Recip SqRt Est., PPC32 p424)
-//zz if (frA_addr != 0 || frC_addr != 0) {
-//zz vex_printf("dis_fp_arith(ppc)(instr,frsqrte)\n");
-//zz return False;
-//zz }
-//zz DIP("frsqrte%s fr%u,fr%u\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?
-//zz return False;
+ case 0x1A: // frsqrte (Floating Recip SqRt Est., PPC32 p424)
+ if (frA_addr != 0 || frC_addr != 0) {
+ vex_printf("dis_fp_arith(ppc)(instr,frsqrte)\n");
+ return False;
+ }
+ DIP("frsqrte%s fr%u,fr%u\n", flag_rC ? ".":"",
+ frD_addr, frB_addr);
+ assign( frD, unop(Iop_Est5FRSqrt, mkexpr(frB)) );
+ break;
default:
vex_printf("dis_fp_arith(ppc)(3F: opc2)\n");
case Pfp_ABS: return "fabs";
case Pfp_NEG: return "fneg";
case Pfp_MOV: return "fmr";
+ case Pfp_RES: return "fres";
+ case Pfp_RSQRTE: return "frsqrte";
default: vpanic("showPPCFpOp");
}
}
UInt fr_dst = fregNo(i->Pin.FpUnary.dst);
UInt fr_src = fregNo(i->Pin.FpUnary.src);
switch (i->Pin.FpUnary.op) {
+ case Pfp_RSQRTE: // frsqrtre, PPC32 p424
+ p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 26, 0 );
+ break;
+ case Pfp_RES: // fres, PPC32 p421
+ p = mkFormA( p, 59, fr_dst, 0, fr_src, 0, 24, 0 );
+ break;
case Pfp_SQRT: // fsqrt, PPC32 p427
p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 22, 0 );
break;
Pfp_ADD, Pfp_SUB, Pfp_MUL, Pfp_DIV,
/* Unary */
- Pfp_SQRT, Pfp_ABS, Pfp_NEG, Pfp_MOV
+ Pfp_SQRT, Pfp_ABS, Pfp_NEG, Pfp_MOV, Pfp_RES, Pfp_RSQRTE
}
PPCFpOp;
if (e->tag == Iex_Unop) {
PPCFpOp fpop = Pfp_INVALID;
switch (e->Iex.Unop.op) {
- case Iop_NegF64: fpop = Pfp_NEG; break;
- case Iop_AbsF64: fpop = Pfp_ABS; break;
- case Iop_SqrtF64: fpop = Pfp_SQRT; break;
+ case Iop_NegF64: fpop = Pfp_NEG; break;
+ case Iop_AbsF64: fpop = Pfp_ABS; break;
+ case Iop_SqrtF64: fpop = Pfp_SQRT; break;
+ case Iop_Est8FRecip: fpop = Pfp_RES; break;
+ case Iop_Est5FRSqrt: fpop = Pfp_RSQRTE; break;
default: break;
}
if (fpop != Pfp_INVALID) {
case Iop_TanF64: vex_printf("TanF64"); return;
case Iop_2xm1F64: vex_printf("2xm1F64"); return;
+ case Iop_Est8FRecip: vex_printf("Est8FRecip"); return;
+ case Iop_Est5FRSqrt: vex_printf("Est5FRSqrt"); return;
+
case Iop_CmpF64: vex_printf("CmpF64"); return;
case Iop_F64toI16: vex_printf("F64toI16"); return;
BINARY(Ity_I32,Ity_F64,Ity_F64);
case Iop_NegF64: case Iop_AbsF64: case Iop_SqrtF64:
case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: case Iop_2xm1F64:
+ case Iop_Est8FRecip: case Iop_Est5FRSqrt:
UNARY(Ity_F64,Ity_F64);
case Iop_ReinterpI64asF64: UNARY(Ity_F64, Ity_I64);
Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
- /* ------ Floating point. We try and be IEEE754 compliant. ------ */
+ /* ------ Floating point. We try to be IEEE754 compliant. ------ */
/* Binary operations mandated by IEEE754. */
Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */
Iop_TanF64, /* FTAN */
Iop_2xm1F64, /* (2^arg - 1.0) */
+ /* Unary ops supported by PPC but not mandated by 754. */
+ Iop_Est8FRecip, /* reciprocal estimate, 8 good bits */
+ Iop_Est5FRSqrt, /* reciprocal square root estimate, 5 good bits */
+
/* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
0x45 Unordered
0x01 LT