[RFC] Prec x86 MMX 3DNow! SSE SSE2 SSE3 SSSE3 SSE4 support
Hui Zhu
teawater@gmail.com
Wed Dec 2 07:00:00 GMT 2009
Hi guys,
This patch is still not complete. So it just for some comments.
Please help me with it. :)
Thanks,
Hui
-------------- next part --------------
---
i386-tdep.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 212 insertions(+), 15 deletions(-)
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -3217,6 +3217,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 +3227,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)
@@ -4868,7 +4869,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 +4877,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 +4974,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 +4999,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 +5350,209 @@ 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;
+
+ /* popcnt */
+ case 0x0fb8:
+ /* Check if the first byte of this insn is 0xf3. */
+ if ((prefixes & (PREFIX_REPZ
+ | PREFIX_LOCK | PREFIX_REPNZ)) != PREFIX_REPZ)
+ goto no_support;
+ 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;
+
+ /* 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;
default:
- if (opcode > 0xff)
- ir.addr -= 2;
- else
- ir.addr -= 1;
goto no_support;
break;
}
@@ -5370,8 +5566,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;
}
More information about the Gdb-patches
mailing list