|
From: <sv...@va...> - 2005-09-15 14:23:01
|
Author: cerion
Date: 2005-09-15 15:22:58 +0100 (Thu, 15 Sep 2005)
New Revision: 1396
Log:
Added AltiVec integer compare insns.
Modified:
trunk/priv/guest-ppc32/toIR.c
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-09-15 12:42:16 UTC (rev 1395)
+++ trunk/priv/guest-ppc32/toIR.c 2005-09-15 14:22:58 UTC (rev 1396)
@@ -1154,6 +1154,50 @@
=20
=20
=20
+/* Set the CR6 flags following an AltiVec compare operation. */
+static void set_AV_CR6 ( IRExpr* result )
+{
+ vassert(typeOfIRExpr(irbb->tyenv,result) =3D=3D Ity_V128);
+
+ /* CR6[0:3] =3D {all_ones, 0, all_zeros, 0}
+ all_ones =3D (v[0] && v[1] && v[2] && v[3])
+ all_zeros =3D ~(v[0] || v[1] || v[2] || v[3])
+ */
+ IRTemp v0 =3D newTemp(Ity_V128);
+ IRTemp v1 =3D newTemp(Ity_V128);
+ IRTemp v2 =3D newTemp(Ity_V128);
+ IRTemp v3 =3D newTemp(Ity_V128);
+ IRTemp rOnes =3D newTemp(Ity_I8);
+ IRTemp rZeros =3D newTemp(Ity_I8);
+ assign( v0, result );
+ assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );
+ assign( v2, binop(Iop_ShrV128, result, mkU8(64)) );
+ assign( v3, binop(Iop_ShrV128, result, mkU8(96)) );
+
+ assign( rOnes, unop(Iop_1Uto8,
+ binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
+ unop(Iop_V128to32,
+ binop(Iop_AndV128,
+ binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)),
+ binop(Iop_AndV128, mkexpr(v2), mkexpr(v3)))))) );
+
+ assign( rZeros, unop(Iop_1Uto8,
+ binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
+ unop(Iop_Not32,
+ unop(Iop_V128to32,
+ binop(Iop_OrV128,
+ binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)),
+ binop(Iop_OrV128, mkexpr(v2), mkexpr(v3))))
+ ))) );
+
+ putCR321( 6, binop(Iop_Or8,
+ binop(Iop_Shl8, mkexpr(rOnes), mkU8(3)),
+ binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) );
+ putCR0( 6, mkU8(0) );
+}=20
+
+
+
/*------------------------------------------------------------*/
/*--- Abstract register interface --- */
/*------------------------------------------------------------*/
@@ -5429,6 +5473,12 @@
UChar flag_Rc =3D toUChar((theInstr >> 10) & 0x1); /* theInstr[10] =
*/
UInt opc2 =3D (theInstr >> 0) & 0x3FF; /* theInstr[0:9]=
*/
=20
+ IRTemp vA =3D newTemp(Ity_V128);
+ IRTemp vB =3D newTemp(Ity_V128);
+ IRTemp vD =3D newTemp(Ity_V128);
+ assign( vA, getVReg(vA_addr));
+ assign( vB, getVReg(vB_addr));
+
if (opc1 !=3D 0x4) {
vex_printf("dis_av_cmp(PPC32)(instr)\n");
return False;
@@ -5437,53 +5487,59 @@
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpEQ8x16, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpEQ16x8, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpEQ32x4, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT8Ux16, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT16Ux8, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT32Ux4, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT8Sx16, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT16Sx8, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
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_ad=
dr, vB_addr);
- DIP(" =3D> not implemented\n");
- return False;
+ assign( vD, binop(Iop_CmpGT32Sx4, mkexpr(vA), mkexpr(vB)) );
+ break;
=20
default:
vex_printf("dis_av_cmp(PPC32)(opc2)\n");
return False;
}
+
+ putVReg( vD_addr, mkexpr(vD) );
+
+ if (flag_Rc) {
+ set_AV_CR6( mkexpr(vD) );
+ }
return True;
}
=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-09-15 12:42:16 UTC (rev 1395)
+++ trunk/priv/host-ppc32/isel.c 2005-09-15 14:22:58 UTC (rev 1396)
@@ -3344,6 +3344,9 @@
case Iop_Max8Sx16: op =3D Pav_MAXS; goto do_AvBin8x16;
case Iop_Min8Ux16: op =3D Pav_MINU; goto do_AvBin8x16;
case Iop_Min8Sx16: op =3D Pav_MINS; goto do_AvBin8x16;
+ case Iop_CmpEQ8x16: op =3D Pav_CMPEQU; goto do_AvBin8x16;
+ case Iop_CmpGT8Ux16: op =3D Pav_CMPGTU; goto do_AvBin8x16;
+ case Iop_CmpGT8Sx16: op =3D Pav_CMPGTS; goto do_AvBin8x16;
do_AvBin8x16: {
HReg arg1 =3D iselVecExpr(env, e->Iex.Binop.arg1);
HReg arg2 =3D iselVecExpr(env, e->Iex.Binop.arg2);
@@ -3368,6 +3371,9 @@
case Iop_MulLo16Sx8: op =3D Pav_OMULS; goto do_AvBin16x8;
case Iop_MulHi16Ux8: op =3D Pav_EMULU; goto do_AvBin16x8;
case Iop_MulHi16Sx8: op =3D Pav_EMULS; goto do_AvBin16x8;
+ case Iop_CmpEQ16x8: op =3D Pav_CMPEQU; goto do_AvBin16x8;
+ case Iop_CmpGT16Ux8: op =3D Pav_CMPGTU; goto do_AvBin16x8;
+ case Iop_CmpGT16Sx8: op =3D Pav_CMPGTS; goto do_AvBin16x8;
do_AvBin16x8: {
HReg arg1 =3D iselVecExpr(env, e->Iex.Binop.arg1);
HReg arg2 =3D iselVecExpr(env, e->Iex.Binop.arg2);
@@ -3388,11 +3394,13 @@
case Iop_Max32Sx4: op =3D Pav_MAXS; goto do_AvBin32x4;
case Iop_Min32Ux4: op =3D Pav_MINU; goto do_AvBin32x4;
case Iop_Min32Sx4: op =3D Pav_MINS; goto do_AvBin32x4;
- case Iop_CmpGT32Ux4: op =3D Pav_CMPGTU; goto do_AvBin32x4;
case Iop_MulLo32Ux4: op =3D Pav_OMULU; goto do_AvBin32x4;
case Iop_MulLo32Sx4: op =3D Pav_OMULS; goto do_AvBin32x4;
case Iop_MulHi32Ux4: op =3D Pav_EMULU; goto do_AvBin32x4;
case Iop_MulHi32Sx4: op =3D Pav_EMULS; goto do_AvBin32x4;
+ case Iop_CmpEQ32x4: op =3D Pav_CMPEQU; goto do_AvBin32x4;
+ case Iop_CmpGT32Ux4: op =3D Pav_CMPGTU; goto do_AvBin32x4;
+ case Iop_CmpGT32Sx4: op =3D Pav_CMPGTS; goto do_AvBin32x4;
do_AvBin32x4: {
HReg arg1 =3D iselVecExpr(env, e->Iex.Binop.arg1);
HReg arg2 =3D iselVecExpr(env, e->Iex.Binop.arg2);
|