Index: valgrind-3.23.0/VEX/priv/guest_x86_toIR.c =================================================================== --- valgrind-3.23.0.orig/VEX/priv/guest_x86_toIR.c +++ valgrind-3.23.0/VEX/priv/guest_x86_toIR.c @@ -12941,6 +12941,62 @@ DisResult disInstr_X86_WRK ( /* --- start of the SSE4 decoder --- */ /* ---------------------------------------------------- */ + /* 66 0F 3A 22 /r ib = PINSRD xmm1, r/m32, imm8 + Extract Doubleword int from gen.reg/mem32 and insert into xmm1 */ + if ( sz == 2 + && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x22 ) { + + Int imm8_10; + IRTemp src_elems = newTemp(Ity_I32); + IRTemp src_vec = newTemp(Ity_V128); + IRTemp z32 = newTemp(Ity_I32); + + modrm = insn[3]; + + if ( epartIsReg( modrm ) ) { + imm8_10 = (Int)(insn[3+1] & 3); + assign( src_elems, getIReg( 4, eregOfRM(modrm) ) ); + delta += 3+1+1; + DIP( "pinsrd $%d, %s,%s\n", imm8_10, + nameIReg( 4, eregOfRM(modrm) ), + nameXMMReg( gregOfRM(modrm) ) ); + } else { + addr = disAMode( &alen, sorb, delta+3, dis_buf ); + imm8_10 = (Int)(insn[3+alen] & 3); + assign( src_elems, loadLE( Ity_I32, mkexpr(addr) ) ); + delta += 3+alen+1; + DIP( "pinsrd $%d, %s,%s\n", + imm8_10, dis_buf, nameXMMReg( gregOfRM(modrm) ) ); + } + + assign(z32, mkU32(0)); + + UShort mask = 0; + switch (imm8_10) { + case 3: mask = 0x0FFF; + assign(src_vec, mk128from32s(src_elems, z32, z32, z32)); + break; + case 2: mask = 0xF0FF; + assign(src_vec, mk128from32s(z32, src_elems, z32, z32)); + break; + case 1: mask = 0xFF0F; + assign(src_vec, mk128from32s(z32, z32, src_elems, z32)); + break; + case 0: mask = 0xFFF0; + assign(src_vec, mk128from32s(z32, z32, z32, src_elems)); + break; + default: vassert(0); + } + + putXMMReg( gregOfRM(modrm), + binop( Iop_OrV128, mkexpr(src_vec), + binop( Iop_AndV128, + getXMMReg( gregOfRM(modrm) ), + mkV128(mask) ) ) ); + + goto decode_success; + } + /* 66 0F 3A 0B /r ib = ROUNDSD imm8, xmm2/m64, xmm1 (Partial implementation only -- only deal with cases where the rounding mode is specified directly by the immediate byte.)