mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-06 03:23:58 +00:00
PPC64, fix for vrlwnm, vrlwmi, vrldrm, vrldmi instructions.
Fixes the case where the specified end bit is less then the start bit. Valgrind bug 405734
This commit is contained in:
parent
30a24515f0
commit
ed80ebfa17
4
NEWS
4
NEWS
@ -119,7 +119,9 @@ where XXXXXX is the bug number as listed below.
|
||||
405363 PPC64, xvcvdpsxws, xvcvdpuxws, do not handle NaN arguments correctly.
|
||||
405365 PPC64, function _get_maxmin_fp_NaN() doesn't handle QNaN, SNaN case
|
||||
correctly.
|
||||
405733 PPC64, xvcvdpsp should write 32-bit result to upper and lower 32-bits of the 64-bit destination field.
|
||||
405733 PPC64, xvcvdpsp should write 32-bit result to upper and lower 32-bits
|
||||
of the 64-bit destination field.
|
||||
405734 PPC64, vrlwnm, vrlwmi, vrldrm, vrldmi do not work properly when me < mb
|
||||
|
||||
n-i-bz add syswrap for PTRACE_GET|SET_THREAD_AREA on amd64.
|
||||
n-i-bz Fix callgrind_annotate non deterministic order for equal total
|
||||
|
||||
@ -15619,8 +15619,12 @@ static Bool dis_av_rotate ( UInt theInstr )
|
||||
IRTemp vA_word[4];
|
||||
IRTemp left_bits[4];
|
||||
IRTemp right_bits[4];
|
||||
IRTemp mb[4];
|
||||
IRTemp me[4];
|
||||
IRTemp shift[4];
|
||||
IRTemp mask[4];
|
||||
IRTemp tmp_mask[4];
|
||||
IRTemp invert_mask[4];
|
||||
IRTemp tmp128[4];
|
||||
UInt i;
|
||||
UInt num_words;
|
||||
@ -15664,7 +15668,11 @@ static Bool dis_av_rotate ( UInt theInstr )
|
||||
left_bits[i] = newTemp( Ity_I8 );
|
||||
right_bits[i] = newTemp( Ity_I8 );
|
||||
shift[i] = newTemp( Ity_I8 );
|
||||
mask[i] = newTemp( Ity_V128 );
|
||||
mb[i] = newTemp( Ity_I64 );
|
||||
me[i] = newTemp( Ity_I64 );
|
||||
tmp_mask[i] = newTemp( Ity_I64 );
|
||||
invert_mask[i] = newTemp( Ity_I64 );
|
||||
mask[i] = newTemp( Ity_V128 );
|
||||
tmp128[i] = newTemp( Ity_V128 );
|
||||
vA_word[i] = newTemp( Ity_V128 );
|
||||
|
||||
@ -15678,50 +15686,90 @@ static Bool dis_av_rotate ( UInt theInstr )
|
||||
* word_size ) ),
|
||||
mkexpr( field_mask ) ) ) ) );
|
||||
|
||||
assign( mb[i], unop( Iop_V128to64,
|
||||
binop( Iop_AndV128,
|
||||
binop( Iop_ShrV128,
|
||||
mkexpr( vB ),
|
||||
mkU8( ( num_words - 1 - i )
|
||||
* word_size + 16 ) ),
|
||||
mkexpr( field_mask ) ) ) );
|
||||
|
||||
assign( me[i], unop( Iop_V128to64,
|
||||
binop( Iop_AndV128,
|
||||
binop( Iop_ShrV128,
|
||||
mkexpr( vB ),
|
||||
mkU8( ( num_words - 1 - i )
|
||||
* word_size + 8 ) ),
|
||||
mkexpr( field_mask ) ) ) );
|
||||
|
||||
/* If me < mb, we have to flip things around and invert the mask */
|
||||
assign( invert_mask[i],
|
||||
unop( Iop_1Sto64, binop( Iop_CmpLT64U,
|
||||
mkexpr( me[i] ), mkexpr( mb[i] ) ) ) );
|
||||
|
||||
/* left_bits = 63 - mb. Tells us how many bits to the left
|
||||
* of mb to clear. Note for a word left_bits = 32+mb, for a double
|
||||
* word left_bits = mb
|
||||
*/
|
||||
assign( left_bits[i],
|
||||
unop( Iop_64to8,
|
||||
binop( Iop_Add64,
|
||||
mkU64( 64 - word_size ),
|
||||
unop( Iop_V128to64,
|
||||
binop( Iop_AndV128,
|
||||
binop( Iop_ShrV128,
|
||||
mkexpr( vB ),
|
||||
mkU8( ( num_words - 1 - i )
|
||||
* word_size + 16 ) ),
|
||||
mkexpr( field_mask ) ) ) ) ) );
|
||||
binop( Iop_Or64,
|
||||
binop( Iop_And64, // mb < me
|
||||
unop( Iop_Not64, mkexpr( invert_mask[i] ) ),
|
||||
binop( Iop_Add64,
|
||||
mkU64( 64 - word_size ),
|
||||
mkexpr( mb[i] ) ) ),
|
||||
binop( Iop_And64, // me < mb
|
||||
mkexpr( invert_mask[i] ),
|
||||
binop( Iop_Add64,
|
||||
mkU64( 64 + 1 - word_size ),
|
||||
mkexpr( me[i] ) ) ) ) ) );
|
||||
|
||||
/* right_bits = 63 - me. Tells us how many bits to the right
|
||||
* of me to clear. Note for a word, left_bits = me+32, for a double
|
||||
* word left_bits = me
|
||||
*/
|
||||
assign( right_bits[i],
|
||||
unop( Iop_64to8,
|
||||
binop( Iop_Sub64,
|
||||
mkU64( word_size - 1 ),
|
||||
unop( Iop_V128to64,
|
||||
binop( Iop_AndV128,
|
||||
binop( Iop_ShrV128,
|
||||
mkexpr( vB ),
|
||||
mkU8( ( num_words - 1 - i )
|
||||
* word_size + 8 ) ),
|
||||
mkexpr( field_mask ) ) ) ) ) );
|
||||
binop( Iop_Or64,
|
||||
binop( Iop_And64, // mb < me
|
||||
unop( Iop_Not64, mkexpr( invert_mask[i] ) ),
|
||||
binop( Iop_Sub64,
|
||||
mkU64( word_size - 1 ),
|
||||
mkexpr( me[i] ) ) ),
|
||||
binop( Iop_And64, // me < mb
|
||||
mkexpr( invert_mask[i] ),
|
||||
binop( Iop_Sub64,
|
||||
mkU64( word_size - 1 + 1),
|
||||
mkexpr( mb[i] ) ) ) ) ) );
|
||||
|
||||
/* create mask for 32-bit word or 64-bit word */
|
||||
assign( tmp_mask[i],
|
||||
binop( Iop_Shl64,
|
||||
binop( Iop_Shr64,
|
||||
binop( Iop_Shr64,
|
||||
binop( Iop_Shl64,
|
||||
mkU64( 0xFFFFFFFFFFFFFFFF ),
|
||||
mkexpr( left_bits[i] ) ),
|
||||
mkexpr( left_bits[i] ) ),
|
||||
mkexpr( right_bits[i] ) ),
|
||||
mkexpr( right_bits[i] ) ) );
|
||||
|
||||
assign( mask[i],
|
||||
binop( Iop_64HLtoV128,
|
||||
mkU64( 0 ),
|
||||
binop( Iop_Shl64,
|
||||
binop( Iop_Shr64,
|
||||
binop( Iop_Shr64,
|
||||
binop( Iop_Shl64,
|
||||
mkU64( 0xFFFFFFFFFFFFFFFF ),
|
||||
mkexpr( left_bits[i] ) ),
|
||||
mkexpr( left_bits[i] ) ),
|
||||
mkexpr( right_bits[i] ) ),
|
||||
mkexpr( right_bits[i] ) ) ) );
|
||||
binop( Iop_Or64,
|
||||
binop( Iop_And64,
|
||||
unop( Iop_Not64, mkexpr( invert_mask[i] ) ),
|
||||
mkexpr( tmp_mask[i] ) ),
|
||||
binop( Iop_And64,
|
||||
mkexpr( invert_mask[i] ),
|
||||
/* Need to make sure mask is only the size
|
||||
desired word.*/
|
||||
binop( Iop_And64,
|
||||
mkU64( word_mask ),
|
||||
unop( Iop_Not64,
|
||||
mkexpr( tmp_mask[i] ) ) ) ))));
|
||||
|
||||
/* Need to rotate vA using a left and right shift of vA OR'd together
|
||||
* then ANDed with the mask.
|
||||
@ -15750,7 +15798,7 @@ static Bool dis_av_rotate ( UInt theInstr )
|
||||
mkU32( word_size ),
|
||||
unop( Iop_8Uto32,
|
||||
mkexpr( shift[i] ) ) )
|
||||
) ) ) ) );
|
||||
) ) ) ) );
|
||||
}
|
||||
|
||||
switch (opc2) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user