|
From: <sv...@va...> - 2005-11-16 18:03:06
|
Author: cerion
Date: 2005-11-16 18:02:58 +0000 (Wed, 16 Nov 2005)
New Revision: 1462
Log:
Implemented most of the remaining altivec fp ops:
rounds (vrfi*), converts (vctu/sxs, vcfu/sx)
Modified:
trunk/priv/guest-ppc32/toIR.c
trunk/priv/host-ppc32/hdefs.c
trunk/priv/host-ppc32/hdefs.h
trunk/priv/host-ppc32/isel.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-11-16 17:21:10 UTC (rev 1461)
+++ trunk/priv/guest-ppc32/toIR.c 2005-11-16 18:02:58 UTC (rev 1462)
@@ -6811,14 +6811,10 @@
return True;
=20
case 0x2F: { // vnmsubfp (Negative Multiply-Subtract FP, AV p215)
- IRTemp zeros =3D newTemp(Ity_V128);
DIP("vnmsubfp v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vC_addr, vB_ad=
dr);
- assign( zeros, unop(Iop_Dup32x4, mkU32(0)) );
- putVReg( vD_addr,
- binop(Iop_Sub32Fx4, mkexpr(zeros),
- binop(Iop_Sub32Fx4,
- binop(Iop_Mul32Fx4, mkexpr(vA), mkexpr(vC)),
- mkexpr(vB))) );
+ putVReg( vD_addr, binop(Iop_Sub32Fx4,
+ mkexpr(vB),
+ binop(Iop_Mul32Fx4, mkexpr(vA), mkexpr(vC)=
)) );
return True;
}
=20
@@ -6983,6 +6979,17 @@
UChar vB_addr =3D toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:1=
5] */
UInt opc2 =3D (theInstr >> 0) & 0x7FF; /* theInstr[0:10=
] */
=20
+ IRTemp vB =3D newTemp(Ity_V128);
+ IRTemp vScale =3D newTemp(Ity_V128);
+ IRTemp vInvScale =3D newTemp(Ity_V128);
+ assign( vB, getVReg(vB_addr));
+
+ /* scale =3D 2^UIMM, cast to float, reinterpreted as uint */
+ float scale =3D (float)( (unsigned int) 1<<UIMM_5 );
+ assign( vScale, unop(Iop_Dup32x4, mkU32( *((unsigned int*)(&scale)) )=
) );
+ float inv_scale =3D 1/scale;
+ assign( vInvScale, unop(Iop_Dup32x4, mkU32( *((unsigned int*)(&inv_sc=
ale)) )) );
+
if (opc1 !=3D 0x4) {
vex_printf("dis_av_fp_convert(PPC32)(instr)\n");
return False;
@@ -6991,23 +6998,32 @@
switch (opc2) {
case 0x30A: // vcfux (Convert from Unsigned Fixed-Point W, AV p156)
DIP("vcfux v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr, binop(Iop_Mul32Fx4,
+ unop(Iop_I32UtoFx4, mkexpr(vB)),
+ mkexpr(vInvScale)) );
+ return True;
=20
case 0x34A: // vcfsx (Convert from Signed Fixed-Point W, AV p155)
DIP("vcfsx v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
- DIP(" =3D> not implemented\n");
- return False;
=20
+ putVReg( vD_addr, binop(Iop_Mul32Fx4,
+ unop(Iop_I32StoFx4, mkexpr(vB)),
+ mkexpr(vInvScale)) );
+ return True;
+
case 0x38A: // vctuxs (Convert to Unsigned Fixed-Point W Saturate, AV=
p172)
DIP("vctuxs v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr,
+ unop(Iop_QFtoI32Ux4_RZ,=20
+ binop(Iop_Mul32Fx4, mkexpr(vB), mkexpr(vScale))) );
+ return True;
=20
case 0x3CA: // vctsxs (Convert to Signed Fixed-Point W Saturate, AV p=
171)
DIP("vctsxs v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr,=20
+ unop(Iop_QFtoI32Sx4_RZ,=20
+ binop(Iop_Mul32Fx4, mkexpr(vB), mkexpr(vScale))) );
+ return True;
=20
default:
break; // Fall through...
@@ -7021,23 +7037,23 @@
switch (opc2) {
case 0x20A: // vrfin (Round to FP Integer Nearest, AV p231)
DIP("vrfin v%d,v%d\n", vD_addr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr, unop(Iop_RoundF32x4_RN, mkexpr(vB)) );
+ break;
=20
case 0x24A: // vrfiz (Round to FP Integer toward zero, AV p233)
DIP("vrfiz v%d,v%d\n", vD_addr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr, unop(Iop_RoundF32x4_RZ, mkexpr(vB)) );
+ break;
=20
case 0x28A: // vrfip (Round to FP Integer toward +inf, AV p232)
DIP("vrfip v%d,v%d\n", vD_addr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr, unop(Iop_RoundF32x4_RP, mkexpr(vB)) );
+ break;
=20
case 0x2CA: // vrfim (Round to FP Integer toward -inf, AV p230)
DIP("vrfim v%d,v%d\n", vD_addr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ putVReg( vD_addr, unop(Iop_RoundF32x4_RM, mkexpr(vB)) );
+ break;
=20
default:
vex_printf("dis_av_fp_convert(PPC32)(opc2)\n");
Modified: trunk/priv/host-ppc32/hdefs.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/host-ppc32/hdefs.c 2005-11-16 17:21:10 UTC (rev 1461)
+++ trunk/priv/host-ppc32/hdefs.c 2005-11-16 18:02:58 UTC (rev 1462)
@@ -708,8 +708,16 @@
/* Floating Point Unary */
case Pavfp_RCPF: return "vrefp";
case Pavfp_RSQRTF: return "vrsqrtefp";
+ case Pavfp_CVTU2F: return "vcfux";
+ case Pavfp_CVTS2F: return "vcfsx";
+ case Pavfp_QCVTF2U: return "vctuxs";
+ case Pavfp_QCVTF2S: return "vctsxs";
+ case Pavfp_ROUNDM: return "vrfim";
+ case Pavfp_ROUNDP: return "vrfip";
+ case Pavfp_ROUNDN: return "vrfin";
+ case Pavfp_ROUNDZ: return "vrfiz";
=20
- default: vpanic("showPPC32AvOp");
+ default: vpanic("showPPC32AvFpOp");
}
}
=20
@@ -1412,7 +1420,7 @@
ppHRegPPC32(i->Pin.AvBin32x4.srcR);
return;
case Pin_AvBin32Fx4:
- vex_printf("%s ", showPPC32AvOp(i->Pin.AvBin32Fx4.op));
+ vex_printf("%s ", showPPC32AvFpOp(i->Pin.AvBin32Fx4.op));
ppHRegPPC32(i->Pin.AvBin32Fx4.dst);
vex_printf(",");
ppHRegPPC32(i->Pin.AvBin32Fx4.srcL);
@@ -1420,7 +1428,7 @@
ppHRegPPC32(i->Pin.AvBin32Fx4.srcR);
return;
case Pin_AvUn32Fx4:
- vex_printf("%s ", showPPC32AvOp(i->Pin.AvUn32Fx4.op));
+ vex_printf("%s ", showPPC32AvFpOp(i->Pin.AvUn32Fx4.op));
ppHRegPPC32(i->Pin.AvUn32Fx4.dst);
vex_printf(",");
ppHRegPPC32(i->Pin.AvUn32Fx4.src);
@@ -3153,7 +3161,7 @@
UInt vB =3D 29; // XXX: Using r29 for temp
UInt konst =3D 0x1F;
=20
- // Better way to load zero_imm?
+ // Better way to load -0.0 (0x80000000) ?
// vspltisw vB,0x1F (0x1F =3D> each word of vB)
p =3D mkFormVX( p, 4, vB, konst, 0, 908 );
=20
@@ -3185,8 +3193,16 @@
UInt v_src =3D vregNo(i->Pin.AvUn32Fx4.src);
UInt opc2;
switch (i->Pin.AvUn32Fx4.op) {
- case Pavfp_RCPF: opc2 =3D 266; break; // vrefp
- case Pavfp_RSQRTF: opc2 =3D 330; break; // vrsqrtefp
+ case Pavfp_RCPF: opc2 =3D 266; break; // vrefp
+ case Pavfp_RSQRTF: opc2 =3D 330; break; // vrsqrtefp
+ case Pavfp_CVTU2F: opc2 =3D 778; break; // vcfux
+ case Pavfp_CVTS2F: opc2 =3D 842; break; // vcfsx
+ case Pavfp_QCVTF2U: opc2 =3D 906; break; // vctuxs
+ case Pavfp_QCVTF2S: opc2 =3D 970; break; // vctsxs
+ case Pavfp_ROUNDM: opc2 =3D 714; break; // vrfim
+ case Pavfp_ROUNDP: opc2 =3D 650; break; // vrfip
+ case Pavfp_ROUNDN: opc2 =3D 522; break; // vrfin
+ case Pavfp_ROUNDZ: opc2 =3D 586; break; // vrfiz
default:
goto bad;
}
Modified: trunk/priv/host-ppc32/hdefs.h
=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/host-ppc32/hdefs.h 2005-11-16 17:21:10 UTC (rev 1461)
+++ trunk/priv/host-ppc32/hdefs.h 2005-11-16 18:02:58 UTC (rev 1462)
@@ -414,6 +414,8 @@
=20
/* Floating point unary */
Pavfp_RCPF, Pavfp_RSQRTF,
+ Pavfp_CVTU2F, Pavfp_CVTS2F, Pavfp_QCVTF2U, Pavfp_QCVTF2S,
+ Pavfp_ROUNDM, Pavfp_ROUNDP, Pavfp_ROUNDN, Pavfp_ROUNDZ,
}
PPC32AvFpOp;
=20
Modified: trunk/priv/host-ppc32/isel.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/host-ppc32/isel.c 2005-11-16 17:21:10 UTC (rev 1461)
+++ trunk/priv/host-ppc32/isel.c 2005-11-16 18:02:58 UTC (rev 1462)
@@ -3059,6 +3059,14 @@
case Iop_Recip32Fx4: op =3D Pavfp_RCPF; goto do_32Fx4_unary;
case Iop_RSqrt32Fx4: op =3D Pavfp_RSQRTF; goto do_32Fx4_unary;
//.. case Iop_Sqrt32Fx4: op =3D Xsse_SQRTF; goto do_32Fx4_unary;
+ case Iop_I32UtoFx4: op =3D Pavfp_CVTU2F; goto do_32Fx4_unary;
+ case Iop_I32StoFx4: op =3D Pavfp_CVTS2F; goto do_32Fx4_unary;
+ case Iop_QFtoI32Ux4_RZ: op =3D Pavfp_QCVTF2U; goto do_32Fx4_unary;
+ case Iop_QFtoI32Sx4_RZ: op =3D Pavfp_QCVTF2S; goto do_32Fx4_unary;
+ case Iop_RoundF32x4_RM: op =3D Pavfp_ROUNDM; goto do_32Fx4_unar=
y;
+ case Iop_RoundF32x4_RP: op =3D Pavfp_ROUNDP; goto do_32Fx4_unar=
y;
+ case Iop_RoundF32x4_RN: op =3D Pavfp_ROUNDN; goto do_32Fx4_unar=
y;
+ case Iop_RoundF32x4_RZ: op =3D Pavfp_ROUNDZ; goto do_32Fx4_unar=
y;
do_32Fx4_unary:
{
HReg arg =3D iselVecExpr(env, e->Iex.Unop.arg);
|