UInt flag );
extern ULong deposit_bits_under_mask_helper( ULong src, ULong mask );
extern ULong population_count64_helper( ULong src );
-extern ULong vbpermq_clean_helper( ULong vA_high, ULong vA_low,
- ULong vB_high, ULong vB_low );
+extern UInt vbpermq_clean_helper( ULong vA_high, ULong vA_low, ULong vB);
extern ULong vector_evaluate64_helper( ULong srcA, ULong srcB, ULong srcC,
ULong IMM );
void write_ACC_entry (VexGuestPPC64State* gst, UInt offset, UInt acc,
/*---------------------------------------------------------------*/
/* --- Clean helper for vbpermq instruction ---*/
/*---------------------------------------------------------------*/
-ULong vbpermq_clean_helper( ULong vA_high, ULong vA_low,
- ULong vB_high, ULong vB_low) {
+UInt vbpermq_clean_helper( ULong vA_high, ULong vA_low, ULong vB) {
ULong bit, result = 0x0;
UInt i, index;
/* IBM numbering bit 0 on is MSB, bit 63 is LSB */
- for ( i = 0; i < 16; i++) {
- if (i < 8)
- index = 0xFFULL & (vB_high >> (56 - 8*i) );
- else
- index = 0xFFULL & (vB_low >> (56 - 8*(i-8)));
+ for ( i = 0; i < 8; i++) {
+ index = 0xFFULL & (vB >> (56 - 8*i) );
if (index < 64) {
bit = 0x1 & (vA_high >> (63 - index));
} else
bit = 0;
- result |= bit << (15 - i);
+ result |= bit << (7 - i);
}
return result;
}
{
/* The original supports was done with Iops but it caused the internal
temorary storage to be exhausted if there were three or more vbpermq
- instructions in a row. Changed to a clean helper on 3/24/2022 */
+ instructions in a row. Changed to a clean helper on 3/24/2022. For
+ Powerpc 32-bit support, passing two 128-bit arguments doesn't work.
+ Hence, the helper is called twice to calculate the result for the
+ upper and lower 64-bit vB register indicies. */
IRTemp res_hi = newTemp( Ity_I64 );
+ IRTemp res_0 = newTemp( Ity_I32 );
+ IRTemp res_1 = newTemp( Ity_I32 );
IRExpr * res_low = mkU64(0);
- assign( res_hi,
- mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ assign( res_0,
+ mkIRExprCCall( Ity_I32, 0 /*regparms*/,
"vbpermq_clean_helper",
fnptr_to_fnentry( vbi,
&vbpermq_clean_helper ),
- mkIRExprVec_4( unop( Iop_V128HIto64,
+ mkIRExprVec_3( unop( Iop_V128HIto64,
mkexpr(vA) ),
unop( Iop_V128to64,
mkexpr(vA) ),
unop( Iop_V128HIto64,
- mkexpr(vB) ),
+ mkexpr(vB) ) ) ) );
+ assign( res_1,
+ mkIRExprCCall( Ity_I32, 0 /*regparms*/,
+ "vbpermq_clean_helper",
+ fnptr_to_fnentry( vbi,
+ &vbpermq_clean_helper ),
+ mkIRExprVec_3( unop( Iop_V128HIto64,
+ mkexpr(vA) ),
+ unop( Iop_V128to64,
+ mkexpr(vA) ),
unop( Iop_V128to64,
mkexpr(vB) ) ) ) );
+ assign( res_hi, binop( Iop_32HLto64,
+ mkU32( 0 ),
+ binop( Iop_Or32,
+ binop( Iop_Shl32, mkexpr( res_0 ),
+ mkU8( 8 ) ),
+ mkexpr( res_1 ) ) ) );
putVReg( vRT_addr, binop( Iop_64HLtoV128, mkexpr( res_hi ), res_low ) );
return True;