|
From: Carl L. <ca...@so...> - 2020-09-22 16:49:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ad293d5168c7966329681da62a952183b61d5a05 commit ad293d5168c7966329681da62a952183b61d5a05 Author: Carl Love <ce...@us...> Date: Wed May 6 15:27:32 2020 -0500 Instruction Prefix Support Diff: --- VEX/priv/guest_ppc_toIR.c | 986 +++++++++++++++++++++++++++++++++------------- VEX/pub/libvex.h | 1 + 2 files changed, 718 insertions(+), 269 deletions(-) diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index 96217fb054..c5016faee6 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -274,11 +274,30 @@ static Bool OV32_CA32_supported = False; #define SIGN_BIT32 0x80000000 #define SIGN_MASK32 0x7fffffff +/* The instruction size can be either 4 byte (word instruction) or 8 bytes + (prefix instruction) starting with ISA 3.1 */ +#define WORD_INST_SIZE 4 +#define PREFIX_INST_SIZE 8 /*------------------------------------------------------------*/ /*--- Debugging output ---*/ /*------------------------------------------------------------*/ +/* Pre DIP macro for prefix instruction printing. */ +#define pDIP(flag,format, args...) \ + if (vex_traceflags & VEX_TRACE_FE){ \ + if (flag) {vex_printf("p"); vex_printf(format, ## args);} \ + else {vex_printf(format, ## args); vex_printf("\n");}} + +/* Post DIP macro to print additional args for prefix instruction printing. */ +#define DIPp(flag,format, args...) \ + if (vex_traceflags & VEX_TRACE_FE) { \ + if (flag) {vex_printf(format, ## args); vex_printf("\n");}} + +/* Post DIP macro with no additional args for prefix instruction printing. */ +#define DIPn(flag) \ + if (vex_traceflags & VEX_TRACE_FE) {if (flag) vex_printf("\n");} + #define DIP(format, args...) \ if (vex_traceflags & VEX_TRACE_FE) \ vex_printf(format, ## args) @@ -532,7 +551,11 @@ static ULong MASK64( UInt begin, UInt end ) static Addr64 nextInsnAddr( void ) { - return guest_CIA_curr_instr + 4; + /* Note in the case of a prefix instruction, delta has already been + incremented by WORD_INST_SIZE to move past the prefix part of the + instruction. So only need to increment by WORD_INST_SIZE to get to + the start of the next instruction. */ + return guest_CIA_curr_instr + WORD_INST_SIZE; } @@ -1602,6 +1625,9 @@ typedef enum { DWORD } _popcount_data_type; +/*-----------------------------------------------------------*/ +/*--- IR popcount helpers ---*/ +/*-----------------------------------------------------------*/ /* Generate an IR sequence to do a popcount operation on the supplied IRTemp, and return a new IRTemp holding the result. 'ty' may be Ity_I32 or Ity_I64 only. */ @@ -3027,7 +3053,44 @@ static void set_XER_OV_OV32_ADDEX ( IRType ty, IRExpr* res, } } +/*-----------------------------------------------------------*/ +/*--- Prefix instruction helpers ---*/ +/*-----------------------------------------------------------*/ +/* ENABLE_PREFIX_CHECK is for development purposes. Turn off for production + releases to improve performance. */ +#define ENABLE_PREFIX_CHECK 0 + +#if ENABLE_PREFIX_CHECK +#define PREFIX_CHECK { vassert( !prefix_instruction( prefix ) ); } +#else +#define PREFIX_CHECK { } +#endif + +/* Bits 0:5 of all prefix instructions are assigned the primary opcode + value 0b000001. 0b000001 is not available for use as a primary opcode for + either word instructions or suffixes of prefixed instructions. */ + +#define PREFIX_INST 0x1 +#define PREFIX_NOP_INVALID -1 + +#define CONCAT(_aa,_bb,_cc) ((_aa) << (_cc) | (_bb)) +/* The codes for the prefix types */ +#define pType0 0 /* Eight-Byte Load/Store Instructions */ +#define pType1 1 /* Eight-Byte Register-to-Register Instructions */ +#define pType2 2 /* Modified Load/Store Instructions */ +#define pType3 3 /* Modified Register-to-Register Instructions */ + +static int prefix_instruction ( UInt instr ) +{ + /* Format of first 4 bytes of prefix instruction + bits [0:5] - must be 0x1 identifying this as a prefix inst + bits [6:7] - prefix instruction type. */ + UChar opcode = IFIELD( instr, 26, 6); + + if (opcode == PREFIX_INST) return True; + return False; +} /*------------------------------------------------------------*/ /*--- Read/write to guest-state --- */ @@ -5107,7 +5170,7 @@ static void storeTMfailure( Addr64 err_address, ULong tm_reason, /* Integer Arithmetic Instructions */ -static Bool dis_int_mult_add ( UInt theInstr ) +static Bool dis_int_mult_add ( UInt prefix, UInt theInstr ) { /* VA-Form */ UChar rD_addr = ifieldRegDS( theInstr ); @@ -5131,6 +5194,9 @@ static Bool dis_int_mult_add ( UInt theInstr ) assign( rB, getIReg( rB_addr ) ); assign( rC, getIReg( rC_addr ) ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc2) { case 0x30: // maddhd multiply-add High doubleword signed DIP("maddhd r%u,r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr, rC_addr); @@ -5207,7 +5273,7 @@ static Bool dis_int_mult_add ( UInt theInstr ) return True; } -static Bool dis_int_arith ( UInt theInstr ) +static Bool dis_int_arith ( UInt prefix, UInt theInstr ) { /* D-Form, XO-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -5227,6 +5293,9 @@ static Bool dis_int_arith ( UInt theInstr ) Bool do_rc = False; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rA, getIReg(rA_addr) ); assign( rB, getIReg(rB_addr) ); // XO-Form: rD, rA, rB @@ -5876,7 +5945,7 @@ static Bool dis_int_arith ( UInt theInstr ) return True; } -static Bool dis_modulo_int ( UInt theInstr ) +static Bool dis_modulo_int ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -5887,6 +5956,9 @@ static Bool dis_modulo_int ( UInt theInstr ) IRType ty = mode64 ? Ity_I64 : Ity_I32; IRTemp rD = newTemp( ty ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc1) { /* X-Form */ case 0x1F: @@ -6258,7 +6330,7 @@ static Bool dis_modulo_int ( UInt theInstr ) /* Byte Compare Instructions */ -static Bool dis_byte_cmp ( UInt theInstr ) +static Bool dis_byte_cmp ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -6270,6 +6342,9 @@ static Bool dis_byte_cmp ( UInt theInstr ) UChar L = toUChar( IFIELD( theInstr, 21, 1 ) ); UChar BF = toUChar( IFIELD( theInstr, 23, 3 ) ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rA, getIReg(rA_addr) ); assign( rB, getIReg(rB_addr) ); @@ -6376,12 +6451,15 @@ static Bool dis_byte_cmp ( UInt theInstr ) /* * Integer Miscellaneous instructions */ -static Bool dis_int_misc ( UInt theInstr ) +static Bool dis_int_misc ( UInt prefix, UInt theInstr ) { Int wc = IFIELD(theInstr, 21, 2); UChar opc1 = ifieldOPC(theInstr); UInt opc2 = ifieldOPClo10(theInstr); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if ( opc1 != 0x1F ) { vex_printf("dis_modulo_int(ppc)(opc1)\n"); return False; @@ -6416,7 +6494,7 @@ static Bool dis_int_misc ( UInt theInstr ) /* Integer Compare Instructions */ -static Bool dis_int_cmp ( UInt theInstr ) +static Bool dis_int_cmp ( UInt prefix, UInt theInstr ) { /* D-Form, X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -6433,6 +6511,9 @@ static Bool dis_int_cmp ( UInt theInstr ) IRExpr *a = getIReg(rA_addr); IRExpr *b; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (!mode64 && flag_L==1) { // L==1 invalid for 32 bit. vex_printf("dis_int_cmp(ppc)(flag_L)\n"); return False; @@ -6580,7 +6661,7 @@ static Bool dis_int_cmp ( UInt theInstr ) /* Integer Logical Instructions */ -static Bool dis_int_logic ( UInt theInstr ) +static Bool dis_int_logic ( UInt prefix, UInt theInstr ) { /* D-Form, X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -6597,6 +6678,9 @@ static Bool dis_int_logic ( UInt theInstr ) IRTemp rB = newTemp(ty); Bool do_rc = False; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rS, getIReg(rS_addr) ); assign( rB, getIReg(rB_addr) ); @@ -6971,7 +7055,7 @@ static Bool dis_int_logic ( UInt theInstr ) /* Integer Parity Instructions */ -static Bool dis_int_parity ( UInt theInstr ) +static Bool dis_int_parity ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -7004,6 +7088,9 @@ static Bool dis_int_parity ( UInt theInstr ) IROp to_bit = (mode64 ? Iop_64to1 : Iop_32to1); IROp shr_op = (mode64 ? Iop_Shr64 : Iop_Shr32); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1f || rB_addr || b0) { vex_printf("dis_int_parity(ppc)(0x1F,opc1:rB|b0)\n"); return False; @@ -7100,7 +7187,7 @@ static Bool dis_int_parity ( UInt theInstr ) /* Integer Rotate Instructions */ -static Bool dis_int_rot ( UInt theInstr ) +static Bool dis_int_rot ( UInt prefix, UInt theInstr ) { /* M-Form, MDS-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -7124,6 +7211,9 @@ static Bool dis_int_rot ( UInt theInstr ) UInt mask32; ULong mask64; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rS, getIReg(rS_addr) ); assign( rB, getIReg(rB_addr) ); @@ -7350,7 +7440,7 @@ static Bool dis_int_rot ( UInt theInstr ) /* Integer Load Instructions */ -static Bool dis_int_load ( UInt theInstr ) +static Bool dis_int_load ( UInt prefix, UInt theInstr ) { /* D-Form, X-Form, DS-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -7367,6 +7457,9 @@ static Bool dis_int_load ( UInt theInstr ) IRTemp EA = newTemp(ty); IRExpr* val; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc1) { case 0x1F: // register offset assign( EA, ea_rAor0_idxd( rA_addr, rB_addr ) ); @@ -7648,7 +7741,7 @@ static Bool dis_int_load ( UInt theInstr ) /* Integer Store Instructions */ -static Bool dis_int_store ( UInt theInstr, const VexAbiInfo* vbi ) +static Bool dis_int_store ( UInt prefix, UInt theInstr, const VexAbiInfo* vbi ) { /* D-Form, X-Form, DS-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -7666,6 +7759,9 @@ static Bool dis_int_store ( UInt theInstr, const VexAbiInfo* vbi ) IRTemp rB = newTemp(ty); IRTemp EA = newTemp(ty); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rB, getIReg(rB_addr) ); assign( rS, getIReg(rS_addr) ); @@ -7874,7 +7970,7 @@ static Bool dis_int_store ( UInt theInstr, const VexAbiInfo* vbi ) /* Integer Load/Store Multiple Instructions */ -static Bool dis_int_ldst_mult ( UInt theInstr ) +static Bool dis_int_ldst_mult ( UInt prefix, UInt theInstr ) { /* D-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -7891,6 +7987,9 @@ static Bool dis_int_ldst_mult ( UInt theInstr ) UInt ea_off = 0; IRExpr* irx_addr; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( EA, ea_rAor0_simm( rA_addr, simm16 ) ); switch (opc1) { @@ -8018,7 +8117,7 @@ void generate_stsw_sequence ( IRTemp tNBytes, // # bytes, :: Ity_I32 } } -static Bool dis_int_ldst_str ( UInt theInstr, /*OUT*/Bool* stopHere ) +static Bool dis_int_ldst_str ( UInt prefix, UInt theInstr, /*OUT*/Bool* stopHere ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -8034,6 +8133,9 @@ static Bool dis_int_ldst_str ( UInt theInstr, /*OUT*/Bool* stopHere ) IRTemp t_EA = newTemp(ty); IRTemp t_nbytes = IRTemp_INVALID; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + *stopHere = False; if (opc1 != 0x1F || b0 != 0) { @@ -8186,7 +8288,7 @@ static IRExpr* /* :: Ity_I32 */ branch_cond_ok( UInt BO, UInt BI ) /* Integer Branch Instructions */ -static Bool dis_branch ( UInt theInstr, +static Bool dis_branch ( UInt prefix, UInt theInstr, const VexAbiInfo* vbi, /*OUT*/DisResult* dres ) { @@ -8210,6 +8312,9 @@ static Bool dis_branch ( UInt theInstr, IRConst* c_nia = mkSzConst(ty, nextInsnAddr()); IRTemp lr_old = newTemp(ty); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + /* Hack to pass through code that just wants to read the PC */ if (theInstr == 0x429F0005) { DIP("bcl 0x%x, 0x%x (a.k.a mr lr,cia+4)\n", BO, BI); @@ -8390,7 +8495,7 @@ static Bool dis_branch ( UInt theInstr, /* * PC relative instruction */ -static Bool dis_pc_relative ( UInt theInstr ) +static Bool dis_pc_relative ( UInt prefix, UInt theInstr ) { /* DX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -8402,6 +8507,9 @@ static Bool dis_pc_relative ( UInt theInstr ) UInt opc2 = ifieldOPClo5(theInstr); IRType ty = mode64 ? Ity_I64 : Ity_I32; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if ( opc1 != 0x13) { vex_printf("dis_pc_relative(ppc)(opc1)\n"); return False; @@ -8441,7 +8549,7 @@ static Bool dis_pc_relative ( UInt theInstr ) /* Condition Register Logical Instructions */ -static Bool dis_cond_logic ( UInt theInstr ) +static Bool dis_cond_logic ( UInt prefix, UInt theInstr ) { /* XL-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -8457,6 +8565,9 @@ static Bool dis_cond_logic ( UInt theInstr ) IRTemp crbA = newTemp(Ity_I32); IRTemp crbB = newTemp(Ity_I32); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 19 || b0 != 0) { vex_printf("dis_cond_logic(ppc)(opc1)\n"); return False; @@ -8625,7 +8736,7 @@ static Bool do_trap ( UChar TO, return False; /* not an unconditional trap */ } -static Bool dis_trapi ( UInt theInstr, +static Bool dis_trapi ( UInt prefix, UInt theInstr, /*OUT*/DisResult* dres ) { /* D-Form */ @@ -8638,6 +8749,9 @@ static Bool dis_trapi ( UInt theInstr, IRType ty = mode64 ? Ity_I64 : Ity_I32; Bool uncond = False; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc1) { case 0x03: // twi (Trap Word Immediate, PPC32 p548) uncond = do_trap( TO, @@ -8676,7 +8790,7 @@ static Bool dis_trapi ( UInt theInstr, return True; } -static Bool dis_trap ( UInt theInstr, +static Bool dis_trap ( UInt prefix, UInt theInstr, /*OUT*/DisResult* dres ) { /* X-Form */ @@ -8688,6 +8802,9 @@ static Bool dis_trap ( UInt theInstr, IRType ty = mode64 ? Ity_I64 : Ity_I32; Bool uncond = False; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (ifieldBIT0(theInstr) != 0) return False; @@ -8734,11 +8851,14 @@ static Bool dis_trap ( UInt theInstr, /* System Linkage Instructions */ -static Bool dis_syslink ( UInt theInstr, +static Bool dis_syslink ( UInt prefix, UInt theInstr, const VexAbiInfo* abiinfo, DisResult* dres ) { IRType ty = mode64 ? Ity_I64 : Ity_I32; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (theInstr != 0x44000002) { vex_printf("dis_syslink(ppc)(theInstr)\n"); return False; @@ -8772,7 +8892,7 @@ static Bool dis_syslink ( UInt theInstr, check any stores it does. Instead, the reservation is cancelled when the scheduler switches to another thread (run_thread_for_a_while()). */ -static Bool dis_memsync ( UInt theInstr ) +static Bool dis_memsync ( UInt prefix, UInt theInstr ) { /* X-Form, XL-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -8790,6 +8910,9 @@ static Bool dis_memsync ( UInt theInstr ) IRType ty = mode64 ? Ity_I64 : Ity_I32; IRTemp EA = newTemp(ty); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( EA, ea_rAor0_idxd( rA_addr, rB_addr ) ); switch (opc1) { @@ -9182,7 +9305,7 @@ static Bool dis_memsync ( UInt theInstr ) /* Integer Shift Instructions */ -static Bool dis_int_shift ( UInt theInstr ) +static Bool dis_int_shift ( UInt prefix, UInt theInstr ) { /* X-Form, XS-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -9203,6 +9326,9 @@ static Bool dis_int_shift ( UInt theInstr ) IRTemp rB_lo32 = newTemp(Ity_I32); IRExpr* e_tmp; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rS, getIReg(rS_addr) ); assign( rB, getIReg(rB_addr) ); assign( rS_lo32, mkNarrowTo32(ty, mkexpr(rS)) ); @@ -9437,7 +9563,7 @@ static IRExpr* /* :: Ity_I32 */ gen_byterev16 ( IRTemp t ) ); } -static Bool dis_int_ldst_rev ( UInt theInstr ) +static Bool dis_int_ldst_rev ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -9453,6 +9579,9 @@ static Bool dis_int_ldst_rev ( UInt theInstr ) IRTemp w1 = newTemp(Ity_I32); IRTemp w2 = newTemp(Ity_I32); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F || b0 != 0) { vex_printf("dis_int_ldst_rev(ppc)(opc1|b0)\n"); return False; @@ -9544,7 +9673,7 @@ static Bool dis_int_ldst_rev ( UInt theInstr ) /* Processor Control Instructions */ -static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt theInstr ) +static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt prefix, UInt theInstr ) { UChar opc1 = ifieldOPC(theInstr); @@ -9567,6 +9696,10 @@ static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt theInstr ) IRType ty = mode64 ? Ity_I64 : Ity_I32; IRTemp rS = newTemp(ty); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rS, getIReg(rS_addr) ); /* Reorder SPR field as per PPC32 p470 */ @@ -10021,7 +10154,7 @@ static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt theInstr ) /* Cache Management Instructions */ -static Bool dis_cache_manage ( UInt theInstr, +static Bool dis_cache_manage ( UInt prefix, UInt theInstr, DisResult* dres, const VexArchInfo* guest_archinfo ) { @@ -10037,6 +10170,9 @@ static Bool dis_cache_manage ( UInt theInstr, IRType ty = mode64 ? Ity_I64 : Ity_I32; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + // Check for valid hint values for dcbt and dcbtst as currently described in // ISA 2.07. If valid, then we simply set b21to25 to zero since we have no // means of modeling the hint anyway. @@ -10346,7 +10482,7 @@ static IRExpr * Complement_non_NaN( IRExpr * value, IRExpr * nan_mask ) /* Floating Point Load Instructions */ -static Bool dis_fp_load ( UInt theInstr ) +static Bool dis_fp_load ( UInt prefix, UInt theInstr ) { /* X-Form, D-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -10365,6 +10501,9 @@ static Bool dis_fp_load ( UInt theInstr ) IRTemp iHi = newTemp(Ity_I32); IRTemp iLo = newTemp(Ity_I32); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( rA, getIReg(rA_addr) ); assign( rB, getIReg(rB_addr) ); @@ -10484,7 +10623,7 @@ static Bool dis_fp_load ( UInt theInstr ) /* Floating Point Store Instructions */ -static Bool dis_fp_store ( UInt theInstr ) +static Bool dis_fp_store ( UInt prefix, UInt theInstr ) { /* X-Form, D-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -10502,6 +10641,9 @@ static Bool dis_fp_store ( UInt theInstr ) IRTemp rA = newTemp(ty); IRTemp rB = newTemp(ty); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frS, getFReg(frS_addr) ); assign( rA, getIReg(rA_addr) ); assign( rB, getIReg(rB_addr) ); @@ -10612,7 +10754,7 @@ static Bool dis_fp_store ( UInt theInstr ) /* Floating Point Arith Instructions */ -static Bool dis_fp_arith ( UInt theInstr ) +static Bool dis_fp_arith ( UInt prefix, UInt theInstr ) { /* A-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -10640,6 +10782,9 @@ static Bool dis_fp_arith ( UInt theInstr ) zero. Hence cr1 should be cleared if this is a . form insn. */ Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getFReg(frA_addr)); assign( frB, getFReg(frB_addr)); assign( frC, getFReg(frC_addr)); @@ -10850,7 +10995,7 @@ static Bool dis_fp_arith ( UInt theInstr ) /* Floating Point Mult-Add Instructions */ -static Bool dis_fp_multadd ( UInt theInstr ) +static Bool dis_fp_multadd ( UInt prefix, UInt theInstr ) { /* A-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -10882,6 +11027,9 @@ static Bool dis_fp_multadd ( UInt theInstr ) zero. Hence cr1 should be cleared if this is a . form insn. */ Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + /* Bind the rounding mode expression to a temp; there's no point in creating gratuitous CSEs, as we know we'll need to use it twice. */ @@ -11352,7 +11500,7 @@ static IRExpr * do_fp_tdiv(IRTemp frA_int, IRTemp frB_int) binop( Iop_Shl32, mkexpr(fe_flag), mkU8( 1 ) ) ); } -static Bool dis_fp_tests ( UInt theInstr ) +static Bool dis_fp_tests ( UInt prefix, UInt theInstr ) { UChar opc1 = ifieldOPC(theInstr); UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); @@ -11361,6 +11509,9 @@ static Bool dis_fp_tests ( UInt theInstr ) UInt opc2 = ifieldOPClo10(theInstr); IRTemp frB_I64 = newTemp(Ity_I64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3F || b0 != 0 ){ vex_printf("dis_fp_tests(ppc)(ftdiv)\n"); return False; @@ -11419,7 +11570,7 @@ static Bool dis_fp_tests ( UInt theInstr ) /* Floating Point Compare Instructions */ -static Bool dis_fp_cmp ( UInt theInstr ) +static Bool dis_fp_cmp ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -11436,6 +11587,9 @@ static Bool dis_fp_cmp ( UInt theInstr ) IRTemp frA = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3F || b21to22 != 0 || b0 != 0) { vex_printf("dis_fp_cmp(ppc)(instr)\n"); return False; @@ -11516,7 +11670,7 @@ static Bool dis_fp_cmp ( UInt theInstr ) /* Floating Point Rounding/Conversion Instructions */ -static Bool dis_fp_round ( UInt theInstr ) +static Bool dis_fp_round ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -11542,6 +11696,10 @@ static Bool dis_fp_round ( UInt theInstr ) simulating exceptions, the exception status will appear to be zero. Hence cr1 should be cleared if this is a . form insn. */ Bool clear_CR1 = True; + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if ((!(opc1 == 0x3F || opc1 == 0x3B)) || b16to20 != 0) { vex_printf("dis_fp_round(ppc)(instr)\n"); return False; @@ -11729,7 +11887,7 @@ putFR: /* Floating Point Pair Instructions */ -static Bool dis_fp_pair ( UInt theInstr ) +static Bool dis_fp_pair ( UInt prefix, UInt theInstr ) { /* X-Form/DS-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -11748,6 +11906,9 @@ static Bool dis_fp_pair ( UInt theInstr ) UChar b0 = ifieldBIT0(theInstr); Bool is_load = 0; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc1) { case 0x1F: // register offset /* These instructions work on a pair of registers. The specified @@ -11986,7 +12147,7 @@ static Bool dis_fp_pair ( UInt theInstr ) /* Floating Point Merge Instructions */ -static Bool dis_fp_merge ( UInt theInstr ) +static Bool dis_fp_merge ( UInt prefix, UInt theInstr ) { /* X-Form */ UInt opc2 = ifieldOPClo10(theInstr); @@ -11998,6 +12159,9 @@ static Bool dis_fp_merge ( UInt theInstr ) IRTemp frA = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getFReg(frA_addr)); assign( frB, getFReg(frB_addr)); @@ -12040,7 +12204,7 @@ static Bool dis_fp_merge ( UInt theInstr ) /* Floating Point Move Instructions */ -static Bool dis_fp_move ( UInt theInstr ) +static Bool dis_fp_move ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -12057,6 +12221,9 @@ static Bool dis_fp_move ( UInt theInstr ) IRTemp signA; IRTemp hiD; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3F || (frA_addr != 0 && opc2 != 0x008)) { vex_printf("dis_fp_move(ppc)(instr)\n"); return False; @@ -12141,13 +12308,16 @@ static Bool dis_fp_move ( UInt theInstr ) /* Floating Point Status/Control Register Instructions */ -static Bool dis_fp_scr ( UInt theInstr, Bool GX_level ) +static Bool dis_fp_scr ( UInt prefix, UInt theInstr, Bool GX_level ) { /* Many forms - see each switch case */ UChar opc1 = ifieldOPC(theInstr); UInt opc2 = ifieldOPClo10(theInstr); UChar flag_rC = ifieldBIT0(theInstr); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3F) { vex_printf("dis_fp_scr(ppc)(instr)\n"); return False; @@ -13078,7 +13248,7 @@ static IRExpr * Check_unordered(IRExpr * val) /*------------------------------------------------------------*/ /* DFP Arithmetic instructions */ -static Bool dis_dfp_arith(UInt theInstr) +static Bool dis_dfp_arith( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); @@ -13099,6 +13269,9 @@ static Bool dis_dfp_arith(UInt theInstr) */ Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getDReg( frA_addr ) ); assign( frB, getDReg( frB_addr ) ); @@ -13136,7 +13309,7 @@ static Bool dis_dfp_arith(UInt theInstr) } /* Quad DFP Arithmetic instructions */ -static Bool dis_dfp_arithq(UInt theInstr) +static Bool dis_dfp_arithq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); @@ -13157,6 +13330,9 @@ static Bool dis_dfp_arithq(UInt theInstr) */ Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getDReg_pair( frA_addr ) ); assign( frB, getDReg_pair( frB_addr ) ); @@ -13194,7 +13370,7 @@ static Bool dis_dfp_arithq(UInt theInstr) } /* DFP 64-bit logical shift instructions */ -static Bool dis_dfp_shift(UInt theInstr) { +static Bool dis_dfp_shift( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo9( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13205,6 +13381,9 @@ static Bool dis_dfp_shift(UInt theInstr) { IRTemp frS = newTemp( Ity_D64 ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getDReg( frA_addr ) ); switch (opc2) { @@ -13231,7 +13410,7 @@ static Bool dis_dfp_shift(UInt theInstr) { } /* Quad DFP logical shift instructions */ -static Bool dis_dfp_shiftq(UInt theInstr) { +static Bool dis_dfp_shiftq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo9( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13242,6 +13421,9 @@ static Bool dis_dfp_shiftq(UInt theInstr) { IRTemp frS = newTemp( Ity_D128 ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getDReg_pair( frA_addr ) ); switch (opc2) { @@ -13268,7 +13450,7 @@ static Bool dis_dfp_shiftq(UInt theInstr) { } /* DFP 64-bit format conversion instructions */ -static Bool dis_dfp_fmt_conv(UInt theInstr) { +static Bool dis_dfp_fmt_conv( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frB_addr = ifieldRegB( theInstr ); @@ -13278,6 +13460,9 @@ static Bool dis_dfp_fmt_conv(UInt theInstr) { IRTemp frS; Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc2) { case 0x102: //dctdp DIP( "dctdp%s fr%u,fr%u\n", @@ -13334,7 +13519,7 @@ static Bool dis_dfp_fmt_conv(UInt theInstr) { } /* Quad DFP format conversion instructions */ -static Bool dis_dfp_fmt_convq(UInt theInstr) { +static Bool dis_dfp_fmt_convq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frB_addr = ifieldRegB( theInstr ); @@ -13346,6 +13531,9 @@ static Bool dis_dfp_fmt_convq(UInt theInstr) { UChar flag_rC = ifieldBIT0( theInstr ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc2) { case 0x102: // dctqpq DIP( "dctqpq%s fr%u,fr%u\n", @@ -13398,7 +13586,7 @@ static Bool dis_dfp_fmt_convq(UInt theInstr) { return True; } -static Bool dis_dfp_round( UInt theInstr ) { +static Bool dis_dfp_round( UInt prefix, UInt theInstr ) { UChar frS_addr = ifieldRegDS(theInstr); UChar R = IFIELD(theInstr, 16, 1); UChar RMC = IFIELD(theInstr, 9, 2); @@ -13409,6 +13597,9 @@ static Bool dis_dfp_round( UInt theInstr ) { UInt opc2 = ifieldOPClo8( theInstr ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc2) { /* drintn, is the same as drintx. The only difference is this * instruction does not generate an exception for an inexact operation. @@ -13443,7 +13634,7 @@ static Bool dis_dfp_round( UInt theInstr ) { return True; } -static Bool dis_dfp_roundq(UInt theInstr) { +static Bool dis_dfp_roundq( UInt prefix, UInt theInstr ) { UChar frS_addr = ifieldRegDS( theInstr ); UChar frB_addr = ifieldRegB( theInstr ); UChar R = IFIELD(theInstr, 16, 1); @@ -13454,6 +13645,9 @@ static Bool dis_dfp_roundq(UInt theInstr) { Bool clear_CR1 = True; UInt opc2 = ifieldOPClo8( theInstr ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + switch (opc2) { /* drintnq, is the same as drintxq. The only difference is this * instruction does not generate an exception for an inexact operation. @@ -13484,7 +13678,7 @@ static Bool dis_dfp_roundq(UInt theInstr) { return True; } -static Bool dis_dfp_quantize_sig_rrnd(UInt theInstr) { +static Bool dis_dfp_quantize_sig_rrnd( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo8( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13498,6 +13692,9 @@ static Bool dis_dfp_quantize_sig_rrnd(UInt theInstr) { IRTemp frS = newTemp( Ity_D64 ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frB, getDReg( frB_addr ) ); switch (opc2) { @@ -13578,7 +13775,7 @@ static Bool dis_dfp_quantize_sig_rrnd(UInt theInstr) { return True; } -static Bool dis_dfp_quantize_sig_rrndq(UInt theInstr) { +static Bool dis_dfp_quantize_sig_rrndq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo8( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13592,6 +13789,9 @@ static Bool dis_dfp_quantize_sig_rrndq(UInt theInstr) { IRTemp frS = newTemp( Ity_D128 ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frB, getDReg_pair( frB_addr ) ); switch (opc2) { @@ -13673,7 +13873,7 @@ static Bool dis_dfp_quantize_sig_rrndq(UInt theInstr) { return True; } -static Bool dis_dfp_extract_insert(UInt theInstr) { +static Bool dis_dfp_extract_insert( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13686,6 +13886,9 @@ static Bool dis_dfp_extract_insert(UInt theInstr) { IRTemp frS = newTemp( Ity_D64 ); IRTemp tmp = newTemp( Ity_I64 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frA, getDReg( frA_addr ) ); assign( frB, getDReg( frB_addr ) ); @@ -13719,7 +13922,7 @@ static Bool dis_dfp_extract_insert(UInt theInstr) { return True; } -static Bool dis_dfp_extract_insertq(UInt theInstr) { +static Bool dis_dfp_extract_insertq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); UChar frS_addr = ifieldRegDS( theInstr ); UChar frA_addr = ifieldRegA( theInstr ); @@ -13733,6 +13936,9 @@ static Bool dis_dfp_extract_insertq(UInt theInstr) { IRTemp tmp = newTemp( Ity_I64 ); Bool clear_CR1 = True; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frB, getDReg_pair( frB_addr ) ); switch (opc2) { @@ -13770,7 +13976,7 @@ static Bool dis_dfp_extract_insertq(UInt theInstr) { } /* DFP 64-bit comparison instructions */ -static Bool dis_dfp_compare(UInt theInstr) { +static Bool dis_dfp_compare( UInt prefix, UInt theInstr ) { /* X-Form */ UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); // AKA BF UChar frA_addr = ifieldRegA( theInstr ); @@ -13782,6 +13988,8 @@ static Bool dis_dfp_compare(UInt theInstr) { IRTemp ccIR = newTemp( Ity_I32 ); IRTemp ccPPC32 = newTemp( Ity_I32 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK /* Note: Differences between dcmpu and dcmpo are only in exception flag settings, which aren't supported anyway. */ @@ -13845,7 +14053,7 @@ static Bool dis_dfp_compare(UInt theInstr) { } /* Test class/group/exponent/significance instructions. */ -static Bool dis_dfp_exponent_test ( UInt theInstr ) +static Bool dis_dfp_exponent_test ( UInt prefix, UInt theInstr ) { UChar frA_addr = ifieldRegA( theInstr ); UChar frB_addr = ifieldRegB( theInstr ); @@ -13872,6 +14080,9 @@ static Bool dis_dfp_exponent_test ( UInt theInstr ) IRTemp cc3 = newTemp( Ity_I32 ); IRTemp cc = newTemp( Ity_I32 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + /* The dtstex and dtstexg instructions only differ in the size of the * exponent field. The following switch statement takes care of the size * specific setup. Once the value of the exponents, the G-field shift @@ -14038,7 +14249,7 @@ static Bool dis_dfp_exponent_test ( UInt theInstr ) } /* Test class/group/exponent/significance instructions. */ -static Bool dis_dfp_class_test ( UInt theInstr ) +static Bool dis_dfp_class_test ( UInt prefix, UInt theInstr ) { UChar frA_addr = ifieldRegA( theInstr ); IRTemp frA = newTemp( Ity_D64 ); @@ -14084,6 +14295,9 @@ static Bool dis_dfp_class_test ( UInt theInstr ) IRTemp dcm4 = newTemp( Ity_I32 ); IRTemp dcm5 = newTemp( Ity_I32 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + /* The only difference between the dtstdc and dtstdcq instructions is * size of the T and G fields. The calculation of the 4 bit field * is the same. Setup the parameters and values that are DFP size @@ -14482,7 +14696,7 @@ static Bool dis_dfp_class_test ( UInt theInstr ) return True; } -static Bool dis_dfp_bcd(UInt theInstr) { +static Bool dis_dfp_bcd( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); ULong sp = IFIELD(theInstr, 19, 2); ULong s = IFIELD(theInstr, 20, 1); @@ -14499,6 +14713,9 @@ static Bool dis_dfp_bcd(UInt theInstr) { IRTemp dbcd_l = newTemp( Ity_I32 ); IRTemp lmd = newTemp( Ity_I32 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frB, getDReg( frB_addr ) ); assign( frBI64, unop( Iop_ReinterpD64asI64, mkexpr( frB ) ) ); @@ -14742,7 +14959,7 @@ static Bool dis_dfp_bcd(UInt theInstr) { return True; } -static Bool dis_dfp_bcdq( UInt theInstr ) +static Bool dis_dfp_bcdq( UInt prefix, UInt theInstr ) { UInt opc2 = ifieldOPClo10( theInstr ); ULong sp = IFIELD(theInstr, 19, 2); @@ -14758,6 +14975,9 @@ static Bool dis_dfp_bcdq( UInt theInstr ) IRTemp result_hi = newTemp( Ity_I64 ); IRTemp result_lo = newTemp( Ity_I64 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( frB_hi, getDReg( frB_addr ) ); assign( frB_lo, getDReg( frB_addr + 1 ) ); assign( frBI64_hi, unop( Iop_ReinterpD64asI64, mkexpr( frB_hi ) ) ); @@ -15151,7 +15371,7 @@ static Bool dis_dfp_bcdq( UInt theInstr ) return True; } -static Bool dis_dfp_significant_digits( UInt theInstr ) +static Bool dis_dfp_significant_digits( UInt prefix, UInt theInstr ) { UInt opc1 = ifieldOPC( theInstr ); UInt opc2 = ifieldOPClo10(theInstr); @@ -15173,6 +15393,9 @@ static Bool dis_dfp_significant_digits( UInt theInstr ) UChar UIM = toUChar( IFIELD( theInstr, 16, 6 ) ); IRTemp BCD_valid = newTemp( Ity_I32 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc2 == 0x2A2) { // dtstsf DFP Test Significance // dtstsfq DFP Test Significance Quad /* Get the reference singificance stored in frA */ @@ -15403,7 +15626,7 @@ static Bool dis_dfp_significant_digits( UInt theInstr ) /* Altivec Cache Control Instructions (Data Streams) */ -static Bool dis_av_datastream ( UInt theInstr ) +static Bool dis_av_datastream ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -15416,6 +15639,9 @@ static Bool dis_av_datastream ( UInt theInstr ) UInt opc2 = ifieldOPClo10(theInstr); UChar b0 = ifieldBIT0(theInstr); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F || b23to24 != 0 || b0 != 0) { vex_printf("dis_av_datastream(ppc)(instr)\n"); return False; @@ -15454,7 +15680,7 @@ static Bool dis_av_datastream ( UInt theInstr ) /* AltiVec Processor Control Instructions */ -static Bool dis_av_procctl ( UInt theInstr ) +static Bool dis_av_procctl ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -15463,6 +15689,9 @@ static Bool dis_av_procctl ( UInt theInstr ) UChar vB_addr = ifieldRegB(theInstr); UInt opc2 = IFIELD( theInstr, 0, 11 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x4) { vex_printf("dis_av_procctl(ppc)(instr)\n"); return False; @@ -15499,7 +15728,8 @@ static Bool dis_av_procctl ( UInt theInstr ) /* Vector Extend Sign Instructions */ -static Bool dis_av_extend_sign_count_zero ( UInt theInstr, UInt allow_isa_3_0 ) +static Bool dis_av_extend_sign_count_zero ( UInt prefix, UInt theInstr, + UInt allow_isa_3_0 ) { /* VX-Form, sort of, the A register field is used to select the specific * sign extension instruction or count leading/trailing zero LSB @@ -15515,6 +15745,9 @@ static Bool dis_av_extend_sign_count_zero ( UInt theInstr, UInt allow_isa_3_0 ) IRTemp vB = newTemp( Ity_V128 ); IRTemp vT = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getVReg ( vB_addr ) ); if ( ( opc1 != 0x4 ) && ( opc2 != 0x602 ) ) { @@ -15841,7 +16074,7 @@ static Bool dis_av_extend_sign_count_zero ( UInt theInstr, UInt allow_isa_3_0 ) /* Vector Rotate Instructions */ -static Bool dis_av_rotate ( UInt theInstr ) +static Bool dis_av_rotate ( UInt prefix, UInt theInstr ) { /* VX-Form */ @@ -15872,6 +16105,9 @@ static Bool dis_av_rotate ( UInt theInstr ) UInt word_size; unsigned long long word_mask; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if ( opc1 != 0x4 ) { vex_printf("dis_av_rotate(ppc)(instr)\n"); return False; @@ -16106,7 +16342,7 @@ static Bool dis_av_rotate ( UInt theInstr ) /* AltiVec Vector Extract Element Instructions */ -static Bool dis_av_extract_element ( UInt theInstr ) +static Bool dis_av_extract_element ( UInt prefix, UInt theInstr ) { /* VX-Form, * sorta destination and first source are GPR not vector registers @@ -16122,6 +16358,9 @@ static Bool dis_av_extract_element ( UInt theInstr ) IRTemp rA = newTemp( Ity_I64 ); IRTemp rT = newTemp( Ity_I64 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getVReg( vB_addr ) ); assign( rA, getIReg( rA_addr ) ); @@ -16192,7 +16431,7 @@ static Bool dis_av_extract_element ( UInt theInstr ) * VSX scalar and vector convert instructions */ static Bool -dis_vx_conv ( UInt theInstr, UInt opc2 ) +dis_vx_conv ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX2-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -16200,6 +16439,10 @@ dis_vx_conv ( UInt theInstr, UInt opc2 ) UChar XB = ifieldRegXB( theInstr ); IRTemp xB, xB2; IRTemp b3, b2, b1, b0; + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + xB = xB2 = IRTemp_INVALID; if (opc1 != 0x3C) { @@ -16854,7 +17097,7 @@ dis_vx_conv ( UInt theInstr, UInt opc2 ) * VSX vector Double Precision Floating Point Arithmetic Instructions */ static Bool -dis_vxv_dp_arith ( UInt theInstr, UInt opc2 ) +dis_vxv_dp_arith ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -16867,6 +17110,9 @@ dis_vxv_dp_arith ( UInt theInstr, UInt opc2 ) IRTemp frA2 = newTemp(Ity_F64); IRTemp frB2 = newTemp(Ity_F64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vxv_dp_arith(ppc)(instr)\n" ); return False; @@ -17097,7 +17343,7 @@ dis_vxv_dp_arith ( UInt theInstr, UInt opc2 ) * VSX vector Single Precision Floating Point Arithmetic Instructions */ static Bool -dis_vxv_sp_arith ( UInt theInstr, UInt opc2 ) +dis_vxv_sp_arith ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -17112,6 +17358,9 @@ dis_vxv_sp_arith ( UInt theInstr, UInt opc2 ) IRTemp res2 = newTemp(Ity_I32); IRTemp res3 = newTemp(Ity_I32); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + a3 = a2 = a1 = a0 = IRTemp_INVALID; b3 = b2 = b1 = b0 = IRTemp_INVALID; @@ -17423,12 +17672,16 @@ dis_vxv_sp_arith ( UInt theInstr, UInt opc2 ) * Vector Population Count/bit matrix transpose */ static Bool -dis_av_count_bitTranspose ( UInt theInstr, UInt opc2 ) +dis_av_count_bitTranspose ( UInt prefix, UInt theInstr, UInt opc2 ) { UChar vRB_addr = ifieldRegB(theInstr); UChar vRT_addr = ifieldRegDS(theInstr); UChar opc1 = ifieldOPC( theInstr ); IRTemp vB = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getVReg(vRB_addr)); if (opc1 != 0x4) { @@ -18007,13 +18260,16 @@ static IRExpr * _do_vsx_fp_roundToInt(IRTemp frB_I64, UInt opc2) * Miscellaneous VSX vector instructions */ static Bool -dis_vxv_misc ( UInt theInstr, UInt opc2 ) +dis_vxv_misc ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); UChar XT = ifieldRegXT( theInstr ); UChar XB = ifieldRegXB( theInstr ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vxv_misc(ppc)(instr)\n" ); return False; @@ -18504,7 +18760,7 @@ dis_vxv_misc ( UInt theInstr, UInt opc2 ) * VSX Scalar Floating Point Arithmetic Instructions */ static Bool -dis_vxs_arith ( UInt theInstr, UInt opc2 ) +dis_vxs_arith ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -18515,6 +18771,9 @@ dis_vxs_arith ( UInt theInstr, UInt opc2 ) IRTemp frA = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vxs_arith(ppc)(instr)\n" ); return False; @@ -18833,7 +19092,7 @@ dis_vxs_arith ( UInt theInstr, UInt opc2 ) * VSX Floating Point Compare Instructions */ static Bool -dis_vx_cmp( UInt theInstr, UInt opc2 ) +dis_vx_cmp( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form and XX2-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -18844,6 +19103,9 @@ dis_vx_cmp( UInt theInstr, UInt opc2 ) IRTemp frA = newTemp(Ity_F64); IRTemp frB = newTemp(Ity_F64); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vx_cmp(ppc)(instr)\n" ); return False; @@ -18958,7 +19220,7 @@ do_vvec_fp_cmp ( IRTemp vA, IRTemp vB, UChar XT, UChar flag_rC, * VSX Vector Compare Instructions */ static Bool -dis_vvec_cmp( UInt theInstr, UInt opc2 ) +dis_vvec_cmp( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -18969,6 +19231,9 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 ) IRTemp vA = newTemp( Ity_V128 ); IRTemp vB = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vvec_cmp(ppc)(instr)\n" ); return False; @@ -19054,7 +19319,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 ) * Miscellaneous VSX Scalar Instructions */ static Bool -dis_vxs_misc( UInt theInstr, const VexAbiInfo* vbi, UInt opc2, +dis_vxs_misc( UInt prefix, UInt theInstr, const VexAbiInfo* vbi, UInt opc2, int allow_isa_3_0 ) { #define VG_PPC_SIGN_MASK 0x7fffffffffffffffULL @@ -19066,6 +19331,9 @@ dis_vxs_misc( UInt theInstr, const VexAbiInfo* vbi, UInt opc2, IRTemp vA = newTemp( Ity_V128 ); IRTemp vB = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vxs_misc(ppc)(instr)\n" ); return False; @@ -20320,7 +20588,7 @@ dis_vxs_misc( UInt theInstr, const VexAbiInfo* vbi, UInt opc2, */ static Bool -dis_vx_misc ( UInt theInstr, UInt opc2 ) +dis_vx_misc ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar XT = ifieldRegXT ( theInstr ); @@ -20340,6 +20608,9 @@ dis_vx_misc ( UInt theInstr, UInt opc2 ) IRTemp nan_cmp_value = newTemp(Ity_I64); UInt trap_enabled = 0; /* 0 - trap enabled is False */ + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVSReg( XA ) ); assign( vB, getVSReg( XB ) ); assign( xT, getVSReg( XT ) ); @@ -20554,7 +20825,7 @@ dis_vx_misc ( UInt theInstr, UInt opc2 ) * VSX Logical Instructions */ static Bool -dis_vx_logic ( UInt theInstr, UInt opc2 ) +dis_vx_logic ( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -20564,6 +20835,9 @@ dis_vx_logic ( UInt theInstr, UInt opc2 ) IRTemp vA = newTemp( Ity_V128 ); IRTemp vB = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vx_logic(ppc)(instr)\n" ); return False; @@ -20625,7 +20899,7 @@ dis_vx_logic ( UInt theInstr, UInt opc2 ) * NOTE: VSX supports word-aligned storage access. */ static Bool -dis_vx_load ( UInt theInstr ) +dis_vx_load ( UInt prefix, UInt theInstr ) { /* XX1-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -20637,6 +20911,9 @@ dis_vx_load ( UInt theInstr ) IRType ty = mode64 ? Ity_I64 : Ity_I32; IRTemp EA = newTemp( ty ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F) { vex_printf( "dis_vx_load(ppc)(instr)\n" ); return False; @@ -21261,7 +21538,7 @@ dis_vx_load ( UInt theInstr ) * VSX Move Instructions */ static Bool -dis_vx_move ( UInt theInstr ) +dis_vx_move ( UInt prefix, UInt theInstr ) { /* XX1-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -21272,6 +21549,9 @@ dis_vx_move ( UInt theInstr ) UInt opc2 = ifieldOPClo10( theInstr ); IRType ty = Ity_I64; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if ( opc1 != 0x1F ) { vex_printf( "dis_vx_move(ppc)(instr)\n" ); return False; @@ -21334,7 +21614,7 @@ dis_vx_move ( UInt theInstr ) * NOTE: VSX supports word-aligned storage access. */ static Bool -dis_vx_store ( UInt theInstr ) +dis_vx_store ( UInt prefix, UInt theInstr ) { /* XX1-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -21347,6 +21627,9 @@ dis_vx_store ( UInt theInstr ) IRType ty = mode64 ? Ity_I64 : Ity_I32; IRTemp EA = newTemp( ty ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F) { vex_printf( "dis_vx_store(ppc)(instr)\n" ); return False; @@ -22177,7 +22460,8 @@ dis_vx_store ( UInt theInstr ) } static Bool -dis_vx_Scalar_Round_to_quad_integer( UInt theInstr, const VexAbiInfo* vbi ) +dis_vx_Scalar_Round_to_quad_integer( UInt prefix, UInt theInstr, + const VexAbiInfo* vbi ) { /* The ISA 3.0 instructions supported in this function require * the underlying hardware platform that supports the ISA3.0 @@ -22192,6 +22476,9 @@ dis_vx_Scalar_Round_to_quad_integer( UInt theInstr, const VexAbiInfo* vbi ) IRTemp vT = newTemp( Ity_F128 ); UChar EX = IFIELD( theInstr, 0, 1 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getF128Reg( vB_addr ) ); if (opc1 != 0x3F) { vex_printf( "dis_vx_Scalar_Round_to_quad_integer(ppc)(instr)\n" ); @@ -22244,7 +22531,7 @@ dis_vx_Scalar_Round_to_quad_integer( UInt theInstr, const VexAbiInfo* vbi ) } static Bool -dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr, +dis_vx_Floating_Point_Arithmetic_quad_precision( UInt prefix, UInt theInstr, const VexAbiInfo* vbi ) { /* The ISA 3.0 instructions supported in this function require @@ -22263,6 +22550,9 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr, IRExpr* rm = get_IR_roundingmode(); UChar R0 = IFIELD( theInstr, 0, 1 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getF128Reg( vB_addr ) ); if ( opc1 != 0x3F ) { @@ -22596,7 +22886,7 @@ dis_vx_Floating_Point_Arithmetic_quad_precision( UInt theInstr, /* VSX Scalar Quad-Precision instructions */ static Bool -dis_vx_scalar_quad_precision ( UInt theInstr ) +dis_vx_scalar_quad_precision ( UInt prefix, UInt theInstr ) { /* This function emulates the 128-bit floating point instructions * using existing 128-bit vector instructions (Iops). The 128-bit @@ -22613,6 +22903,9 @@ dis_vx_scalar_quad_precision ( UInt theInstr ) IRTemp vB = newTemp( Ity_V128 ); IRTemp vT = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vB, getVSReg( vB_addr ) ); if (opc1 != 0x3F) { @@ -23006,7 +23299,7 @@ dis_vx_scalar_quad_precision ( UInt theInstr ) * VSX permute and other miscealleous instructions */ static Bool -dis_vx_permute_misc( UInt theInstr, UInt opc2 ) +dis_vx_permute_misc( UInt prefix, UInt theInstr, UInt opc2 ) { /* XX3-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -23017,6 +23310,9 @@ dis_vx_permute_misc( UInt theInstr, UInt opc2 ) IRTemp vA = newTemp( Ity_V128 ); IRTemp vB = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x3C) { vex_printf( "dis_vx_permute_misc(ppc)(instr)\n" ); return False; @@ -23186,7 +23482,7 @@ dis_vx_permute_misc( UInt theInstr, UInt opc2 ) /* AltiVec Load Instructions */ -static Bool dis_av_load ( const VexAbiInfo* vbi, UInt theInstr ) +static Bool dis_av_load ( const VexAbiInfo* vbi, UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -23200,6 +23496,9 @@ static Bool dis_av_load ( const VexAbiInfo* vbi, UInt theInstr ) IRTemp EA = newTemp(ty); IRTemp EA_align16 = newTemp(ty); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F || b0 != 0) { vex_printf("dis_av_load(ppc)(instr)\n"); return False; @@ -23349,7 +23648,7 @@ static Bool dis_av_load ( const VexAbiInfo* vbi, UInt theInstr ) /* AltiVec Store Instructions */ -static Bool dis_av_store ( UInt theInstr ) +static Bool dis_av_store ( UInt prefix, UInt theInstr ) { /* X-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -23366,6 +23665,9 @@ static Bool dis_av_store ( UInt theInstr ) IRTemp eb = newTemp(Ity_I8); IRTemp idx = newTemp(Ity_I8); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x1F || b0 != 0) { vex_printf("dis_av_store(ppc)(instr)\n"); return False; @@ -23447,7 +23749,7 @@ static Bool dis_av_store ( UInt theInstr ) /* AltiVec Arithmetic Instructions */ -static Bool dis_av_arith ( UInt theInstr ) +static Bool dis_av_arith ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -23467,6 +23769,9 @@ static Bool dis_av_arith ( UInt theInstr ) IRTemp a7, a6, a5, a4, a3, a2, a1, a0; IRTemp b3, b2, b1, b0; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + aEvn = aOdd = IRTemp_INVALID; a15 = a14 = a13 = a12 = a11 = a10 = a9 = a8 = IRTemp_INVALID; a7 = a6 = a5 = a4 = a3 = a2 = a1 = a0 = IRTemp_INVALID; @@ -23954,7 +24259,7 @@ static Bool dis_av_arith ( UInt theInstr ) /* AltiVec Logic Instructions */ -static Bool dis_av_logic ( UInt theInstr ) +static Bool dis_av_logic ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -23968,6 +24273,9 @@ static Bool dis_av_logic ( UInt theInstr ) assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + if (opc1 != 0x4) { vex_printf("dis_av_logic(ppc)(opc1 != 0x4)\n"); return False; @@ -24032,7 +24340,7 @@ static Bool dis_av_logic ( UInt theInstr ) /* AltiVec Compare Instructions */ -static Bool dis_av_cmp ( UInt theInstr ) +static Bool dis_av_cmp ( UInt prefix, UInt theInstr ) { /* VXR-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -24045,6 +24353,10 @@ static Bool dis_av_cmp ( UInt theInstr ) IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); IRTemp vD = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); @@ -24234,7 +24546,7 @@ static Bool dis_av_cmp ( UInt theInstr ) /* AltiVec Multiply-Sum Instructions */ -static Bool dis_av_multarith ( UInt theInstr ) +static Bool dis_av_multarith ( UInt prefix, UInt theInstr ) { /* VA-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -24265,6 +24577,9 @@ static Bool dis_av_multarith ( UInt theInstr ) IRTemp ab7, ab6, ab5, ab4, ab3, ab2, ab1, ab0; IRTemp c3, c2, c1, c0; + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + ab7 = ab6 = ab5 = ab4 = ab3 = ab2 = ab1 = ab0 = IRTemp_INVALID; c3 = c2 = c1 = c0 = IRTemp_INVALID; @@ -24627,7 +24942,7 @@ static Bool dis_av_multarith ( UInt theInstr ) /* AltiVec Polynomial Multiply-Sum Instructions */ -static Bool dis_av_polymultarith ( UInt theInstr ) +static Bool dis_av_polymultarith ( UInt prefix, UInt theInstr ) { /* VA-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -24640,6 +24955,9 @@ static Bool dis_av_polymultarith ( UInt theInstr ) IRTemp vB = newTemp(Ity_V128); IRTemp vC = newTemp(Ity_V128); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); assign( vC, getVReg(vC_addr)); @@ -24681,7 +24999,7 @@ static Bool dis_av_polymultarith ( UInt theInstr ) /* AltiVec Shift/Rotate Instructions */ -static Bool dis_av_shift ( UInt theInstr ) +static Bool dis_av_shift ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -24692,6 +25010,10 @@ static Bool dis_av_shift ( UInt theInstr ) IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); @@ -24839,7 +25161,7 @@ static Bool dis_av_shift ( UInt theInstr ) /* AltiVec Permute Instructions */ -static Bool dis_av_permute ( UInt theInstr ) +static Bool dis_av_permute ( UInt prefix, UInt theInstr ) { /* VA-Form, VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -24857,6 +25179,10 @@ static Bool dis_av_permute ( UInt theInstr ) IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); IRTemp vC = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); assign( vC, getVReg(vC_addr)); @@ -25337,7 +25663,7 @@ static Bool dis_av_permute ( UInt theInstr ) /* Vector Integer Absolute Difference */ -static Bool dis_abs_diff ( UInt theInstr ) +static Bool dis_abs_diff ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC( theInstr ); @@ -25354,6 +25680,9 @@ static Bool dis_abs_diff ( UInt theInstr ) IRTemp vBminusA = newTemp( Ity_V128 ); IRTemp vMask = newTemp( Ity_V128 ); + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg( vA_addr ) ); assign( vB, getVReg( vB_addr ) ); @@ -25450,7 +25779,7 @@ static Bool dis_abs_diff ( UInt theInstr ) /* AltiVec 128 bit integer multiply by 10 Instructions */ -static Bool dis_av_mult10 ( UInt theInstr ) +static Bool dis_av_mult10 ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -25460,6 +25789,10 @@ static Bool dis_av_mult10 ( UInt theInstr ) UInt opc2 = IFIELD( theInstr, 0, 11 ); IRTemp vA = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); if (opc1 != 0x4) { @@ -25507,7 +25840,7 @@ static Bool dis_av_mult10 ( UInt theInstr ) /* AltiVec Pack/Unpack Instructions */ -static Bool dis_av_pack ( UInt theInstr ) +static Bool dis_av_pack ( UInt prefix, UInt theInstr ) { /* VX-Form */ UChar opc1 = ifieldOPC(theInstr); @@ -25520,6 +25853,10 @@ static Bool dis_av_pack ( UInt theInstr ) IRTemp zeros = IRTemp_INVALID; IRTemp vA = newTemp(Ity_V128); IRTemp vB = newTemp(Ity_V128); + + /* There is no prefixed version of these instructions. */ + PREFIX_CHECK + assign( vA, getVReg(vA_addr)); assign( vB, getVReg(vB_addr)); @@ -25827,7 +26164,7 @@ static Bool dis_av_pack ( UInt theInstr ) /* AltiVec Cipher Instructions */ -static Bool dis_av_cipher ( UInt theInstr ) +static Bool dis_... [truncated message content] |