summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Love <carll@us.ibm.com>2017-10-03 12:08:09 -0500
committerCarl Love <carll@us.ibm.com>2017-10-03 12:08:09 -0500
commitacdeb75d2a58f4f3910ddaf9b2bc2ec74378fa3a (patch)
treef52273357ab5d5bda3570c5fb90b13c110a4a11f
parentPPC64, Add support for the Data Stream Control Register (DSCR) (diff)
downloadvalgrind-acdeb75d2a58f4f3910ddaf9b2bc2ec74378fa3a.tar.gz
valgrind-acdeb75d2a58f4f3910ddaf9b2bc2ec74378fa3a.tar.bz2
valgrind-acdeb75d2a58f4f3910ddaf9b2bc2ec74378fa3a.tar.xz
PPC64, Replace body of generate_store_FPRF with C helper function.
The function calculates the floating point condition code values and stores them into the floating point condition code register. The function is used by a number of instructions. The calculation generates a lot of Iops as it much check the operatds for NaN, SNaN, zero, dnorm, norm and infinity. The large number of Iops exhausts temporary memory.
-rw-r--r--NEWS1
-rw-r--r--VEX/priv/guest_ppc_defs.h1
-rw-r--r--VEX/priv/guest_ppc_helpers.c104
-rw-r--r--VEX/priv/guest_ppc_toIR.c241
4 files changed, 185 insertions, 162 deletions
diff --git a/NEWS b/NEWS
index ca61811..20007cf 100644
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,7 @@ where XXXXXX is the bug number as listed below.
59384584 Callee saved registers listed first for AMD64, X86, and PPC architectures 59384584 Callee saved registers listed first for AMD64, X86, and PPC architectures
60n-i-bz Fix missing workq_ops operations (macOS) 60n-i-bz Fix missing workq_ops operations (macOS)
61385182 PPC64 is missing support for the DSCR 61385182 PPC64 is missing support for the DSCR
62385207 PPC64, generate_store_FPRF() generates too many Iops
62 63
63Release 3.13.0 (15 June 2017) 64Release 3.13.0 (15 June 2017)
64~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/VEX/priv/guest_ppc_defs.h b/VEX/priv/guest_ppc_defs.h
index fe411f7..f3eb956 100644
--- a/VEX/priv/guest_ppc_defs.h
+++ b/VEX/priv/guest_ppc_defs.h
@@ -156,6 +156,7 @@ extern ULong convert_to_zoned_helper( ULong src_hi, ULong src_low,
156extern ULong convert_to_national_helper( ULong src, ULong return_upper ); 156extern ULong convert_to_national_helper( ULong src, ULong return_upper );
157extern ULong convert_from_zoned_helper( ULong src_hi, ULong src_low ); 157extern ULong convert_from_zoned_helper( ULong src_hi, ULong src_low );
158extern ULong convert_from_national_helper( ULong src_hi, ULong src_low ); 158extern ULong convert_from_national_helper( ULong src_hi, ULong src_low );
159extern ULong generate_C_FPCC_helper( ULong size, ULong src_hi, ULong src );
159 160
160 161
161/* --- DIRTY HELPERS --- */ 162/* --- DIRTY HELPERS --- */
diff --git a/VEX/priv/guest_ppc_helpers.c b/VEX/priv/guest_ppc_helpers.c
index 34adf62..bf2d071 100644
--- a/VEX/priv/guest_ppc_helpers.c
+++ b/VEX/priv/guest_ppc_helpers.c
@@ -216,6 +216,110 @@ IRExpr* guest_ppc64_spechelper ( const HChar* function_name,
216} 216}
217 217
218 218
219/* 16-bit floating point number is stored in the lower 16-bits of 32-bit value */
220#define I16_EXP_MASK 0x7C00
221#define I16_FRACTION_MASK 0x03FF
222#define I32_EXP_MASK 0x7F800000
223#define I32_FRACTION_MASK 0x007FFFFF
224#define I64_EXP_MASK 0x7FF0000000000000ULL
225#define I64_FRACTION_MASK 0x000FFFFFFFFFFFFFULL
226#define V128_EXP_MASK 0x7FFF000000000000ULL
227#define V128_FRACTION_MASK 0x0000FFFFFFFFFFFFULL /* upper 64-bit fractional mask */
228
229ULong generate_C_FPCC_helper( ULong irType, ULong src_hi, ULong src )
230{
231 UInt NaN, inf, zero, norm, dnorm, pos;
232 UInt bit0, bit1, bit2, bit3;
233 UInt sign_bit = 0;
234 ULong exp_mask = 0, exp_part = 0, frac_part = 0;
235 ULong fpcc, c;
236
237 if ( irType == Ity_I16 ) {
238 frac_part = I16_FRACTION_MASK & src;
239 exp_mask = I16_EXP_MASK;
240 exp_part = exp_mask & src;
241 sign_bit = src >> 15;
242
243 } else if ( irType == Ity_I32 ) {
244 frac_part = I32_FRACTION_MASK & src;
245 exp_mask = I32_EXP_MASK;
246 exp_part = exp_mask & src;
247 sign_bit = src >> 31;
248
249 } else if ( irType == Ity_I64 ) {
250 frac_part = I64_FRACTION_MASK & src;
251 exp_mask = I64_EXP_MASK;
252 exp_part = exp_mask & src;
253 sign_bit = src >> 63;
254
255 } else if ( irType == Ity_F128 ) {
256 /* only care if the frac part is zero or non-zero */
257 frac_part = (V128_FRACTION_MASK & src_hi) | src;
258 exp_mask = V128_EXP_MASK;
259 exp_part = exp_mask & src_hi;
260 sign_bit = src_hi >> 63;
261 } else {
262 vassert(0); // Unknown value of irType
263 }
264
265 /* NaN: exponene is all ones, fractional part not zero */
266 if ((exp_part == exp_mask) && (frac_part != 0))
267 NaN = 1;
268 else
269 NaN = 0;
270
271 /* inf: exponent all 1's, fraction part is zero */
272 if ((exp_part == exp_mask) && (frac_part == 0))
273 inf = 1;
274 else
275 inf = 0;
276
277 /* zero: exponent is 0, fraction part is zero */
278 if ((exp_part == 0) && (frac_part == 0))
279 zero = 1;
280 else
281 zero = 0;
282
283 /* norm: exponent is not 0, exponent is not all 1's */
284 if ((exp_part != 0) && (exp_part != exp_mask))
285 norm = 1;
286 else
287 norm = 0;
288
289 /* dnorm: exponent is all 0's, fraction is not 0 */
290 if ((exp_part == 0) && (frac_part != 0))
291 dnorm = 1;
292 else
293 dnorm = 0;
294
295 /* pos: MSB is 1 */
296 if (sign_bit == 0)
297 pos = 1;
298 else
299 pos = 0;
300
301 /* calculate FPCC */
302 /* If the result is NaN then must force bits 1, 2 and 3 to zero
303 * to get correct result.
304 */
305 bit0 = NaN | inf;
306
307 bit1 = (!NaN) & zero;
308 bit2 = (!NaN) & ((pos & dnorm) | (pos & norm) | (pos & inf))
309 & ((!zero) & (!NaN));
310 bit3 = (!NaN) & (((!pos) & dnorm) |((!pos) & norm) | ((!pos) & inf))
311 & ((!zero) & (!NaN));
312
313 fpcc = (bit3 << 3) | (bit2 << 2) | (bit1 << 1) | bit0;
314
315 /* calculate C */
316 c = NaN | ((!pos) & dnorm) | ((!pos) & zero) | (pos & dnorm);
317
318 /* return C in the upper 32-bits and FPCC in the lower 32 bits */
319 return (c <<32) | fpcc;
320}
321
322
219/*---------------------------------------------------------------*/ 323/*---------------------------------------------------------------*/
220/*--- Misc BCD clean helpers. ---*/ 324/*--- Misc BCD clean helpers. ---*/
221/*---------------------------------------------------------------*/ 325/*---------------------------------------------------------------*/
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
index 2467f70..0dae368 100644
--- a/VEX/priv/guest_ppc_toIR.c
+++ b/VEX/priv/guest_ppc_toIR.c
@@ -3860,7 +3860,7 @@ static IRExpr * is_Denorm( IRType size, IRTemp src )
3860 3860
3861 setup_value_check_args( size, &exp_mask, &frac_mask, &zero ); 3861 setup_value_check_args( size, &exp_mask, &frac_mask, &zero );
3862 3862
3863 /* check exponent is all ones, i.e. (exp AND exp_mask) = exp_mask */ 3863 /* check exponent is all zeros */
3864 zero_exp = exponent_compare( size, src, exp_mask, mkexpr( zero ) ); 3864 zero_exp = exponent_compare( size, src, exp_mask, mkexpr( zero ) );
3865 3865
3866 /* check fractional part is not zero */ 3866 /* check fractional part is not zero */
@@ -3871,8 +3871,11 @@ static IRExpr * is_Denorm( IRType size, IRTemp src )
3871 return mkAND1( zero_exp, not_zero_frac ); 3871 return mkAND1( zero_exp, not_zero_frac );
3872} 3872}
3873 3873
3874#if 0
3874/* Normalized number has exponent between 1 and max_exp -1, or in other words 3875/* Normalized number has exponent between 1 and max_exp -1, or in other words
3875 the exponent is not zero and not equal to the max exponent value. */ 3876 the exponent is not zero and not equal to the max exponent value. */
3877 Currently not needed since generate_C_FPCC is now done with a C helper.
3878 Keep it around, might be useful in the future.
3876static IRExpr * is_Norm( IRType size, IRTemp src ) 3879static IRExpr * is_Norm( IRType size, IRTemp src )
3877{ 3880{
3878 IRExpr *not_zero_exp, *not_max_exp; 3881 IRExpr *not_zero_exp, *not_max_exp;
@@ -3919,72 +3922,18 @@ static IRExpr * is_Norm( IRType size, IRTemp src )
3919 3922
3920 return mkAND1( not_zero_exp, not_max_exp ); 3923 return mkAND1( not_zero_exp, not_max_exp );
3921} 3924}
3925#endif
3922 3926
3923 3927static void generate_store_FPRF( IRType size, IRTemp src,
3924static IRExpr * create_FPCC( IRTemp NaN, IRTemp inf, 3928 const VexAbiInfo* vbi )
3925 IRTemp zero, IRTemp norm,
3926 IRTemp dnorm, IRTemp pos,
3927 IRTemp neg ) {
3928 IRExpr *bit0, *bit1, *bit2, *bit3;
3929
3930 /* If the result is NaN then must force bits 1, 2 and 3 to zero
3931 * to get correct result.
3932 */
3933 bit0 = unop( Iop_1Uto32, mkOR1( mkexpr( NaN ), mkexpr( inf ) ) );
3934 bit1 = unop( Iop_1Uto32, mkAND1( mkNOT1( mkexpr( NaN ) ), mkexpr( zero ) ) );
3935 bit2 = unop( Iop_1Uto32,
3936 mkAND1( mkNOT1( mkexpr( NaN ) ),
3937 mkAND1( mkOR1( mkOR1( mkAND1( mkexpr( pos ),
3938 mkexpr( dnorm ) ),
3939 mkAND1( mkexpr( pos ),
3940 mkexpr( norm ) ) ),
3941 mkAND1( mkexpr( pos ),
3942 mkexpr( inf ) ) ),
3943 mkAND1( mkNOT1 ( mkexpr( zero ) ),
3944 mkNOT1( mkexpr( NaN ) ) ) ) ) );
3945 bit3 = unop( Iop_1Uto32,
3946 mkAND1( mkNOT1( mkexpr( NaN ) ),
3947 mkAND1( mkOR1( mkOR1( mkAND1( mkexpr( neg ),
3948 mkexpr( dnorm ) ),
3949 mkAND1( mkexpr( neg ),
3950 mkexpr( norm ) ) ),
3951 mkAND1( mkexpr( neg ),
3952 mkexpr( inf ) ) ),
3953 mkAND1( mkNOT1 ( mkexpr( zero ) ),
3954 mkNOT1( mkexpr( NaN ) ) ) ) ) );
3955
3956 return binop( Iop_Or32,
3957 binop( Iop_Or32,
3958 bit0,
3959 binop( Iop_Shl32, bit1, mkU8( 1 ) ) ),
3960 binop( Iop_Or32,
3961 binop( Iop_Shl32, bit2, mkU8( 2 ) ),
3962 binop( Iop_Shl32, bit3, mkU8( 3 ) ) ) );
3963}
3964
3965static IRExpr * create_C( IRTemp NaN, IRTemp zero,
3966 IRTemp dnorm, IRTemp pos,
3967 IRTemp neg )
3968{
3969
3970 return unop( Iop_1Uto32,
3971 mkOR1( mkOR1( mkexpr( NaN ),
3972 mkAND1( mkexpr( neg ), mkexpr( dnorm ) ) ),
3973 mkOR1( mkAND1( mkexpr( neg ), mkexpr( zero ) ),
3974 mkAND1( mkexpr( pos ), mkexpr( dnorm ) ) ) ) );
3975}
3976
3977static void generate_store_FPRF( IRType size, IRTemp src )
3978{ 3929{
3979 IRExpr *FPCC, *C;
3980 IRTemp NaN = newTemp( Ity_I1 ), inf = newTemp( Ity_I1 );
3981 IRTemp dnorm = newTemp( Ity_I1 ), norm = newTemp( Ity_I1 );
3982 IRTemp pos = newTemp( Ity_I1 ), neg = newTemp( Ity_I1 );
3983 IRTemp zero = newTemp( Ity_I1 );
3984 3930
3985 IRTemp sign_bit = newTemp( Ity_I1 ); 3931 /* This function was originally written using IR code. It has been
3986 IRTemp value; 3932 * replaced with a clean helper due to the large amount of IR code
3933 * needed by this function.
3934 */
3987 3935
3936 IRTemp tmp = newTemp( Ity_I64 );
3988 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 ) 3937 vassert( ( size == Ity_I16 ) || ( size == Ity_I32 )
3989 || ( size == Ity_I64 ) || ( size == Ity_F128 ) ); 3938 || ( size == Ity_I64 ) || ( size == Ity_F128 ) );
3990 3939
@@ -3993,82 +3942,45 @@ static void generate_store_FPRF( IRType size, IRTemp src )
3993 || ( typeOfIRExpr(irsb->tyenv, mkexpr( src ) ) == Ity_F128 ) ); 3942 || ( typeOfIRExpr(irsb->tyenv, mkexpr( src ) ) == Ity_F128 ) );
3994 3943
3995 if( size == Ity_I16 ) { 3944 if( size == Ity_I16 ) {
3996 /* The 16-bit floating point value is in the lower 16-bits of 3945 assign( tmp,
3997 the 32-bit input value */ 3946 mkIRExprCCall( Ity_I64, 0 /*regparms*/,
3998 value = newTemp( Ity_I32 ); 3947 "generate_store_C_FPCC_helper",
3999 assign( value, mkexpr( src ) ); 3948 fnptr_to_fnentry( vbi, &generate_C_FPCC_helper ),
4000 assign( sign_bit, 3949 mkIRExprVec_3( mkU64( size ), mkU64( 0 ),
4001 unop ( Iop_32to1, 3950 mkexpr( src ) ) ) );
4002 binop( Iop_And32,
4003 binop( Iop_Shr32, mkexpr( value ), mkU8( 15 ) ),
4004 mkU32( 0x1 ) ) ) );
4005
4006 } else if( size == Ity_I32 ) { 3951 } else if( size == Ity_I32 ) {
4007 value = newTemp( size ); 3952 assign( tmp,
4008 assign( value, mkexpr( src ) ); 3953 mkIRExprCCall( Ity_I64, 0 /*regparms*/,
4009 assign( sign_bit, 3954 "generate_store_C_FPCC_helper",
4010 unop ( Iop_32to1, 3955 fnptr_to_fnentry( vbi, &generate_C_FPCC_helper ),
4011 binop( Iop_And32, 3956 mkIRExprVec_3( mkU64( size ), mkU64( 0 ),
4012 binop( Iop_Shr32, mkexpr( value ), mkU8( 31 ) ), 3957 mkexpr( src ) ) ) );
4013 mkU32( 0x1 ) ) ) );
4014
4015 } else if( size == Ity_I64 ) { 3958 } else if( size == Ity_I64 ) {
4016 value = newTemp( size ); 3959 assign( tmp,
4017 assign( value, mkexpr( src ) ); 3960 mkIRExprCCall( Ity_I64, 0 /*regparms*/,
4018 assign( sign_bit, 3961 "generate_store_C_FPCC_helper",
4019 unop ( Iop_64to1, 3962 fnptr_to_fnentry( vbi, &generate_C_FPCC_helper ),
4020 binop( Iop_And64, 3963 mkIRExprVec_3( mkU64( size ), mkU64( 0 ),
4021 binop( Iop_Shr64, mkexpr( value ), mkU8( 63 ) ), 3964 mkexpr( src ) ) ) );
4022 mkU64( 0x1 ) ) ) ); 3965 } else if( size == Ity_F128 ) {
4023 3966 assign( tmp,
4024 } else { 3967 mkIRExprCCall( Ity_I64, 0 /*regparms*/,
4025 /* Move the F128 bit pattern to an integer V128 bit pattern */ 3968 "generate_store_C_FPCC_helper",
4026 value = newTemp( Ity_V128 ); 3969 fnptr_to_fnentry( vbi, &generate_C_FPCC_helper ),
4027 assign( value, 3970 mkIRExprVec_3( mkU64( size ),
4028 binop( Iop_64HLtoV128, 3971 unop( Iop_ReinterpF64asI64,
4029 unop( Iop_ReinterpF64asI64, 3972 unop( Iop_F128HItoF64,
4030 unop( Iop_F128HItoF64, mkexpr( src ) ) ), 3973 mkexpr( src ) ) ),
4031 unop( Iop_ReinterpF64asI64, 3974 unop( Iop_ReinterpF64asI64,
4032 unop( Iop_F128LOtoF64, mkexpr( src ) ) ) ) ); 3975 unop( Iop_F128LOtoF64,
4033 3976 mkexpr( src ) ) ) ) ) );
4034 size = Ity_V128;
4035 assign( sign_bit,
4036 unop ( Iop_64to1,
4037 binop( Iop_And64,
4038 binop( Iop_Shr64,
4039 unop( Iop_V128HIto64, mkexpr( value ) ),
4040 mkU8( 63 ) ),
4041 mkU64( 0x1 ) ) ) );
4042 } 3977 }
4043 3978
4044 /* Calculate the floating point result field FPRF */ 3979 /* C is in the upper 32-bits, FPCC is in the lower 32-bits of the
4045 assign( NaN, is_NaN( size, value ) ); 3980 * value returned by the helper function
4046 assign( inf, is_Inf( size, value ) );
4047 assign( zero, is_Zero( size, value ) );
4048 assign( norm, is_Norm( size, value ) );
4049 assign( dnorm, is_Denorm( size, value ) );
4050 assign( pos, mkAND1( mkNOT1( mkexpr( sign_bit ) ), mkU1( 1 ) ) );
4051 assign( neg, mkAND1( mkexpr( sign_bit ), mkU1( 1 ) ) );
4052
4053 /* create the FPRF bit field
4054 *
4055 * FPRF field[4:0] type of value
4056 * 10001 QNaN
4057 * 01001 - infininity
4058 * 01000 - Normalized
4059 * 11000 - Denormalized
4060 * 10010 - zero
4061 * 00010 + zero
4062 * 10100 + Denormalized
4063 * 00100 + Normalized
4064 * 00101 + infinity
4065 */ 3981 */
4066 FPCC = create_FPCC( NaN, inf, zero, norm, dnorm, pos, neg ); 3982 putC( unop( Iop_64HIto32, mkexpr( tmp) ) );
4067 C = create_C( NaN, zero, dnorm, pos, neg ); 3983 putFPCC( unop( Iop_64to32, mkexpr( tmp) ) );
4068
4069 /* Write the C and FPCC fields of the FPRF field */
4070 putC( C );
4071 putFPCC( FPCC );
4072} 3984}
4073 3985
4074/* This function takes an Ity_I32 input argument interpreted 3986/* This function takes an Ity_I32 input argument interpreted
@@ -18538,7 +18450,8 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
18538 * Miscellaneous VSX Scalar Instructions 18450 * Miscellaneous VSX Scalar Instructions
18539 */ 18451 */
18540static Bool 18452static Bool
18541dis_vxs_misc( UInt theInstr, UInt opc2, int allow_isa_3_0 ) 18453dis_vxs_misc( UInt theInstr, const VexAbiInfo* vbi, UInt opc2,
18454 int allow_isa_3_0 )
18542{ 18455{
18543#define VG_PPC_SIGN_MASK 0x7fffffffffffffffULL 18456#define VG_PPC_SIGN_MASK 0x7fffffffffffffffULL
18544 /* XX3-Form and XX2-Form */ 18457 /* XX3-Form and XX2-Form */
@@ -18783,7 +18696,7 @@ dis_vxs_misc( UInt theInstr, UInt opc2, int allow_isa_3_0 )
18783 putVSReg( XT, mkexpr( result ) ); 18696 putVSReg( XT, mkexpr( result ) );
18784 18697
18785 assign( value, unop( Iop_V128HIto64, mkexpr( result ) ) ); 18698 assign( value, unop( Iop_V128HIto64, mkexpr( result ) ) );
18786 generate_store_FPRF( Ity_I64, value ); 18699 generate_store_FPRF( Ity_I64, value, vbi );
18787 return True; 18700 return True;
18788 18701
18789 } else if (inst_select == 17) { // xscvdphp 18702 } else if (inst_select == 17) { // xscvdphp
@@ -18798,7 +18711,7 @@ dis_vxs_misc( UInt theInstr, UInt opc2, int allow_isa_3_0 )
18798 assign( value, unop( Iop_64to32, unop( Iop_V128HIto64, 18711 assign( value, unop( Iop_64to32, unop( Iop_V128HIto64,
18799 mkexpr( result ) ) ) ); 18712 mkexpr( result ) ) ) );
18800 putVSReg( XT, mkexpr( result ) ); 18713 putVSReg( XT, mkexpr( result ) );
18801 generate_store_FPRF( Ity_I16, value ); 18714 generate_store_FPRF( Ity_I16, value, vbi );
18802 return True; 18715 return True;
18803 18716
18804 } else { 18717 } else {
@@ -21475,7 +21388,7 @@ dis_vx_store ( UInt theInstr )
21475} 21388}
21476 21389
21477static Bool 21390static Bool
21478dis_vx_Scalar_Round_to_quad_integer( UInt theInstr ) 21391dis_vx_Scalar_Round_to_quad_integer( UInt theInstr, const VexAbiInfo* vbi )
21479{ 21392{
21480 /* The ISA 3.0 instructions supported in this function require 21393 /* The ISA 3.0 instructions supported in this function require
21481 * the underlying hardware platform that supports the ISA3.0 21394 * the underlying hardware platform that supports the ISA3.0
@@ -21514,7 +21427,7 @@ dis_vx_Scalar_Round_to_quad_integer( UInt theInstr )
21514 DIP("xsrqpix %d,v%d,v%d,%d\n", R, vT_addr, vB_addr, RMC); 21427 DIP("xsrqpix %d,v%d,v%d,%d\n", R, vT_addr, vB_addr, RMC);
21515 assign( vT, binop( Iop_F128toI128S, rm, mkexpr( vB ) ) ); 21428 assign( vT, binop( Iop_F128toI128S, rm, mkexpr( vB ) ) );
21516 } 21429 }
21517 generate_store_FPRF( Ity_F128, vT ); 21430 generate_store_FPRF( Ity_F128, vT, vbi );
21518 } /* case 0x005 */ 21431 } /* case 0x005 */
21519 break; 21432 break;
21520 case 0x025: // xsrqpxp VSX Scalar Round Quad-Precision to 21433 case 0x025: // xsrqpxp VSX Scalar Round Quad-Precision to
@@ -21530,7 +21443,7 @@ dis_vx_Scalar_Round_to_quad_integer( UInt theInstr )
21530 21443
21531 DIP("xsrqpxp %d,v%d,v%d,%d\n", R, vT_addr, vB_addr, RMC); 21444 DIP("xsrqpxp %d,v%d,v%d,%d\n", R, vT_addr, vB_addr, RMC);
21532 assign( vT, binop( Iop_RndF128, rm, mkexpr( vB ) ) ); 21445 assign( vT, binop( Iop_RndF128, rm, mkexpr( vB ) ) );
21533 generate_store_FPRF( Ity_F128, vT ); 21446 generate_store_FPRF( Ity_F128, vT, vbi );
21534 } /* case 0x025 */ 21447 } /* case 0x025 */
21535 break; 21448 break;
21536 default: 21449 default:
@@ -21542,7 +21455,8 @@ dis_vx_Scalar_Round_to_quad_integer( UInt theInstr )
21542} 21455}
21543 21456
21544static Bool 21457static Bool
21545dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr ) 21458dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr,
21459 const VexAbiInfo* vbi )
21546{ 21460{
21547 /* The ISA 3.0 instructions supported in this function require 21461 /* The ISA 3.0 instructions supported in this function require
21548 * the underlying hardware platform that supports the ISA 3.0 21462 * the underlying hardware platform that supports the ISA 3.0
@@ -21582,7 +21496,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21582 assign( vT, triop( Iop_AddF128, set_round_to_Oddmode(), 21496 assign( vT, triop( Iop_AddF128, set_round_to_Oddmode(),
21583 mkexpr( vA ), mkexpr( vB ) ) ); 21497 mkexpr( vA ), mkexpr( vB ) ) );
21584 } 21498 }
21585 generate_store_FPRF( Ity_F128, vT ); 21499 generate_store_FPRF( Ity_F128, vT, vbi );
21586 break; 21500 break;
21587 } 21501 }
21588 case 0x024: // xsmulqp (VSX Scalar Multiply Quad-Precision[using round to Odd]) 21502 case 0x024: // xsmulqp (VSX Scalar Multiply Quad-Precision[using round to Odd])
@@ -21600,7 +21514,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21600 assign( vT, triop( Iop_MulF128, set_round_to_Oddmode(), mkexpr( vA ), 21514 assign( vT, triop( Iop_MulF128, set_round_to_Oddmode(), mkexpr( vA ),
21601 mkexpr( vB ) ) ); 21515 mkexpr( vB ) ) );
21602 } 21516 }
21603 generate_store_FPRF( Ity_F128, vT ); 21517 generate_store_FPRF( Ity_F128, vT, vbi );
21604 break; 21518 break;
21605 } 21519 }
21606 case 0x184: // xsmaddqp (VSX Scalar Multiply add Quad-Precision[using round to Odd]) 21520 case 0x184: // xsmaddqp (VSX Scalar Multiply add Quad-Precision[using round to Odd])
@@ -21625,7 +21539,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21625 qop( Iop_MAddF128, set_round_to_Oddmode(), mkexpr( vA ), 21539 qop( Iop_MAddF128, set_round_to_Oddmode(), mkexpr( vA ),
21626 mkexpr( vC ), mkexpr( vB ) ) ); 21540 mkexpr( vC ), mkexpr( vB ) ) );
21627 } 21541 }
21628 generate_store_FPRF( Ity_F128, vT ); 21542 generate_store_FPRF( Ity_F128, vT, vbi );
21629 break; 21543 break;
21630 } 21544 }
21631 case 0x1A4: // xsmsubqp (VSX Scalar Multiply Subtract Quad-Precision[using round to Odd]) 21545 case 0x1A4: // xsmsubqp (VSX Scalar Multiply Subtract Quad-Precision[using round to Odd])
@@ -21649,7 +21563,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21649 qop( Iop_MSubF128, set_round_to_Oddmode(), 21563 qop( Iop_MSubF128, set_round_to_Oddmode(),
21650 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) ); 21564 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) );
21651 } 21565 }
21652 generate_store_FPRF( Ity_F128, vT ); 21566 generate_store_FPRF( Ity_F128, vT, vbi );
21653 break; 21567 break;
21654 } 21568 }
21655 case 0x1C4: // xsnmaddqp (VSX Scalar Negative Multiply Add Quad-Precision[using round to Odd]) 21569 case 0x1C4: // xsnmaddqp (VSX Scalar Negative Multiply Add Quad-Precision[using round to Odd])
@@ -21673,7 +21587,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21673 qop( Iop_NegMAddF128, set_round_to_Oddmode(), 21587 qop( Iop_NegMAddF128, set_round_to_Oddmode(),
21674 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) ); 21588 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) );
21675 } 21589 }
21676 generate_store_FPRF( Ity_F128, vT ); 21590 generate_store_FPRF( Ity_F128, vT, vbi );
21677 break; 21591 break;
21678 } 21592 }
21679 case 0x1E4: // xsmsubqp (VSX Scalar Negatve Multiply Subtract Quad-Precision[using round to Odd]) 21593 case 0x1E4: // xsmsubqp (VSX Scalar Negatve Multiply Subtract Quad-Precision[using round to Odd])
@@ -21697,7 +21611,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21697 qop( Iop_NegMSubF128, set_round_to_Oddmode(), 21611 qop( Iop_NegMSubF128, set_round_to_Oddmode(),
21698 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) ); 21612 mkexpr( vA ), mkexpr( vC ), mkexpr( vB ) ) );
21699 } 21613 }
21700 generate_store_FPRF( Ity_F128, vT ); 21614 generate_store_FPRF( Ity_F128, vT, vbi );
21701 break; 21615 break;
21702 } 21616 }
21703 case 0x204: // xssubqp (VSX Scalar Subtract Quad-Precision[using round to Odd]) 21617 case 0x204: // xssubqp (VSX Scalar Subtract Quad-Precision[using round to Odd])
@@ -21714,7 +21628,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21714 assign( vT, triop( Iop_SubF128, set_round_to_Oddmode(), mkexpr( vA ), 21628 assign( vT, triop( Iop_SubF128, set_round_to_Oddmode(), mkexpr( vA ),
21715 mkexpr( vB ) ) ); 21629 mkexpr( vB ) ) );
21716 } 21630 }
21717 generate_store_FPRF( Ity_F128, vT ); 21631 generate_store_FPRF( Ity_F128, vT, vbi );
21718 break; 21632 break;
21719 } 21633 }
21720 case 0x224: // xsdivqp (VSX Scalar Divide Quad-Precision[using round to Odd]) 21634 case 0x224: // xsdivqp (VSX Scalar Divide Quad-Precision[using round to Odd])
@@ -21731,7 +21645,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21731 assign( vT, triop( Iop_DivF128, set_round_to_Oddmode(), mkexpr( vA ), 21645 assign( vT, triop( Iop_DivF128, set_round_to_Oddmode(), mkexpr( vA ),
21732 mkexpr( vB ) ) ); 21646 mkexpr( vB ) ) );
21733 } 21647 }
21734 generate_store_FPRF( Ity_F128, vT ); 21648 generate_store_FPRF( Ity_F128, vT, vbi );
21735 break; 21649 break;
21736 } 21650 }
21737 case 0x324: // xssqrtqp (VSX Scalar Square root Quad-Precision[using round to Odd]) 21651 case 0x324: // xssqrtqp (VSX Scalar Square root Quad-Precision[using round to Odd])
@@ -21752,7 +21666,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21752 assign( vT, binop( Iop_SqrtF128, set_round_to_Oddmode(), 21666 assign( vT, binop( Iop_SqrtF128, set_round_to_Oddmode(),
21753 mkexpr( vB ) ) ); 21667 mkexpr( vB ) ) );
21754 } 21668 }
21755 generate_store_FPRF( Ity_F128, vT ); 21669 generate_store_FPRF( Ity_F128, vT, vbi );
21756 break; 21670 break;
21757 } /* end case 27 */ 21671 } /* end case 27 */
21758 default: 21672 default:
@@ -21783,7 +21697,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21783 assign( tmp, unop( Iop_ReinterpF64asI64, 21697 assign( tmp, unop( Iop_ReinterpF64asI64,
21784 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) ); 21698 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) );
21785 assign( vT, unop( Iop_I64UtoF128, mkexpr( tmp ) ) ); 21699 assign( vT, unop( Iop_I64UtoF128, mkexpr( tmp ) ) );
21786 generate_store_FPRF( Ity_F128, vT ); 21700 generate_store_FPRF( Ity_F128, vT, vbi );
21787 break; 21701 break;
21788 } 21702 }
21789 case 9: // xsvqpswz VSX Scalar Truncate & Convert Quad-Precision 21703 case 9: // xsvqpswz VSX Scalar Truncate & Convert Quad-Precision
@@ -21803,7 +21717,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21803 assign( tmp, unop( Iop_ReinterpF64asI64, 21717 assign( tmp, unop( Iop_ReinterpF64asI64,
21804 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) ); 21718 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) );
21805 assign( vT, unop( Iop_I64StoF128, mkexpr( tmp ) ) ); 21719 assign( vT, unop( Iop_I64StoF128, mkexpr( tmp ) ) );
21806 generate_store_FPRF( Ity_F128, vT ); 21720 generate_store_FPRF( Ity_F128, vT, vbi );
21807 break; 21721 break;
21808 } 21722 }
21809 case 17: // xsvqpudz VSX Scalar Truncate & Convert Quad-Precision 21723 case 17: // xsvqpudz VSX Scalar Truncate & Convert Quad-Precision
@@ -21855,7 +21769,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21855 assign( tmp, unop( Iop_ReinterpF64asI64, 21769 assign( tmp, unop( Iop_ReinterpF64asI64,
21856 unop( Iop_F128HItoF64, mkexpr( vT ) ) ) ); 21770 unop( Iop_F128HItoF64, mkexpr( vT ) ) ) );
21857 21771
21858 generate_store_FPRF( Ity_I64, tmp ); 21772 generate_store_FPRF( Ity_I64, tmp, vbi );
21859 break; 21773 break;
21860 } 21774 }
21861 case 22: // xscvdpqp VSX Scalar Convert from Double-Precision 21775 case 22: // xscvdpqp VSX Scalar Convert from Double-Precision
@@ -21866,7 +21780,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr )
21866 assign( vT, unop( Iop_F64toF128, 21780 assign( vT, unop( Iop_F64toF128,
21867 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) ); 21781 unop( Iop_F128HItoF64, mkexpr( vB ) ) ) );
21868 21782
21869 generate_store_FPRF( Ity_F128, vT ); 21783 generate_store_FPRF( Ity_F128, vT, vbi );
21870 break; 21784 break;
21871 } 21785 }
21872 case 25: // xsvqpsdz VSX Scalar Truncate & Convert Quad-Precision 21786 case 25: // xsvqpsdz VSX Scalar Truncate & Convert Quad-Precision
@@ -28199,13 +28113,13 @@ DisResult disInstr_PPC_WRK (
28199 UInt vsxOpc2; 28113 UInt vsxOpc2;
28200 28114
28201 if (( opc2hi == 13 ) && ( opc2lo == 5)) { //xvtstdcsp 28115 if (( opc2hi == 13 ) && ( opc2lo == 5)) { //xvtstdcsp
28202 if (dis_vxs_misc(theInstr, 0x354, allow_isa_3_0)) 28116 if (dis_vxs_misc(theInstr, abiinfo, 0x354, allow_isa_3_0))
28203 goto decode_success; 28117 goto decode_success;
28204 goto decode_failure; 28118 goto decode_failure;
28205 } 28119 }
28206 28120
28207 if (( opc2hi == 15 ) && ( opc2lo == 5)) { //xvtstdcdp 28121 if (( opc2hi == 15 ) && ( opc2lo == 5)) { //xvtstdcdp
28208 if (dis_vxs_misc(theInstr, 0x3D4, allow_isa_3_0)) 28122 if (dis_vxs_misc(theInstr, abiinfo, 0x3D4, allow_isa_3_0))
28209 goto decode_success; 28123 goto decode_success;
28210 goto decode_failure; 28124 goto decode_failure;
28211 } 28125 }
@@ -28221,7 +28135,7 @@ DisResult disInstr_PPC_WRK (
28221 /* This is a special case of the XX1 form where the RA, RB 28135 /* This is a special case of the XX1 form where the RA, RB
28222 * fields hold an immediate value. 28136 * fields hold an immediate value.
28223 */ 28137 */
28224 if (dis_vxs_misc(theInstr, opc2, allow_isa_3_0)) goto decode_success; 28138 if (dis_vxs_misc(theInstr, abiinfo, opc2, allow_isa_3_0)) goto decode_success;
28225 goto decode_failure; 28139 goto decode_failure;
28226 } 28140 }
28227 28141
@@ -28231,7 +28145,8 @@ DisResult disInstr_PPC_WRK (
28231 case 0x8: case 0x28: case 0x48: case 0xc8: // xxsldwi, xxpermdi, xxmrghw, xxmrglw 28145 case 0x8: case 0x28: case 0x48: case 0xc8: // xxsldwi, xxpermdi, xxmrghw, xxmrglw
28232 case 0x068: case 0xE8: // xxperm, xxpermr 28146 case 0x068: case 0xE8: // xxperm, xxpermr
28233 case 0x018: case 0x148: // xxsel, xxspltw 28147 case 0x018: case 0x148: // xxsel, xxspltw
28234 if (dis_vx_permute_misc(theInstr, vsxOpc2)) goto decode_success; 28148 if (dis_vx_permute_misc(theInstr, vsxOpc2 ))
28149 goto decode_success;
28235 goto decode_failure; 28150 goto decode_failure;
28236 case 0x268: case 0x248: case 0x288: // xxlxor, xxlor, xxlnor, 28151 case 0x268: case 0x248: case 0x288: // xxlxor, xxlor, xxlnor,
28237 case 0x208: case 0x228: case 0x2A8: // xxland, xxlandc, xxlorc 28152 case 0x208: case 0x228: case 0x2A8: // xxland, xxlandc, xxlorc
@@ -28255,7 +28170,7 @@ DisResult disInstr_PPC_WRK (
28255 case 0x354: // xvtstdcsp 28170 case 0x354: // xvtstdcsp
28256 case 0x360:case 0x396: // xviexpsp, xsiexpdp 28171 case 0x360:case 0x396: // xviexpsp, xsiexpdp
28257 case 0x3D4: case 0x3E0: // xvtstdcdp, xviexpdp 28172 case 0x3D4: case 0x3E0: // xvtstdcdp, xviexpdp
28258 if (dis_vxs_misc(theInstr, vsxOpc2, allow_isa_3_0)) 28173 if (dis_vxs_misc(theInstr, abiinfo, vsxOpc2, allow_isa_3_0))
28259 goto decode_success; 28174 goto decode_success;
28260 goto decode_failure; 28175 goto decode_failure;
28261 case 0x08C: case 0x0AC: // xscmpudp, xscmpodp 28176 case 0x08C: case 0x0AC: // xscmpudp, xscmpodp
@@ -28409,7 +28324,7 @@ DisResult disInstr_PPC_WRK (
28409 case 0x5: // xsrqpi, xsrqpix 28324 case 0x5: // xsrqpi, xsrqpix
28410 case 0x25: // xsrqpxp 28325 case 0x25: // xsrqpxp
28411 if ( !mode64 || !allow_isa_3_0 ) goto decode_failure; 28326 if ( !mode64 || !allow_isa_3_0 ) goto decode_failure;
28412 if ( dis_vx_Scalar_Round_to_quad_integer( theInstr ) ) 28327 if ( dis_vx_Scalar_Round_to_quad_integer( theInstr, abiinfo ) )
28413 goto decode_success; 28328 goto decode_success;
28414 goto decode_failure; 28329 goto decode_failure;
28415 default: 28330 default:
@@ -28531,7 +28446,8 @@ DisResult disInstr_PPC_WRK (
28531 28446
28532 case 0x324: // xsabsqp, xsxexpqp,xsnabsqp, xsnegqp, xsxsigqp 28447 case 0x324: // xsabsqp, xsxexpqp,xsnabsqp, xsnegqp, xsxsigqp
28533 if ( inst_select == 27 ) { // xssqrtqp 28448 if ( inst_select == 27 ) { // xssqrtqp
28534 if ( dis_vx_Floating_Point_Arithmetic_quad_precision( theInstr ) ) 28449 if ( dis_vx_Floating_Point_Arithmetic_quad_precision( theInstr,
28450 abiinfo ) )
28535 goto decode_success; 28451 goto decode_success;
28536 } 28452 }
28537 28453
@@ -28566,7 +28482,8 @@ DisResult disInstr_PPC_WRK (
28566 case 0x344: // xscvudqp, xscvsdqp, xscvqpdp, xscvqpdpo, xsvqpdp 28482 case 0x344: // xscvudqp, xscvsdqp, xscvqpdp, xscvqpdpo, xsvqpdp
28567 // xscvqpswz, xscvqpuwz, xscvqpudz, xscvqpsdz 28483 // xscvqpswz, xscvqpuwz, xscvqpudz, xscvqpsdz
28568 if ( !mode64 || !allow_isa_3_0 ) goto decode_failure; 28484 if ( !mode64 || !allow_isa_3_0 ) goto decode_failure;
28569 if ( dis_vx_Floating_Point_Arithmetic_quad_precision( theInstr ) ) 28485 if ( dis_vx_Floating_Point_Arithmetic_quad_precision( theInstr,
28486 abiinfo ) )
28570 goto decode_success; 28487 goto decode_success;
28571 goto decode_failure; 28488 goto decode_failure;
28572 28489