[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