--- i386-tdep.c | 1217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1201 insertions(+), 16 deletions(-) --- a/i386-tdep.c +++ b/i386-tdep.c @@ -2848,6 +2848,7 @@ enum OT_WORD, OT_LONG, OT_QUAD, + OT_DQUAD, }; /* i386 arith/logic operations */ @@ -3217,6 +3218,7 @@ i386_process_record (struct gdbarch *gdb int rex = 0; uint8_t rex_w = -1; uint8_t rex_r = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); memset (&ir, 0, sizeof (struct i386_record_s)); ir.regcache = regcache; @@ -3226,7 +3228,7 @@ i386_process_record (struct gdbarch *gdb ir.dflag = 1; ir.override = -1; ir.popl_esp_hack = 0; - ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; + ir.regmap = tdep->record_regmap; ir.gdbarch = gdbarch; if (record_debug > 1) @@ -3344,7 +3346,7 @@ reswitch: return -1; } ir.addr++; - opcode = (uint16_t) tmpu8 | 0x0f00; + opcode = (uint32_t) tmpu8 | 0x0f00; goto reswitch; break; @@ -4868,7 +4870,7 @@ reswitch: } ir.addr++; if (tmpu8 != 0x80 - || gdbarch_tdep (gdbarch)->i386_intx80_record == NULL) + || tdep->i386_intx80_record == NULL) { printf_unfiltered (_("Process record doesn't support " "instruction int 0x%02x.\n"), @@ -4876,7 +4878,7 @@ reswitch: ir.addr -= 2; goto no_support; } - ret = gdbarch_tdep (gdbarch)->i386_intx80_record (ir.regcache); + ret = tdep->i386_intx80_record (ir.regcache); if (ret) return ret; } @@ -4973,14 +4975,14 @@ reswitch: ir.addr -= 2; goto no_support; } - if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL) + if (tdep->i386_sysenter_record == NULL) { printf_unfiltered (_("Process record doesn't support " "instruction sysenter.\n")); ir.addr -= 2; goto no_support; } - ret = gdbarch_tdep (gdbarch)->i386_sysenter_record (ir.regcache); + ret = tdep->i386_sysenter_record (ir.regcache); if (ret) return ret; } @@ -4998,14 +5000,14 @@ reswitch: case 0x0f05: { int ret; - if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + if (tdep->i386_syscall_record == NULL) { printf_unfiltered (_("Process record doesn't support " "instruction syscall.\n")); ir.addr -= 2; goto no_support; } - ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + ret = tdep->i386_syscall_record (ir.regcache); if (ret) return ret; } @@ -5349,14 +5351,1196 @@ reswitch: I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; - /* MMX/SSE/SSE2/PNI support */ - /* XXX */ + /* MMX 3DNow! SSE SSE2 SSE3 SSSE3 SSE4 */ + /* 3DNow! prefetch */ + case 0x0f0d: + break; + + /* 3DNow! femms */ + case 0x0f0e: + /* emms */ + case 0x0f77: + if (i386_fpc_regnum_p (gdbarch, I387_FTAG_REGNUM(tdep))) + goto no_support; + record_arch_list_add_reg (ir.regcache, I387_FTAG_REGNUM(tdep)); + break; + + /* 3DNow! data */ + case 0x0f0f: + if (i386_record_modrm (&ir)) + return -1; + if (target_read_memory (ir.addr, &tmpu8, 1)) + { + if (record_debug) + printf_unfiltered (_("Process record: error reading memory at " + "addr %s len = 1.\n"), + paddress (gdbarch, ir.addr)); + return -1; + } + ir.addr++; + switch (tmpu8) + { + /* 3DNow! pi2fw */ + case 0x0c: + /* 3DNow! pi2fd */ + case 0x0d: + /* 3DNow! pf2iw */ + case 0x1c: + /* 3DNow! pf2id */ + case 0x1d: + /* 3DNow! pfnacc */ + case 0x8a: + /* 3DNow! pfpnacc */ + case 0x8e: + /* 3DNow! pfcmpge */ + case 0x90: + /* 3DNow! pfmin */ + case 0x94: + /* 3DNow! pfrcp */ + case 0x96: + /* 3DNow! pfrsqrt */ + case 0x97: + /* 3DNow! pfsub */ + case 0x9a: + /* 3DNow! pfadd */ + case 0x9e: + /* 3DNow! pfcmpgt */ + case 0xa0: + /* 3DNow! pfmax */ + case 0xa4: + /* 3DNow! pfrcpit1 */ + case 0xa6: + /* 3DNow! pfrsqit1 */ + case 0xa7: + /* 3DNow! pfsubr */ + case 0xaa: + /* 3DNow! pfacc */ + case 0xae: + /* 3DNow! pfcmpeq */ + case 0xb0: + /* 3DNow! pfmul */ + case 0xb4: + /* 3DNow! pfrcpit2 */ + case 0xb6: + /* 3DNow! pmulhrw */ + case 0xb7: + /* 3DNow! pswapd */ + case 0xbb: + /* 3DNow! pavgusb */ + case 0xbf: + if (!i386_mmx_regnum_p (gdbarch, I387_MM0_REGNUM (tdep) + ir.reg)) + goto no_support_3dnow_data; + record_arch_list_add_reg (ir.regcache, ir.reg); + break; + + default: +no_support_3dnow_data: + opcode = (opcode << 8) | tmpu8; + goto no_support; + break; + } + break; + + /* rsm */ + case 0x0faa: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM); + break; + + case 0x0fae: + if (i386_record_modrm (&ir)) + return -1; + switch(ir.reg) + { + /* fxsave */ + case 0: + { + uint64_t tmpu64; + + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + if (i386_record_lea_modrm_addr (&ir, &tmpu64)) + return -1; + if (record_arch_list_add_mem (tmpu64, 512)) + return -1; + } + break; + + /* fxrstor */ + case 1: + { + int i; + + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + + for (i = I387_MM0_REGNUM (tdep); + i386_mmx_regnum_p (gdbarch, i); i++) + record_arch_list_add_reg (ir.regcache, i); + + for (i = I387_XMM0_REGNUM (tdep); + i386_sse_regnum_p (gdbarch, i); i++) + record_arch_list_add_reg (ir.regcache, i); + + if (i386_mxcsr_regnum_p (gdbarch, I387_MXCSR_REGNUM(tdep))) + record_arch_list_add_reg (ir.regcache, I387_MXCSR_REGNUM(tdep)); + + for (i = I387_ST0_REGNUM (tdep); + i386_fp_regnum_p (gdbarch, i); i++) + record_arch_list_add_reg (ir.regcache, i); + + for (i = I387_FCTRL_REGNUM (tdep); + i386_fpc_regnum_p (gdbarch, i); i++) + record_arch_list_add_reg (ir.regcache, i); + } + break; + + /* ldmxcsr */ + case 2: + if (!i386_mxcsr_regnum_p (gdbarch, I387_MXCSR_REGNUM(tdep))) + goto no_support; + record_arch_list_add_reg (ir.regcache, I387_MXCSR_REGNUM(tdep)); + break; + + /* stmxcsr */ + case 3: + ir.ot = OT_LONG; + if (i386_record_lea_modrm (&ir)) + return -1; + break; + + /* lfence */ + case 5: + /* mfence */ + case 6: + /* sfence clflush */ + case 7: + break; + + default: + opcode = (opcode << 8) | ir.modrm; + goto no_support; + break; + } + break; + + /* movnti */ + case 0x0fc3: + ir.ot = (ir.dflag == 2) ? OT_QUAD : OT_LONG; + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + goto no_support; + ir.reg |= rex_r; + if (i386_record_lea_modrm (&ir)) + return -1; + break; + + /* Add prefix to opcode. */ + case 0x0f10: + case 0x0f11: + case 0x0f12: + case 0x0f13: + case 0x0f14: + case 0x0f16: + case 0x0f17: + case 0x0f28: + case 0x0f29: + case 0x0f2a: + case 0x0f2b: + case 0x0f2c: + case 0x0f2d: + case 0x0f2e: + case 0x0f2f: + case 0x0f38: + case 0x0f39: + case 0x0f3a: + case 0x0f50: + case 0x0f51: + case 0x0f52: + case 0x0f53: + case 0x0f54: + case 0x0f55: + case 0x0f56: + case 0x0f57: + case 0x0f58: + case 0x0f59: + case 0x0f5a: + case 0x0f5b: + case 0x0f5c: + case 0x0f5d: + case 0x0f5e: + case 0x0f5f: + case 0x0f60: + case 0x0f61: + case 0x0f62: + case 0x0f63: + case 0x0f64: + case 0x0f65: + case 0x0f66: + case 0x0f67: + case 0x0f68: + case 0x0f69: + case 0x0f6a: + case 0x0f6b: + case 0x0f6c: + case 0x0f6d: + case 0x0f6e: + case 0x0f6f: + case 0x0f70: + case 0x0f71: + case 0x0f72: + case 0x0f73: + case 0x0f74: + case 0x0f75: + case 0x0f76: + case 0x0f7c: + case 0x0f7d: + case 0x0f7e: + case 0x0f7f: + case 0x0fb8: + case 0x0fc2: + case 0x0fc4: + case 0x0fc5: + case 0x0fc6: + case 0x0fd0: + case 0x0fd1: + case 0x0fd2: + case 0x0fd3: + case 0x0fd4: + case 0x0fd5: + case 0x0fd6: + case 0x0fd7: + case 0x0fd8: + case 0x0fd9: + case 0x0fda: + case 0x0fdb: + case 0x0fdc: + case 0x0fdd: + case 0x0fde: + case 0x0fdf: + case 0x0fe0: + case 0x0fe1: + case 0x0fe2: + case 0x0fe3: + case 0x0fe4: + case 0x0fe5: + case 0x0fe6: + case 0x0fe7: + case 0x0fe8: + case 0x0fe9: + case 0x0fea: + case 0x0feb: + case 0x0fec: + case 0x0fed: + case 0x0fee: + case 0x0fef: + case 0x0ff0: + case 0x0ff1: + case 0x0ff2: + case 0x0ff3: + case 0x0ff4: + case 0x0ff5: + case 0x0ff6: + case 0x0ff7: + case 0x0ff8: + case 0x0ff9: + case 0x0ffa: + case 0x0ffb: + case 0x0ffc: + case 0x0ffd: + case 0x0ffe: + switch (prefixes) + { + case PREFIX_REPNZ: + opcode |= 0xf20000; + break; + case PREFIX_DATA: + opcode |= 0x660000; + break; + case PREFIX_REPZ: + opcode |= 0xf30000; + break; + } +reswitch_prefix_add: + switch (opcode) + { + case 0x0f38: + case 0x660f38: + case 0xf20f38: + case 0x0f3a: + case 0x660f3a: + if (target_read_memory (ir.addr, &tmpu8, 1)) + { + if (record_debug) + printf_unfiltered (_("Process record: error reading memory at " + "addr %s len = 1.\n"), + paddress (gdbarch, ir.addr)); + return -1; + } + ir.addr++; + opcode = (uint32_t) tmpu8 | opcode << 4; + goto reswitch_prefix_add; + break; + + /* movups */ + case 0x0f10: + /* movupd */ + case 0x660f10: + /* movss */ + case 0xf30f10: + /* movsd */ + case 0xf20f10: + /* movlps */ + case 0x0f12: + /* movlpd */ + case 0x660f12: + /* movsldup */ + case 0xf30f12: + /* movddup */ + case 0xf20f12: + /* unpcklps */ + case 0x0f14: + /* unpcklpd */ + case 0x660f14: + /* unpckhps */ + case 0x0f15: + /* unpckhpd */ + case 0x660f15: + /* movhps */ + case 0x0f16: + /* movhpd */ + case 0x660f16: + /* movshdup */ + case 0xf30f16: + /* movaps */ + case 0x0f28: + /* movapd */ + case 0x660f28: + /* cvtpi2ps */ + case 0x0f2a: + /* cvtpi2pd */ + case 0x660f2a: + /* cvtsi2ss */ + case 0xf30f2a: + /* cvtsi2sd */ + case 0xf20f2a: + /* cvttps2pi */ + case 0x0f2c: + /* cvttpd2pi */ + case 0x660f2c: + /* cvtps2pi */ + case 0x0f2d: + /* cvtpd2pi */ + case 0x660f2d: + /* pshufb */ + case 0x660f3800: + /* phaddw */ + case 0x660f3801: + /* phaddd */ + case 0x660f3802: + /* phaddsw */ + case 0x660f3803: + /* pmaddubsw */ + case 0x660f3804: + /* phsubw */ + case 0x660f3805: + /* phsubd */ + case 0x660f3806: + /* phaddsw */ + case 0x660f3807: + /* psignb */ + case 0x660f3808: + /* psignw */ + case 0x660f3809: + /* psignd */ + case 0x660f380a: + /* pmulhrsw */ + case 0x660f380b: + /* pblendvb */ + case 0x660f3810: + /* blendvps */ + case 0x660f3814: + /* blendvpd */ + case 0x660f3815: + /* pabsb */ + case 0x660f381c: + /* pabsw */ + case 0x660f381d: + /* pabsd */ + case 0x660f381e: + /* pmovsxbw */ + case 0x660f3820: + /* pmovsxbd */ + case 0x660f3821: + /* pmovsxbq */ + case 0x660f3822: + /* pmovsxwd */ + case 0x660f3823: + /* pmovsxwq */ + case 0x660f3824: + /* pmovsxdq */ + case 0x660f3825: + /* pmuldq */ + case 0x660f3828: + /* pcmpeqq */ + case 0x660f3829: + /* movntdqa */ + case 0x660f382a: + /* roundps */ + case 0x660f3a08: + /* roundpd */ + case 0x660f3a09: + /* roundss */ + case 0x660f3a0a: + /* roundsd */ + case 0x660f3a0b: + /* blendps */ + case 0x660f3a0c: + /* blendpd */ + case 0x660f3a0d: + /* pblendw */ + case 0x660f3a0e: + /* palignr */ + case 0x660f3a0f: + /* pinsrb */ + case 0x660f3a20: + /* insertps */ + case 0x660f3a21: + /* pinsrd pinsrq */ + case 0x660f3a22: + /* dpps */ + case 0x660f3a40: + /* dppd */ + case 0x660f3a41: + /* mpsadbw */ + case 0x660f3a42: + /* pcmpestrm */ + case 0x660f3a60: + /* pcmpestri */ + case 0x660f3a61: + /* pcmpistrm */ + case 0x660f3a62: + /* pcmpistri */ + case 0x660f3a63: + /* sqrtps */ + case 0x0f51: + /* sqrtpd */ + case 0x660f51: + /* sqrtsd */ + case 0xf20f51: + /* sqrtss */ + case 0xf30f51: + /* rsqrtps */ + case 0x0f52: + /* rsqrtss */ + case 0xf30f52: + /* rcpps */ + case 0x0f53: + /* rcpss */ + case 0xf30f53: + /* andps */ + case 0x0f54: + /* andpd */ + case 0x660f54: + /* andnps */ + case 0x0f55: + /* andnpd */ + case 0x660f55: + /* orps */ + case 0x0f56: + /* orpd */ + case 0x660f56: + /* xorps */ + case 0x0f57: + /* xorpd */ + case 0x660f57: + /* addps */ + case 0x0f58: + /* addpd */ + case 0x660f58: + /* addsd */ + case 0xf20f58: + /* addss */ + case 0xf30f58: + /* mulps */ + case 0x0f59: + /* mulpd */ + case 0x660f59: + /* mulsd */ + case 0xf20f59: + /* mulss */ + case 0xf30f59: + /* cvtps2pd */ + case 0x0f5a: + /* cvtpd2ps */ + case 0x660f5a: + /* cvtsd2ss */ + case 0xf20f5a: + /* cvtss2sd */ + case 0xf30f5a: + /* cvtdq2ps */ + case 0x0f5b: + /* cvtps2dq */ + case 0x660f5b: + /* cvttps2dq */ + case 0xf30f5b: + /* subps */ + case 0x0f5c: + /* subpd */ + case 0x660f5c: + /* subsd */ + case 0xf20f5c: + /* subss */ + case 0xf30f5c: + /* minps */ + case 0x0f5d: + /* minpd */ + case 0x660f5d: + /* minsd */ + case 0xf20f5d: + /* minss */ + case 0xf30f5d: + /* divps */ + case 0x0f5e: + /* divpd */ + case 0x660f5e: + /* divsd */ + case 0xf20f5e: + /* divss */ + case 0xf30f5e: + /* maxps */ + case 0x0f5f: + /* maxpd */ + case 0x660f5f: + /* maxsd */ + case 0xf20f5f: + /* maxss */ + case 0xf30f5f: + /* punpcklbw */ + case 0x660f60: + /* punpcklwd */ + case 0x660f61: + /* punpckldq */ + case 0x660f62: + /* packsswb */ + case 0x660f63: + /* pcmpgtb */ + case 0x660f64: + /* pcmpgtw */ + case 0x660f65: + /* pcmpgtl */ + case 0x660f66: + /* packuswb */ + case 0x660f67: + /* punpckhbw */ + case 0x660f68: + /* punpckhwd */ + case 0x660f69: + /* punpckhdq */ + case 0x660f6a: + /* packssdw */ + case 0x660f6b: + /* punpcklqdq */ + case 0x660f6c: + /* punpckhqdq */ + case 0x660f6d: + /* movd */ + case 0x660f6e: + /* movdqa */ + case 0x660f6f: + /* movdqu */ + case 0xf30f6f: + /* pshufd */ + case 0x660f70: + /* pshuflw */ + case 0xf20f70: + /* pshufhw */ + case 0xf30f70: + /* pcmpeqb */ + case 0x660f74: + /* pcmpeqw */ + case 0x660f75: + /* pcmpeql */ + case 0x660f76: + /* haddpd */ + case 0x660f7c: + /* haddps */ + case 0xf20f7c: + /* hsubpd */ + case 0x660f7d: + /* hsubps */ + case 0xf20f7d: + /* movq */ + case 0xf30f7e: + /* cmpps */ + case 0x0fc2: + /* cmppd */ + case 0x660fc2: + /* cmpsd */ + case 0xf20fc2: + /* cmpss */ + case 0xf30fc2: + /* pinsrw */ + case 0x660fc4: + /* shufps */ + case 0x0fc6: + /* shufpd */ + case 0x660fc6: + /* addsubpd */ + case 0x660fd0: + /* addsubps */ + case 0xf20fd0: + /* psrlw */ + case 0x660fd1: + /* psrld */ + case 0x660fd2: + /* psrlq */ + case 0x660fd3: + /* paddq */ + case 0x660fd4: + /* pmullw */ + case 0x660fd5: + /* movq2dq */ + case 0xf30fd6: + /* psubusb */ + case 0x660fd8: + /* psubusw */ + case 0x660fd9: + /* pminub */ + case 0x660fda: + /* pand */ + case 0x660fdb: + /* paddusb */ + case 0x660fdc: + /* paddusw */ + case 0x660fdd: + /* pmaxub */ + case 0x660fde: + /* pandn */ + case 0x660fdf: + /* pavgb */ + case 0x660fe0: + /* psraw */ + case 0x660fe1: + /* psrad */ + case 0x660fe2: + /* pavgw */ + case 0x660fe3: + /* pmulhuw */ + case 0x660fe4: + /* pmulhw */ + case 0x660fe5: + /* cvttpd2dq */ + case 0x660fe6: + /* cvtpd2dq */ + case 0xf20fe6: + /* cvtdq2pd */ + case 0xf30fe6: + /* psubsb */ + case 0x660fe8: + /* psubsw */ + case 0x660fe9: + /* pminsw */ + case 0x660fea: + /* por */ + case 0x660feb: + /* paddsb */ + case 0x660fec: + /* paddsw */ + case 0x660fed: + /* pmaxsw */ + case 0x660fee: + /* pxor */ + case 0x660fef: + /* lddqu */ + case 0x660ff0: + /* psllw */ + case 0x660ff1: + /* pslld */ + case 0x660ff2: + /* psllq */ + case 0x660ff3: + /* pmuludq */ + case 0x660ff4: + /* pmaddwd */ + case 0x660ff5: + /* psadbw */ + case 0x660ff6: + /* psubb */ + case 0x660ff8: + /* psubw */ + case 0x660ff9: + /* psubl */ + case 0x660ffa: + /* psubq */ + case 0x660ffb: + /* paddb */ + case 0x660ffc: + /* paddw */ + case 0x660ffd: + /* paddl */ + case 0x660ffe: + if (i386_record_modrm (&ir)) + return -1; + ir.reg |= rex_r; + if (!i386_sse_regnum_p (gdbarch, I387_XMM0_REGNUM (tdep) + ir.reg)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_XMM0_REGNUM (tdep) + ir.reg); + if ((opcode & 0xfffffffc) == 0x660f3a60) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + + /* movups */ + case 0x0f11: + /* movupd */ + case 0x660f11: + /* movss */ + case 0xf30f11: + /* movsd */ + case 0xf20f11: + /* movlps */ + case 0x0f13: + /* movlpd */ + case 0x660f13: + /* movhps */ + case 0x0f17: + /* movhpd */ + case 0x660f17: + /* movaps */ + case 0x0f29: + /* movapd */ + case 0x660f29: + /* pextrb */ + case 0x660f3a14: + /* pextrw */ + case 0x660f3a15: + /* pextrd pextrq */ + case 0x660f3a16: + /* extractps */ + case 0x660f3a17: + /* movdqa */ + case 0x660f7f: + /* movdqu */ + case 0xf30f7f: + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + { + if (opcode == 0x0f13 || opcode == 0x660f13 + || opcode == 0x0f17 || opcode == 0x660f17) + goto no_support; + ir.rm |= ir.rex_b; + if (!i386_sse_regnum_p (gdbarch, I387_XMM0_REGNUM (tdep) + ir.rm)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_XMM0_REGNUM (tdep) + ir.rm); + } + else + { + switch (opcode) + { + case 0x660f3a14: + ir.ot = OT_BYTE; + break; + case 0x660f3a15: + ir.ot = OT_WORD; + break; + case 0x660f3a16: + ir.ot = OT_LONG; + break; + case 0x660f3a17: + ir.ot = OT_QUAD; + break; + default: + ir.ot = OT_DQUAD; + break; + } + if (i386_record_lea_modrm (&ir)) + return -1; + } + break; + + /* movntps */ + case 0x0f2b: + /* movntpd */ + case 0x660f2b: + /* movntq */ + case 0x0fe7: + /* movntdq */ + case 0x660fe7: + if (ir.mod == 3) + goto no_support; + if (opcode == 0x0fe7) + ir.ot = OT_QUAD; + else + ir.ot = OT_DQUAD; + if (i386_record_lea_modrm (&ir)) + return -1; + break; + + /* cvttss2si */ + case 0xf30f2c: + /* cvttsd2si */ + case 0xf20f2c: + /* cvtss2si */ + case 0xf30f2d: + /* cvtsd2si */ + case 0xf20f2d: + /* crc32 */ + case 0xf20f38f0: + /* crc32 */ + case 0xf20f38f1: + /* movmskps */ + case 0x0f50: + /* movmskpd */ + case 0x660f50: + /* pextrw */ + case 0x0fc5: + /* pextrw */ + case 0x660fc5: + /* pmovmskb */ + case 0x0fd7: + /* pmovmskb */ + case 0x660fd7: + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r); + break; + + /* pshufb */ + case 0x0f3800: + /* phaddw */ + case 0x0f3801: + /* phaddd */ + case 0x0f3802: + /* phaddsw */ + case 0x0f3803: + /* pmaddubsw */ + case 0x0f3804: + /* phsubw */ + case 0x0f3805: + /* phsubd */ + case 0x0f3806: + /* phaddsw */ + case 0x0f3807: + /* psignb */ + case 0x0f3808: + /* psignw */ + case 0x0f3809: + /* psignd */ + case 0x0f380a: + /* pmulhrsw */ + case 0x0f380b: + /* pabsb */ + case 0x0f381c: + /* pabsw */ + case 0x0f381d: + /* pabsd */ + case 0x0f381e: + /* packusdw */ + case 0x0f382b: + /* pmovzxbw */ + case 0x0f3830: + /* pmovzxbd */ + case 0x0f3831: + /* pmovzxbq */ + case 0x0f3832: + /* pmovzxwd */ + case 0x0f3833: + /* pmovzxwq */ + case 0x0f3834: + /* pmovzxdq */ + case 0x0f3835: + /* pcmpgtq */ + case 0x0f3837: + /* pminsb */ + case 0x0f3838: + /* pminsd */ + case 0x0f3839: + /* pminuw */ + case 0x0f383a: + /* pminud */ + case 0x0f383b: + /* pmaxsb */ + case 0x0f383c: + /* pmaxsd */ + case 0x0f383d: + /* pmaxuw */ + case 0x0f383e: + /* pmaxud */ + case 0x0f383f: + /* pmulld */ + case 0x0f3840: + /* phminposuw */ + case 0x0f3841: + /* palignr */ + case 0x0f3a0f: + /* punpcklbw */ + case 0x0f60: + /* punpcklwd */ + case 0x0f61: + /* punpckldq */ + case 0x0f62: + /* packsswb */ + case 0x0f63: + /* pcmpgtb */ + case 0x0f64: + /* pcmpgtw */ + case 0x0f65: + /* pcmpgtl */ + case 0x0f66: + /* packuswb */ + case 0x0f67: + /* punpckhbw */ + case 0x0f68: + /* punpckhwd */ + case 0x0f69: + /* punpckhdq */ + case 0x0f6a: + /* packssdw */ + case 0x0f6b: + /* movd */ + case 0x0f6e: + /* movq */ + case 0x0f6f: + /* pshufw */ + case 0x0f70: + /* pcmpeqb */ + case 0x0f74: + /* pcmpeqw */ + case 0x0f75: + /* pcmpeql */ + case 0x0f76: + /* pinsrw */ + case 0x0fc4: + /* psrlw */ + case 0x0fd1: + /* psrld */ + case 0x0fd2: + /* psrlq */ + case 0x0fd3: + /* paddq */ + case 0x0fd4: + /* pmullw */ + case 0x0fd5: + /* movdq2q */ + case 0xf20fd6: + /* psubusb */ + case 0x0fd8: + /* psubusw */ + case 0x0fd9: + /* pminub */ + case 0x0fda: + /* pand */ + case 0x0fdb: + /* paddusb */ + case 0x0fdc: + /* paddusw */ + case 0x0fdd: + /* pmaxub */ + case 0x0fde: + /* pandn */ + case 0x0fdf: + /* pavgb */ + case 0x0fe0: + /* psraw */ + case 0x0fe1: + /* psrad */ + case 0x0fe2: + /* pavgw */ + case 0x0fe3: + /* pmulhuw */ + case 0x0fe4: + /* pmulhw */ + case 0x0fe5: + /* psubsb */ + case 0x0fe8: + /* psubsw */ + case 0x0fe9: + /* pminsw */ + case 0x0fea: + /* por */ + case 0x0feb: + /* paddsb */ + case 0x0fec: + /* paddsw */ + case 0x0fed: + /* pmaxsw */ + case 0x0fee: + /* pxor */ + case 0x0fef: + /* psllw */ + case 0x0ff1: + /* pslld */ + case 0x0ff2: + /* psllq */ + case 0x0ff3: + /* pmuludq */ + case 0x0ff4: + /* pmaddwd */ + case 0x0ff5: + /* psadbw */ + case 0x0ff6: + /* psubb */ + case 0x0ff8: + /* psubw */ + case 0x0ff9: + /* psubl */ + case 0x0ffa: + /* psubq */ + case 0x0ffb: + /* paddb */ + case 0x0ffc: + /* paddw */ + case 0x0ffd: + /* paddl */ + case 0x0ffe: + if (i386_record_modrm (&ir)) + return -1; + if (!i386_mmx_regnum_p (gdbarch, I387_MM0_REGNUM (tdep) + ir.reg)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_MM0_REGNUM (tdep) + ir.reg); + break; + + /* psllw */ + case 0x0f71: + /* pslld */ + case 0x0f72: + /* psllq */ + case 0x0f73: + if (i386_record_modrm (&ir)) + return -1; + if (!i386_mmx_regnum_p (gdbarch, I387_MM0_REGNUM (tdep) + ir.rm)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_MM0_REGNUM (tdep) + ir.rm); + break; + + /* psllw */ + case 0x660f71: + /* pslld */ + case 0x660f72: + /* psllq */ + case 0x660f73: + if (i386_record_modrm (&ir)) + return -1; + ir.rm |= ir.rex_b; + if (!i386_sse_regnum_p (gdbarch, I387_XMM0_REGNUM (tdep) + ir.rm)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_XMM0_REGNUM (tdep) + ir.rm); + break; + + /* movd */ + case 0x0f7e: + /* movd */ + case 0x660f7e: + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); + else + { + if (ir.dflag == 2) + ir.ot = OT_QUAD; + else + ir.ot = OT_LONG; + if (i386_record_lea_modrm (&ir)) + return -1; + } + break; + + /* movq */ + case 0x0f7f: + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + { + if (!i386_mmx_regnum_p (gdbarch, I387_MM0_REGNUM (tdep) + ir.rm)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_MM0_REGNUM (tdep) + ir.rm); + } + else + { + ir.ot = OT_QUAD; + if (i386_record_lea_modrm (&ir)) + return -1; + } + break; + + /* popcnt */ + case 0xf30fb8: + if (i386_record_modrm (&ir)) + return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + + /* movq */ + case 0x660fd6: + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + { + ir.rm |= ir.rex_b; + if (!i386_sse_regnum_p (gdbarch, I387_XMM0_REGNUM (tdep) + ir.rm)) + goto no_support; + record_arch_list_add_reg (ir.regcache, + I387_XMM0_REGNUM (tdep) + ir.rm); + } + else + { + ir.ot = OT_QUAD; + if (i386_record_lea_modrm (&ir)) + return -1; + } + break; + + /* ptest */ + case 0x660f3817: + /* ucomiss */ + case 0x0f2e: + /* ucomisd */ + case 0x660f2e: + /* comiss */ + case 0x0f2f: + /* comisd */ + case 0x660f2f: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + + /* maskmovq */ + case 0x0ff7: + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + if (record_arch_list_add_mem (tmpulongest, 64)) + return -1; + break; + + /* maskmovdqu */ + case 0x660ff7: + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + if (record_arch_list_add_mem (tmpulongest, 128)) + return -1; + break; + + default: + goto no_support; + break; + } + break; default: - if (opcode > 0xff) - ir.addr -= 2; - else - ir.addr -= 1; goto no_support; break; } @@ -5370,8 +6554,9 @@ reswitch: no_support: printf_unfiltered (_("Process record doesn't support instruction 0x%02x " - "at address %s.\n"), - (unsigned int) (opcode), paddress (gdbarch, ir.addr)); + "at address %s.\n"), + (unsigned int) (opcode), + paddress (gdbarch, ir.orig_addr)); return -1; }