Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA/RFC Prec] Add Linux AMD64 process record support second version,   (instruction set support) 1/3
@ 2009-07-07  2:38 Hui Zhu
  2009-07-13  0:52 ` Michael Snyder
  0 siblings, 1 reply; 15+ messages in thread
From: Hui Zhu @ 2009-07-07  2:38 UTC (permalink / raw)
  To: gdb-patches ml, Michael Snyder

[-- Attachment #1: Type: text/plain, Size: 74491 bytes --]

Because AMD64 instruction set is the extend of I386 instruction set.
So I update the function i386_process_record to make it support AMD64
instruction set.  some of other software do something like it.
2009-07-07  Hui Zhu  <teawater@gmail.com>

	Add AMD64 process record instruction set support.

	* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
	because the AMD64's registers order in GDB is not same with
	I386 instructions.
	Add i386_syscall_record to be the syscall function handle
	interface.
	(record_i386_regnum): Number for record_regmap.
	* i386-tdep.c (OT_QUAD): For 64 bits.
	(i386_record_s): Add rex_x, rex_b, rip_offset and
	popl_esp_hack for AMD64 instruction set. And regmap for
	record_regmap.
	(i386_record_lea_modrm_addr): Support AMD64 instruction set
	64 bits lea.
	(i386_record_lea_modrm): Ditto.
	(i386_record_push): New function.  Record the execution log
	of push.
	(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
	register.
	(i386_process_record): Support AMD64 instruction set.
	amd64-tdep.c (amd64_record_regmap): For record_regmap.
	(amd64_init_abi): Set amd64_record_regmap to record_regmap.

---
 amd64-tdep.c |   12
 i386-tdep.c  | 1444 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 830 insertions(+), 661 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }

+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;

+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2764,6 +2764,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };

 /* i386 arith/logic operations */
@@ -2781,6 +2782,7 @@ enum

 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2789,6 +2791,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };

 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2797,7 +2804,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;

   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2820,12 +2827,13 @@ i386_record_modrm (struct i386_record_s
    Return -1 if something wrong. */

 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;

   *addr = 0;
   if (irp->aflag)
@@ -2849,9 +2857,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;

       switch (irp->mod)
 	{
@@ -2859,7 +2868,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2868,6 +2877,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr++;
-	  *addr = (int8_t) tmpu8;
+	  *addr = (int8_t)tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2895,21 +2907,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}

+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t)(tmpulongest + *addr);

-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t)(*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -2921,7 +2946,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *)&tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2930,7 +2955,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -2949,10 +2974,10 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr++;
-	  *addr = (int8_t) tmpu8;
+	  *addr = (int8_t)tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2961,63 +2986,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}

       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3034,10 +3071,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;

-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3056,10 +3093,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }

+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR)tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3068,14 +3131,21 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;

   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;

   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3106,22 +3176,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3129,16 +3199,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;

   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3228,30 +3333,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP1 */
@@ -3271,17 +3374,17 @@ reswitch:

 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* inv */
@@ -3302,10 +3405,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP3 */
@@ -3318,28 +3419,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;

+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3349,13 +3439,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3365,15 +3456,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3387,10 +3473,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3399,13 +3481,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3413,42 +3498,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3463,22 +3546,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;

       /* imul */
@@ -3488,12 +3567,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* xadd */
@@ -3505,28 +3587,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg */
@@ -3540,22 +3619,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg8b */
@@ -3568,14 +3644,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* push */
@@ -3589,6 +3662,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3597,16 +3676,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;

@@ -3619,113 +3718,103 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;

       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;

       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;

       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;

       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* mov */
@@ -3743,19 +3832,21 @@ reswitch:

       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3763,40 +3854,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;

-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;

       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3804,38 +3910,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* movzbS */
@@ -3848,8 +3924,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;

       /* lea */
@@ -3862,12 +3937,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* mov EAX */
@@ -3875,62 +3949,71 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;

       /* mov R, Ib */
@@ -3942,8 +4025,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+				     ((opcode & 0x7) | ir.rex_b) :
+				     ((opcode & 0x7) & 0x3));
       break;

       /* mov R, Iv */
@@ -3955,8 +4039,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* xchg R, EAX */
@@ -3967,10 +4050,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;

       /* xchg Ev, Gv */
@@ -3980,33 +4061,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4024,35 +4107,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* shifts */
@@ -4066,10 +4146,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4077,14 +4155,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0fa4:
@@ -4121,9 +4197,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;

-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4183,16 +4259,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4202,16 +4278,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4228,43 +4304,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4286,123 +4362,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;

-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* port I/O */
@@ -4410,8 +4451,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

     case 0xe6:
@@ -4425,48 +4466,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* jmp im */
@@ -4528,14 +4553,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+                                                  (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4562,34 +4586,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4600,66 +4623,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod ==3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t)tmpulongest >> 4)<< 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t)tmpulongest >> 5)<< 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t)tmpulongest >> 6)<< 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bcd */
@@ -4675,10 +4727,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* misc */
@@ -4770,16 +4825,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;

       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* loopnz */
@@ -4790,8 +4847,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* wrmsr */
@@ -4822,6 +4879,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4843,16 +4905,37 @@ reswitch:
       goto no_support;
       break;

+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+          "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;

       /* hlt */
@@ -4873,10 +4956,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4893,8 +4973,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4912,7 +4991,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;

 	    if (ir.mod == 3)
 	      {
@@ -4920,8 +4999,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -4933,13 +5011,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -4953,8 +5039,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -4966,7 +5051,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -4978,15 +5063,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;

-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -4994,9 +5087,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5008,7 +5098,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5017,9 +5107,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5032,21 +5145,21 @@ reswitch:

       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+                                           (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lar */
@@ -5055,13 +5168,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;

       /* nop (multi byte) */
@@ -5082,7 +5201,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5094,16 +5213,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5119,22 +5234,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;

       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* MMX/SSE/SSE2/PNI support */
@@ -5149,9 +5261,8 @@ reswitch:
       break;
     }

-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, Maybe still need to deal with need_dasm */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;

@@ -5164,6 +5275,15 @@ no_support:
   return -1;
 }

+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
 \f
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5224,6 +5344,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;

+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;

   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order in GDB is not
+     same with I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };

 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };

+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 70867 bytes --]

---
 amd64-tdep.c |   12 
 i386-tdep.c  | 1444 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 830 insertions(+), 661 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }
 
+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;
 
+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
 
   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2764,6 +2764,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };
 
 /* i386 arith/logic operations */
@@ -2781,6 +2782,7 @@ enum
 
 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2789,6 +2791,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };
 
 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2797,7 +2804,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
 
   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2820,12 +2827,13 @@ i386_record_modrm (struct i386_record_s 
    Return -1 if something wrong. */
 
 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;
 
   *addr = 0;
   if (irp->aflag)
@@ -2849,9 +2857,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;
 
       switch (irp->mod)
 	{
@@ -2859,7 +2868,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2868,6 +2877,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr++;
-	  *addr = (int8_t) tmpu8;
+	  *addr = (int8_t)tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2895,21 +2907,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}
 
+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t)(tmpulongest + *addr);
 
-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t)(*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -2921,7 +2946,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *)&tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2930,7 +2955,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -2949,10 +2974,10 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr++;
-	  *addr = (int8_t) tmpu8;
+	  *addr = (int8_t)tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2961,63 +2986,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}
 
       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t)(*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3034,10 +3071,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;
 
-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3056,10 +3093,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }
 
+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR)tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */
 
+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3068,14 +3131,21 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;
 
   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;
 
   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3106,22 +3176,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3129,16 +3199,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;
 
   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3228,30 +3333,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP1 */
@@ -3271,17 +3374,17 @@ reswitch:
 
 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* inv */
@@ -3302,10 +3405,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP3 */
@@ -3318,28 +3419,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;
 
+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3349,13 +3439,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3365,15 +3456,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3387,10 +3473,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3399,13 +3481,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3413,42 +3498,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3463,22 +3546,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;
 
       /* imul */
@@ -3488,12 +3567,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* xadd */
@@ -3505,28 +3587,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg */
@@ -3540,22 +3619,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg8b */
@@ -3568,14 +3644,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* push */
@@ -3589,6 +3662,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3597,16 +3676,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;
 
@@ -3619,113 +3718,103 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;
 
       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;
 
       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;
 
       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;
 
       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* mov */
@@ -3743,19 +3832,21 @@ reswitch:
 
       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3763,40 +3854,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;
 
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;
 
       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3804,38 +3910,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* movzbS */
@@ -3848,8 +3924,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;
 
       /* lea */
@@ -3862,12 +3937,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* mov EAX */
@@ -3875,62 +3949,71 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory
+		  (ir.addr, (gdb_byte *)&tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;
 
       /* mov R, Ib */
@@ -3942,8 +4025,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+				     ((opcode & 0x7) | ir.rex_b) :
+				     ((opcode & 0x7) & 0x3));
       break;
 
       /* mov R, Iv */
@@ -3955,8 +4039,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* xchg R, EAX */
@@ -3967,10 +4050,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;
 
       /* xchg Ev, Gv */
@@ -3980,33 +4061,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4024,35 +4107,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* shifts */
@@ -4066,10 +4146,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4077,14 +4155,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0fa4:
@@ -4121,9 +4197,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;
 
-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4183,16 +4259,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4202,16 +4278,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4228,43 +4304,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4286,123 +4362,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
 
-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* port I/O */
@@ -4410,8 +4451,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
     case 0xe6:
@@ -4425,48 +4466,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* jmp im */
@@ -4528,14 +4553,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+                                                  (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4562,34 +4586,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4600,66 +4623,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod ==3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t)tmpulongest >> 4)<< 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t)tmpulongest >> 5)<< 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t)tmpulongest >> 6)<< 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bcd */
@@ -4675,10 +4727,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* misc */
@@ -4770,16 +4825,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;
 
       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* loopnz */
@@ -4790,8 +4847,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* wrmsr */
@@ -4822,6 +4879,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4843,16 +4905,37 @@ reswitch:
       goto no_support;
       break;
 
+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+          "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;
 
       /* hlt */
@@ -4873,10 +4956,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4893,8 +4973,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4912,7 +4991,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;
 
 	    if (ir.mod == 3)
 	      {
@@ -4920,8 +4999,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -4933,13 +5011,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -4953,8 +5039,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -4966,7 +5051,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -4978,15 +5063,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;
 
-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -4994,9 +5087,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5008,7 +5098,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5017,9 +5107,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5032,21 +5145,21 @@ reswitch:
 
       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+                                           (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lar */
@@ -5055,13 +5168,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;
 
       /* nop (multi byte) */
@@ -5082,7 +5201,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5094,16 +5213,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5119,22 +5234,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;
 
       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* MMX/SSE/SSE2/PNI support */
@@ -5149,9 +5261,8 @@ reswitch:
       break;
     }
 
-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, Maybe still need to deal with need_dasm */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;
 
@@ -5164,6 +5275,15 @@ no_support:
   return -1;
 }
 
+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
 \f
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5224,6 +5344,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;
 
+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;
 
   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order in GDB is not
+     same with I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };
 
 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };
 
+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second  version,  (instruction set support) 1/3
  2009-07-07  2:38 [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 Hui Zhu
@ 2009-07-13  0:52 ` Michael Snyder
  2009-07-17  8:50   ` Hui Zhu
  0 siblings, 1 reply; 15+ messages in thread
From: Michael Snyder @ 2009-07-13  0:52 UTC (permalink / raw)
  To: Hui Zhu; +Cc: gdb-patches ml

Hui Zhu wrote:
> Because AMD64 instruction set is the extend of I386 instruction set.
> So I update the function i386_process_record to make it support AMD64
> instruction set.  some of other software do something like it.
> 2009-07-07  Hui Zhu  <teawater@gmail.com>
> 
>         Add AMD64 process record instruction set support.
> 
>         * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>         because the AMD64's registers order in GDB is not same with
>         I386 instructions.
>         Add i386_syscall_record to be the syscall function handle
>         interface.
>         (record_i386_regnum): Number for record_regmap.
>         * i386-tdep.c (OT_QUAD): For 64 bits.
>         (i386_record_s): Add rex_x, rex_b, rip_offset and
>         popl_esp_hack for AMD64 instruction set. And regmap for
>         record_regmap.
>         (i386_record_lea_modrm_addr): Support AMD64 instruction set
>         64 bits lea.
>         (i386_record_lea_modrm): Ditto.
>         (i386_record_push): New function.  Record the execution log
>         of push.
>         (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>         register.
>         (i386_process_record): Support AMD64 instruction set.
>         amd64-tdep.c (amd64_record_regmap): For record_regmap.
>         (amd64_init_abi): Set amd64_record_regmap to record_regmap.

OK, this is kind of preliminary -- mostly concerned with
whitespace / formatting.  I'll try to do more later.


> @@ -2859,7 +2868,7 @@ i386_record_lea_modrm_addr (struct i386_
>           if ((base & 7) == 5)
>             {
>               base = 0xff;
> -             if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
> +             if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))

Space after a cast, please.  There are many instances of this,
I won't try to note them all.

> @@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_
>               return -1;
>             }
>           irp->addr++;
> -         *addr = (int8_t) tmpu8;
> +         *addr = (int8_t)tmpu8;

Space after cast

> @@ -2949,10 +2974,10 @@ i386_record_lea_modrm_addr (struct i386_
>               return -1;
>             }
>           irp->addr++;
> -         *addr = (int8_t) tmpu8;
> +         *addr = (int8_t)tmpu8;
>           break;
>         case 2:
> -         if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
> +         if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2))

No space after '&' operator.  In general, we use a space
both before and after a binary operator (such as 'plus'),
but no space after a unary operator such as '&', '*' or '-'.

> +         if (ir.aflag == 2)
> +           {
> +              if (target_read_memory
> +                 (ir.addr, (gdb_byte *)&addr, 8))

Please try to avoid doing this (putting the left-paren of a
function call on the next line).  Occasionally when a line gets
really long I tend to overlook it, but in this case it would
be really easy to divide the line up like this:

                if (target_read_memory (ir.addr,
                                        (gdb_byte *) &addr, 8))

> +          if (ir.mod ==3)

Space after ==

> +          switch (ir.dflag)
> +            {
> +            case 0:
> +              tmpu64 += ((int16_t)tmpulongest >> 4)<< 4;

Space before <<, space after cast.

> +              break;
> +            case 1:
> +              tmpu64 += ((int32_t)tmpulongest >> 5)<< 5;

Ditto

> +              break;
> +            case 2:
> +              tmpu64 += ((int64_t)tmpulongest >> 6)<< 6;

Ditto

> +  /* The map for registers because the AMD64's registers order in GDB is not
> +     same with I386 instructions.  */

"same as".  And could you shorten the first line please?



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-13  0:52 ` Michael Snyder
@ 2009-07-17  8:50   ` Hui Zhu
  2009-07-18  1:20     ` Michael Snyder
  0 siblings, 1 reply; 15+ messages in thread
From: Hui Zhu @ 2009-07-17  8:50 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches ml

[-- Attachment #1: Type: text/plain, Size: 78309 bytes --]

On Mon, Jul 13, 2009 at 08:34, Michael Snyder<msnyder@vmware.com> wrote:
> Hui Zhu wrote:
>>
>> Because AMD64 instruction set is the extend of I386 instruction set.
>> So I update the function i386_process_record to make it support AMD64
>> instruction set.  some of other software do something like it.
>> 2009-07-07  Hui Zhu  <teawater@gmail.com>
>>
>>        Add AMD64 process record instruction set support.
>>
>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>        because the AMD64's registers order in GDB is not same with
>>        I386 instructions.
>>        Add i386_syscall_record to be the syscall function handle
>>        interface.
>>        (record_i386_regnum): Number for record_regmap.
>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>        record_regmap.
>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>        64 bits lea.
>>        (i386_record_lea_modrm): Ditto.
>>        (i386_record_push): New function.  Record the execution log
>>        of push.
>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>        register.
>>        (i386_process_record): Support AMD64 instruction set.
>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>>        (amd64_init_abi): Set amd64_record_regmap to record_regmap.
>
> OK, this is kind of preliminary -- mostly concerned with
> whitespace / formatting.  I'll try to do more later.
>
>
>> @@ -2859,7 +2868,7 @@ i386_record_lea_modrm_addr (struct i386_
>>          if ((base & 7) == 5)
>>            {
>>              base = 0xff;
>> -             if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
>> +             if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
>
> Space after a cast, please.  There are many instances of this,
> I won't try to note them all.
>
>> @@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_
>>              return -1;
>>            }
>>          irp->addr++;
>> -         *addr = (int8_t) tmpu8;
>> +         *addr = (int8_t)tmpu8;
>
> Space after cast
>
>> @@ -2949,10 +2974,10 @@ i386_record_lea_modrm_addr (struct i386_
>>              return -1;
>>            }
>>          irp->addr++;
>> -         *addr = (int8_t) tmpu8;
>> +         *addr = (int8_t)tmpu8;
>>          break;
>>        case 2:
>> -         if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
>> +         if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2))
>
> No space after '&' operator.  In general, we use a space
> both before and after a binary operator (such as 'plus'),
> but no space after a unary operator such as '&', '*' or '-'.
>
>> +         if (ir.aflag == 2)
>> +           {
>> +              if (target_read_memory
>> +                 (ir.addr, (gdb_byte *)&addr, 8))
>
> Please try to avoid doing this (putting the left-paren of a
> function call on the next line).  Occasionally when a line gets
> really long I tend to overlook it, but in this case it would
> be really easy to divide the line up like this:
>
>               if (target_read_memory (ir.addr,
>                                       (gdb_byte *) &addr, 8))
>
>> +          if (ir.mod ==3)
>
> Space after ==
>
>> +          switch (ir.dflag)
>> +            {
>> +            case 0:
>> +              tmpu64 += ((int16_t)tmpulongest >> 4)<< 4;
>
> Space before <<, space after cast.
>
>> +              break;
>> +            case 1:
>> +              tmpu64 += ((int32_t)tmpulongest >> 5)<< 5;
>
> Ditto
>
>> +              break;
>> +            case 2:
>> +              tmpu64 += ((int64_t)tmpulongest >> 6)<< 6;
>
> Ditto
>
>> +  /* The map for registers because the AMD64's registers order in GDB is
>> not
>> +     same with I386 instructions.  */
>
> "same as".  And could you shorten the first line please?
>
>
>

Thanks Michael,

I updated all the AMD64 patches.  Please help me review it.

Thanks,
Hui

2009-07-17  Hui Zhu  <teawater@gmail.com>

	Add AMD64 process record instruction set support.

	* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
	because the AMD64's registers order in GDB is not same with
	I386 instructions.
	Add i386_syscall_record to be the syscall function handle
	interface.
	(record_i386_regnum): Number for record_regmap.
	* i386-tdep.c (OT_QUAD): For 64 bits.
	(i386_record_s): Add rex_x, rex_b, rip_offset and
	popl_esp_hack for AMD64 instruction set. And regmap for
	record_regmap.
	(i386_record_lea_modrm_addr): Support AMD64 instruction set
	64 bits lea.
	(i386_record_lea_modrm): Ditto.
	(i386_record_push): New function.  Record the execution log
	of push.
	(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
	register.
	(i386_process_record): Support AMD64 instruction set.
	amd64-tdep.c (amd64_record_regmap): For record_regmap.
	(amd64_init_abi): Set amd64_record_regmap to record_regmap.

---
 amd64-tdep.c |   12
 i386-tdep.c  | 1437 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 825 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }

+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;

+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };

 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum

 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };

 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;

   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s
    Return -1 if something wrong. */

 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;

   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;

       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}

+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);

-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}

       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;

-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }

+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3214,21 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;

   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;

   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3259,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3282,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;

   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3416,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP1 */
@@ -3354,17 +3457,17 @@ reswitch:

 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* inv */
@@ -3385,10 +3488,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP3 */
@@ -3401,28 +3502,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;

+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3522,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3539,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3556,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3564,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3581,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3629,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;

       /* imul */
@@ -3571,12 +3650,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* xadd */
@@ -3588,28 +3670,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg */
@@ -3623,22 +3702,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg8b */
@@ -3651,14 +3727,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* push */
@@ -3672,6 +3745,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3759,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;

@@ -3702,113 +3801,103 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;

       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;

       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;

       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;

       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* mov */
@@ -3826,19 +3915,21 @@ reswitch:

       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3937,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;

-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;

       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3993,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* movzbS */
@@ -3931,8 +4007,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;

       /* lea */
@@ -3945,12 +4020,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* mov EAX */
@@ -3958,62 +4032,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;

       /* mov R, Ib */
@@ -4025,8 +4105,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+				     ((opcode & 0x7) | ir.rex_b) :
+				     ((opcode & 0x7) & 0x3));
       break;

       /* mov R, Iv */
@@ -4038,8 +4119,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* xchg R, EAX */
@@ -4050,10 +4130,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;

       /* xchg Ev, Gv */
@@ -4063,33 +4141,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4187,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* shifts */
@@ -4149,10 +4226,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4235,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0fa4:
@@ -4204,9 +4277,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;

-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4339,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4358,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4384,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4442,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;

-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* port I/O */
@@ -4493,8 +4531,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

     case 0xe6:
@@ -4508,48 +4546,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* jmp im */
@@ -4611,14 +4633,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+                                                  (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4666,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4703,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bcd */
@@ -4758,10 +4807,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* misc */
@@ -4853,16 +4905,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;

       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* loopnz */
@@ -4873,8 +4927,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* wrmsr */
@@ -4905,6 +4959,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4985,37 @@ reswitch:
       goto no_support;
       break;

+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;

       /* hlt */
@@ -4956,10 +5036,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5053,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5071,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;

 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5079,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5091,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5119,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5131,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5143,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;

-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5167,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5178,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5187,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5225,21 @@ reswitch:

       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+                                           (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lar */
@@ -5138,13 +5248,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;

       /* nop (multi byte) */
@@ -5165,7 +5281,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5293,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5314,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;

       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5341,8 @@ reswitch:
       break;
     }

-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, Maybe still need to deal with need_dasm */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;

@@ -5247,6 +5355,15 @@ no_support:
   return -1;
 }

+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+

 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5424,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;

+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;

   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };

 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };

+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 70749 bytes --]

---
 amd64-tdep.c |   12 
 i386-tdep.c  | 1437 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 825 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }
 
+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;
 
+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
 
   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };
 
 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum
 
 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };
 
 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
 
   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s 
    Return -1 if something wrong. */
 
 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;
 
   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;
 
       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}
 
+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);
 
-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}
 
       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;
 
-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }
 
+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */
 
+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3214,21 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;
 
   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;
 
   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3259,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3282,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;
 
   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3416,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP1 */
@@ -3354,17 +3457,17 @@ reswitch:
 
 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* inv */
@@ -3385,10 +3488,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP3 */
@@ -3401,28 +3502,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;
 
+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3522,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3539,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3556,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3564,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3581,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3629,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;
 
       /* imul */
@@ -3571,12 +3650,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* xadd */
@@ -3588,28 +3670,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg */
@@ -3623,22 +3702,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg8b */
@@ -3651,14 +3727,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* push */
@@ -3672,6 +3745,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3759,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;
 
@@ -3702,113 +3801,103 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;
 
       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;
 
       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;
 
       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;
 
       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* mov */
@@ -3826,19 +3915,21 @@ reswitch:
 
       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3937,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;
 
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;
 
       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3993,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* movzbS */
@@ -3931,8 +4007,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;
 
       /* lea */
@@ -3945,12 +4020,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* mov EAX */
@@ -3958,62 +4032,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;
 
       /* mov R, Ib */
@@ -4025,8 +4105,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+				     ((opcode & 0x7) | ir.rex_b) :
+				     ((opcode & 0x7) & 0x3));
       break;
 
       /* mov R, Iv */
@@ -4038,8 +4119,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* xchg R, EAX */
@@ -4050,10 +4130,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;
 
       /* xchg Ev, Gv */
@@ -4063,33 +4141,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4187,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* shifts */
@@ -4149,10 +4226,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4235,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0fa4:
@@ -4204,9 +4277,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;
 
-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4339,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4358,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4384,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4442,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
 
-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* port I/O */
@@ -4493,8 +4531,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
     case 0xe6:
@@ -4508,48 +4546,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* jmp im */
@@ -4611,14 +4633,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+                                                  (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4666,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4703,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bcd */
@@ -4758,10 +4807,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* misc */
@@ -4853,16 +4905,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;
 
       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* loopnz */
@@ -4873,8 +4927,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* wrmsr */
@@ -4905,6 +4959,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4985,37 @@ reswitch:
       goto no_support;
       break;
 
+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;
 
       /* hlt */
@@ -4956,10 +5036,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5053,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5071,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;
 
 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5079,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5091,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5119,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5131,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5143,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;
 
-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5167,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5178,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5187,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5225,21 @@ reswitch:
 
       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+                                           (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lar */
@@ -5138,13 +5248,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;
 
       /* nop (multi byte) */
@@ -5165,7 +5281,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5293,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5314,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;
 
       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5341,8 @@ reswitch:
       break;
     }
 
-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, Maybe still need to deal with need_dasm */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;
 
@@ -5247,6 +5355,15 @@ no_support:
   return -1;
 }
 
+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
 \f
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5424,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;
 
+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;
 
   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };
 
 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };
 
+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-17  8:50   ` Hui Zhu
@ 2009-07-18  1:20     ` Michael Snyder
  2009-07-19 17:21       ` Hui Zhu
  0 siblings, 1 reply; 15+ messages in thread
From: Michael Snyder @ 2009-07-18  1:20 UTC (permalink / raw)
  To: Hui Zhu; +Cc: gdb-patches ml, mark.kettenis


> Thanks Michael,
> 
> I updated all the AMD64 patches.  Please help me review it.
> 
> Thanks,
> Hui
> 
> 2009-07-17  Hui Zhu  <teawater@gmail.com>
> 
>         Add AMD64 process record instruction set support.
> 
>         * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>         because the AMD64's registers order in GDB is not same with
>         I386 instructions.
>         Add i386_syscall_record to be the syscall function handle
>         interface.
>         (record_i386_regnum): Number for record_regmap.
>         * i386-tdep.c (OT_QUAD): For 64 bits.
>         (i386_record_s): Add rex_x, rex_b, rip_offset and
>         popl_esp_hack for AMD64 instruction set. And regmap for
>         record_regmap.
>         (i386_record_lea_modrm_addr): Support AMD64 instruction set
>         64 bits lea.
>         (i386_record_lea_modrm): Ditto.
>         (i386_record_push): New function.  Record the execution log
>         of push.
>         (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>         register.
>         (i386_process_record): Support AMD64 instruction set.
>         amd64-tdep.c (amd64_record_regmap): For record_regmap.

Should be a "*" at the beginning of the line above.


> @@ -2864,6 +2865,7 @@ enum
> 
>  struct i386_record_s
>  {
> +  struct gdbarch *gdbarch;
>    struct regcache *regcache;
>    CORE_ADDR addr;
>    int aflag;
> @@ -2872,6 +2874,11 @@ struct i386_record_s
>    uint8_t modrm;
>    uint8_t mod, reg, rm;
>    int ot;
> +  uint8_t rex_x;
> +  uint8_t rex_b;
> +  int rip_offset;
> +  int popl_esp_hack;

popl_esp_hack is used but never initialized.
Do you still need it?  Is it for some future use?


> @@ -4611,14 +4633,13 @@ reswitch:
>      case 0x0f9d:
>      case 0x0f9e:
>      case 0x0f9f:
> +      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
>        ir.ot = OT_BYTE;
>        if (i386_record_modrm (&ir))
>         return -1;
>        if (ir.mod == 3)
> -       {
> -         if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
> -           return -1;
> -       }
> +        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
> +                                                  (ir.rm & 0x3));

Space before colon operator (':'), and then
the 2nd line isn't indented right.  I know it
looks prettier the way it is, but it should be
over to the left.   ;-)


> @@ -5115,21 +5225,21 @@ reswitch:
> 
>        /* arpl */
>      case 0x63:
> -      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
>        if (i386_record_modrm (&ir))
>         return -1;
> -      if (ir.mod != 3)
> -       {
> -         if (i386_record_lea_modrm (&ir))
> -           return -1;
> -       }
> +      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
> +        {
> +          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
> +                                           (ir.reg | rex_r) : ir.rm);

Space before question-mark, and then the indentation of the second line.


> @@ -5232,9 +5341,8 @@ reswitch:
>        break;
>      }
> 
> -/* In the future, Maybe still need to deal with need_dasm */
> -  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
> -    return -1;
> +  /* In the future, Maybe still need to deal with need_dasm */

"maybe" lower case.  Period and two spaces at end of sentence.


Everything else in this patch looks great!

Mark Kettenis should approve it, though.

Michael


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-18  1:20     ` Michael Snyder
@ 2009-07-19 17:21       ` Hui Zhu
  2009-07-19 21:22         ` Mark Kettenis
                           ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Hui Zhu @ 2009-07-19 17:21 UTC (permalink / raw)
  To: Michael Snyder, Mark Kettenis; +Cc: gdb-patches ml

[-- Attachment #1: Type: text/plain, Size: 78123 bytes --]

On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:
>
>> Thanks Michael,
>>
>> I updated all the AMD64 patches.  Please help me review it.
>>
>> Thanks,
>> Hui
>>
>> 2009-07-17  Hui Zhu  <teawater@gmail.com>
>>
>>        Add AMD64 process record instruction set support.
>>
>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>        because the AMD64's registers order in GDB is not same with
>>        I386 instructions.
>>        Add i386_syscall_record to be the syscall function handle
>>        interface.
>>        (record_i386_regnum): Number for record_regmap.
>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>        record_regmap.
>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>        64 bits lea.
>>        (i386_record_lea_modrm): Ditto.
>>        (i386_record_push): New function.  Record the execution log
>>        of push.
>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>        register.
>>        (i386_process_record): Support AMD64 instruction set.
>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>
> Should be a "*" at the beginning of the line above.



>
>
>> @@ -2864,6 +2865,7 @@ enum
>>
>>  struct i386_record_s
>>  {
>> +  struct gdbarch *gdbarch;
>>   struct regcache *regcache;
>>   CORE_ADDR addr;
>>   int aflag;
>> @@ -2872,6 +2874,11 @@ struct i386_record_s
>>   uint8_t modrm;
>>   uint8_t mod, reg, rm;
>>   int ot;
>> +  uint8_t rex_x;
>> +  uint8_t rex_b;
>> +  int rip_offset;
>> +  int popl_esp_hack;
>
> popl_esp_hack is used but never initialized.
> Do you still need it?  Is it for some future use?
>
>
>> @@ -4611,14 +4633,13 @@ reswitch:
>>     case 0x0f9d:
>>     case 0x0f9e:
>>     case 0x0f9f:
>> +      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
>>       ir.ot = OT_BYTE;
>>       if (i386_record_modrm (&ir))
>>        return -1;
>>       if (ir.mod == 3)
>> -       {
>> -         if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
>> -           return -1;
>> -       }
>> +        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
>> +                                                  (ir.rm & 0x3));
>
> Space before colon operator (':'), and then
> the 2nd line isn't indented right.  I know it
> looks prettier the way it is, but it should be
> over to the left.   ;-)
>
>
>> @@ -5115,21 +5225,21 @@ reswitch:
>>
>>       /* arpl */
>>     case 0x63:
>> -      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
>>       if (i386_record_modrm (&ir))
>>        return -1;
>> -      if (ir.mod != 3)
>> -       {
>> -         if (i386_record_lea_modrm (&ir))
>> -           return -1;
>> -       }
>> +      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
>> +        {
>> +          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
>> +                                           (ir.reg | rex_r) : ir.rm);
>
> Space before question-mark, and then the indentation of the second line.
>
>
>> @@ -5232,9 +5341,8 @@ reswitch:
>>       break;
>>     }
>>
>> -/* In the future, Maybe still need to deal with need_dasm */
>> -  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
>> -    return -1;
>> +  /* In the future, Maybe still need to deal with need_dasm */
>
> "maybe" lower case.  Period and two spaces at end of sentence.
>
>
> Everything else in this patch looks great!
>
> Mark Kettenis should approve it, though.
>


Thanks Michael.

I update the patches according to your mail except changelog.  Because
It sames that we just add * at the begin of the function name.

Please help me review it.

Thanks,
Hui

2009-07-20  Hui Zhu  <teawater@gmail.com>

	Add AMD64 process record instruction set support.

	* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
	because the AMD64's registers order in GDB is not same with
	I386 instructions.
	Add i386_syscall_record to be the syscall function handle
	interface.
	(record_i386_regnum): Number for record_regmap.
	* i386-tdep.c (OT_QUAD): For 64 bits.
	(i386_record_s): Add rex_x, rex_b, rip_offset and
	popl_esp_hack for AMD64 instruction set. And regmap for
	record_regmap.
	(i386_record_lea_modrm_addr): Support AMD64 instruction set
	64 bits lea.
	(i386_record_lea_modrm): Ditto.
	(i386_record_push): New function.  Record the execution log
	of push.
	(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
	register.
	(i386_process_record): Support AMD64 instruction set.
	amd64-tdep.c (amd64_record_regmap): For record_regmap.
	(amd64_init_abi): Set amd64_record_regmap to record_regmap.

---
 amd64-tdep.c |   12
 i386-tdep.c  | 1439 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 827 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }

+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;

+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };

 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum

 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };

 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;

   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s
    Return -1 if something wrong. */

 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;

   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;

       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}

+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);

-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}

       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;

-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }

+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3214,22 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;

   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.popl_esp_hack = 0;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;

   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3260,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3283,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;

   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3417,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP1 */
@@ -3354,17 +3458,17 @@ reswitch:

 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* inv */
@@ -3385,10 +3489,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP3 */
@@ -3401,28 +3503,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;

+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3523,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3540,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3557,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3565,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3582,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3630,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;

       /* imul */
@@ -3571,12 +3651,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* xadd */
@@ -3588,28 +3671,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg */
@@ -3623,22 +3703,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg8b */
@@ -3651,14 +3728,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* push */
@@ -3672,6 +3746,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3760,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;

@@ -3702,113 +3802,104 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;

       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
+          ir.popl_esp_hack = 1 << ir.ot;
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;

       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;

       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;

       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* mov */
@@ -3826,19 +3917,21 @@ reswitch:

       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3939,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;

-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;

       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3995,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* movzbS */
@@ -3931,8 +4009,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;

       /* lea */
@@ -3945,12 +4022,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* mov EAX */
@@ -3958,62 +4034,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;

       /* mov R, Ib */
@@ -4025,8 +4107,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM])
+                                        ? ((opcode & 0x7) | ir.rex_b)
+					: ((opcode & 0x7) & 0x3));
       break;

       /* mov R, Iv */
@@ -4038,8 +4121,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* xchg R, EAX */
@@ -4050,10 +4132,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;

       /* xchg Ev, Gv */
@@ -4063,33 +4143,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4189,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* shifts */
@@ -4149,10 +4228,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4237,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0fa4:
@@ -4204,9 +4279,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;

-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4341,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4360,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4386,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4444,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;

-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* port I/O */
@@ -4493,8 +4533,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

     case 0xe6:
@@ -4508,48 +4548,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* jmp im */
@@ -4611,14 +4635,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b)
+	                                        : (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4668,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4705,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bcd */
@@ -4758,10 +4809,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* misc */
@@ -4853,16 +4907,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;

       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* loopnz */
@@ -4873,8 +4929,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* wrmsr */
@@ -4905,6 +4961,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4987,37 @@ reswitch:
       goto no_support;
       break;

+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;

       /* hlt */
@@ -4956,10 +5038,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5055,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5073,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;

 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5081,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5093,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5121,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5133,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5145,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;

-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5169,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5180,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5189,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5227,21 @@ reswitch:

       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]
+	                                   ? (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lar */
@@ -5138,13 +5250,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;

       /* nop (multi byte) */
@@ -5165,7 +5283,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5295,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5316,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;

       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5343,8 @@ reswitch:
       break;
     }

-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, maybe still need to deal with need_dasm.  */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;

@@ -5247,6 +5357,15 @@ no_support:
   return -1;
 }

+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+

 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5426,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;

+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;

   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };

 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };

+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 70831 bytes --]

---
 amd64-tdep.c |   12 
 i386-tdep.c  | 1439 +++++++++++++++++++++++++++++++----------------------------
 i386-tdep.h  |   35 +
 3 files changed, 827 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }
 
+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;
 
+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
 
   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };
 
 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum
 
 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };
 
 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
 
   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s 
    Return -1 if something wrong. */
 
 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;
 
   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;
 
       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}
 
+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);
 
-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}
 
       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;
 
-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }
 
+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */
 
+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    do { \
+         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+         return -1; \
+       } while (0)
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3214,22 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;
 
   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.popl_esp_hack = 0;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;
 
   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3260,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3283,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;
 
   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3417,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP1 */
@@ -3354,17 +3458,17 @@ reswitch:
 
 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* inv */
@@ -3385,10 +3489,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP3 */
@@ -3401,28 +3503,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;
 
+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3523,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3540,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3557,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3565,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3582,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3630,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;
 
       /* imul */
@@ -3571,12 +3651,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* xadd */
@@ -3588,28 +3671,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg */
@@ -3623,22 +3703,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg8b */
@@ -3651,14 +3728,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* push */
@@ -3672,6 +3746,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3760,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;
 
@@ -3702,113 +3802,104 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;
 
       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
+          ir.popl_esp_hack = 1 << ir.ot;
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;
 
       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;
 
       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;
 
       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* mov */
@@ -3826,19 +3917,21 @@ reswitch:
 
       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3939,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;
 
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;
 
       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3995,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* movzbS */
@@ -3931,8 +4009,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;
 
       /* lea */
@@ -3945,12 +4022,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* mov EAX */
@@ -3958,62 +4034,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;
 
       /* mov R, Ib */
@@ -4025,8 +4107,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM])
+                                        ? ((opcode & 0x7) | ir.rex_b)
+					: ((opcode & 0x7) & 0x3));
       break;
 
       /* mov R, Iv */
@@ -4038,8 +4121,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* xchg R, EAX */
@@ -4050,10 +4132,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;
 
       /* xchg Ev, Gv */
@@ -4063,33 +4143,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4189,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* shifts */
@@ -4149,10 +4228,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4237,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0fa4:
@@ -4204,9 +4279,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;
 
-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4341,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4360,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4386,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4444,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
 
-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* port I/O */
@@ -4493,8 +4533,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
     case 0xe6:
@@ -4508,48 +4548,32 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* jmp im */
@@ -4611,14 +4635,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b)
+	                                        : (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4668,33 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4705,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bcd */
@@ -4758,10 +4809,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* misc */
@@ -4853,16 +4907,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;
 
       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* loopnz */
@@ -4873,8 +4929,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* wrmsr */
@@ -4905,6 +4961,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4987,37 @@ reswitch:
       goto no_support;
       break;
 
+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;
 
       /* hlt */
@@ -4956,10 +5038,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5055,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5073,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;
 
 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5081,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5093,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5121,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5133,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5145,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;
 
-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5169,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5180,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5189,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5227,21 @@ reswitch:
 
       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]
+	                                   ? (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lar */
@@ -5138,13 +5250,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;
 
       /* nop (multi byte) */
@@ -5165,7 +5283,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5295,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5316,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;
 
       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5343,8 @@ reswitch:
       break;
     }
 
-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, maybe still need to deal with need_dasm.  */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;
 
@@ -5247,6 +5357,15 @@ no_support:
   return -1;
 }
 
+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
 \f
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5426,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;
 
+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;
 
   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };
 
 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };
 
+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-19 17:21       ` Hui Zhu
@ 2009-07-19 21:22         ` Mark Kettenis
  2009-07-20  6:14           ` Hui Zhu
  2009-07-20  1:39         ` Michael Snyder
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2009-07-19 21:22 UTC (permalink / raw)
  To: teawater; +Cc: msnyder, gdb-patches

> From: Hui Zhu <teawater@gmail.com>
> Date: Mon, 20 Jul 2009 01:16:10 +0800

>  /* Parse the current instruction and record the values of the registers and
>     memory that will be changed in current instruction to "record_arch_list".
>     Return -1 if something wrong. */
> 
> +#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
> +    do { \
> +         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
> +         return -1; \
> +       } while (0)
> +

Hmm, I really disklike this macro.  Having that return embedded in
there is really bad.

The current implementation of record_arch_list_add_reg() always
returns 0, so I don't see why you need it.

You should make record_arch_list_add_reg().


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-19 17:21       ` Hui Zhu
  2009-07-19 21:22         ` Mark Kettenis
@ 2009-07-20  1:39         ` Michael Snyder
  2009-07-20 10:22           ` Hui Zhu
  2009-07-25 22:07         ` Michael Snyder
  2009-07-25 22:20         ` Michael Snyder
  3 siblings, 1 reply; 15+ messages in thread
From: Michael Snyder @ 2009-07-20  1:39 UTC (permalink / raw)
  To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml

Hi Hui,

I think I discovered a bug in this one.  In 64-bit mode,
the "call immediate" instruction is not correctly logging
the pushed return address.  It's only saving 4 bytes.

Please tell me what you think of this patch to your patch?

Michael

--- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700
+++ tmp/i386-tdep.c     2009-07-19 17:51:51.000907000 -0700
@@ -4563,6 +4563,8 @@ reswitch:

        /* call im */
      case 0xe8:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
        if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
          return -1;
        break;


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-19 21:22         ` Mark Kettenis
@ 2009-07-20  6:14           ` Hui Zhu
  0 siblings, 0 replies; 15+ messages in thread
From: Hui Zhu @ 2009-07-20  6:14 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: msnyder, gdb-patches

On Mon, Jul 20, 2009 at 01:39, Mark Kettenis<mark.kettenis@xs4all.nl> wrote:
>> From: Hui Zhu <teawater@gmail.com>
>> Date: Mon, 20 Jul 2009 01:16:10 +0800
>
>>  /* Parse the current instruction and record the values of the registers and
>>     memory that will be changed in current instruction to "record_arch_list".
>>     Return -1 if something wrong. */
>>
>> +#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
>> +    do { \
>> +         if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
>> +         return -1; \
>> +       } while (0)
>> +
>
> Hmm, I really disklike this macro.  Having that return embedded in
> there is really bad.
>
> The current implementation of record_arch_list_add_reg() always
> returns 0, so I don't see why you need it.
>
> You should make record_arch_list_add_reg().
>

Thanks Mark,

I will change it to:
+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])
+

And about the the "record_arch_list_add_reg", I will post a special
patch to change it to void later.

Thanks,
Hui


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-20  1:39         ` Michael Snyder
@ 2009-07-20 10:22           ` Hui Zhu
  2009-07-20 14:24             ` Hui Zhu
  0 siblings, 1 reply; 15+ messages in thread
From: Hui Zhu @ 2009-07-20 10:22 UTC (permalink / raw)
  To: Michael Snyder; +Cc: Mark Kettenis, gdb-patches ml

Oops, I found a lot of push code need be check clear.

Thanks for you remind me.  I will check them all.

Hui

On Mon, Jul 20, 2009 at 08:51, Michael Snyder<msnyder@vmware.com> wrote:
> Hi Hui,
>
> I think I discovered a bug in this one.  In 64-bit mode,
> the "call immediate" instruction is not correctly logging
> the pushed return address.  It's only saving 4 bytes.
>
> Please tell me what you think of this patch to your patch?
>
> Michael
>
> --- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700
> +++ tmp/i386-tdep.c     2009-07-19 17:51:51.000907000 -0700
> @@ -4563,6 +4563,8 @@ reswitch:
>
>       /* call im */
>     case 0xe8:
> +      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
> +        ir.dflag = 2;
>       if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
>         return -1;
>       break;
>
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-20 10:22           ` Hui Zhu
@ 2009-07-20 14:24             ` Hui Zhu
  0 siblings, 0 replies; 15+ messages in thread
From: Hui Zhu @ 2009-07-20 14:24 UTC (permalink / raw)
  To: Michael Snyder, Mark Kettenis; +Cc: gdb-patches ml

[-- Attachment #1: Type: text/plain, Size: 75557 bytes --]

On Mon, Jul 20, 2009 at 14:13, Hui Zhu<teawater@gmail.com> wrote:
> Oops, I found a lot of push code need be check clear.
>
> Thanks for you remind me.  I will check them all.
>
> Hui
>
> On Mon, Jul 20, 2009 at 08:51, Michael Snyder<msnyder@vmware.com> wrote:
>> Hi Hui,
>>
>> I think I discovered a bug in this one.  In 64-bit mode,
>> the "call immediate" instruction is not correctly logging
>> the pushed return address.  It's only saving 4 bytes.
>>
>> Please tell me what you think of this patch to your patch?
>>
>> Michael
>>
>> --- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700
>> +++ tmp/i386-tdep.c     2009-07-19 17:51:51.000907000 -0700
>> @@ -4563,6 +4563,8 @@ reswitch:
>>
>>       /* call im */
>>     case 0xe8:
>> +      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
>> +        ir.dflag = 2;
>>       if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
>>         return -1;
>>       break;
>>
>>
>

Hi guys,

I make a new version to fix the error.  Please help me review it.

Thanks,
Hui

2009-07-20  Hui Zhu  <teawater@gmail.com>
            Michael Snyder  <msnyder@vmware.com>

	Add AMD64 process record instruction set support.

	* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
	because the AMD64's registers order in GDB is not same with
	I386 instructions.
	Add i386_syscall_record to be the syscall function handle
	interface.
	(record_i386_regnum): Number for record_regmap.
	* i386-tdep.c (OT_QUAD): For 64 bits.
	(i386_record_s): Add rex_x, rex_b, rip_offset and
	popl_esp_hack for AMD64 instruction set. And regmap for
	record_regmap.
	(i386_record_lea_modrm_addr): Support AMD64 instruction set
	64 bits lea.
	(i386_record_lea_modrm): Ditto.
	(i386_record_push): New function.  Record the execution log
	of push.
	(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
	register.
	(i386_process_record): Support AMD64 instruction set.
	amd64-tdep.c (amd64_record_regmap): For record_regmap.
	(amd64_init_abi): Set amd64_record_regmap to record_regmap.

---
 amd64-tdep.c |   12
 i386-tdep.c  | 1445 ++++++++++++++++++++++++++++++++---------------------------
 i386-tdep.h  |   35 +
 3 files changed, 833 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }

+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;

+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };

 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum

 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };

 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;

   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s
    Return -1 if something wrong. */

 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;

   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;

       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}

+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);

-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}

       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;

-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,33 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }

+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3211,22 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;

   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.popl_esp_hack = 0;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;

   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3257,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3280,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;

   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3414,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP1 */
@@ -3354,17 +3455,17 @@ reswitch:

 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* inv */
@@ -3385,10 +3486,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* GRP3 */
@@ -3401,28 +3500,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;

+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3520,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3537,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3554,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3562,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3579,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3627,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;

       /* imul */
@@ -3571,12 +3648,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* xadd */
@@ -3588,28 +3668,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg */
@@ -3623,22 +3700,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* cmpxchg8b */
@@ -3651,14 +3725,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* push */
@@ -3672,6 +3743,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3757,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;

@@ -3702,113 +3799,104 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;

       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
+          ir.popl_esp_hack = 1 << ir.ot;
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;

       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;

       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;

       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* mov */
@@ -3826,19 +3914,21 @@ reswitch:

       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3936,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;

-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;

       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3992,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* movzbS */
@@ -3931,8 +4006,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;

       /* lea */
@@ -3945,12 +4019,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* mov EAX */
@@ -3958,62 +4031,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;

       /* mov R, Ib */
@@ -4025,8 +4104,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM])
+                                        ? ((opcode & 0x7) | ir.rex_b)
+					: ((opcode & 0x7) & 0x3));
       break;

       /* mov R, Iv */
@@ -4038,8 +4118,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;

       /* xchg R, EAX */
@@ -4050,10 +4129,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;

       /* xchg Ev, Gv */
@@ -4063,33 +4140,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4186,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* shifts */
@@ -4149,10 +4225,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4234,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0fa4:
@@ -4204,9 +4276,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;

-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4338,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4357,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4383,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4441,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;

-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* port I/O */
@@ -4493,8 +4530,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

     case 0xe6:
@@ -4508,48 +4545,39 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* jmp im */
@@ -4611,14 +4639,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b)
+	                                        : (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4672,35 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;

       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;

       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4711,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;

       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* bcd */
@@ -4758,10 +4815,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* misc */
@@ -4853,16 +4913,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;

       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* loopnz */
@@ -4873,8 +4935,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* wrmsr */
@@ -4905,6 +4967,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4993,37 @@ reswitch:
       goto no_support;
       break;

+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;

       /* hlt */
@@ -4956,10 +5044,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5061,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5079,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;

 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5087,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5099,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5127,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5139,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5151,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;

-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5175,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5186,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5195,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5233,21 @@ reswitch:

       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]
+	                                   ? (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* lar */
@@ -5138,13 +5256,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;

       /* nop (multi byte) */
@@ -5165,7 +5289,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5301,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5322,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;

       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;

       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5349,8 @@ reswitch:
       break;
     }

-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, maybe still need to deal with need_dasm.  */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;

@@ -5247,6 +5363,15 @@ no_support:
   return -1;
 }

+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+

 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5432,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;

+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;

   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };

 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };

+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 71041 bytes --]

---
 amd64-tdep.c |   12 
 i386-tdep.c  | 1445 ++++++++++++++++++++++++++++++++---------------------------
 i386-tdep.h  |   35 +
 3 files changed, 833 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
   return 1;
 }
 
+static const int amd64_record_regmap[] =
+{
+  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
 void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   tdep->mm0_regnum = -1;
 
+  tdep->record_regmap = amd64_record_regmap;
+
   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
 
   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
   OT_BYTE = 0,
   OT_WORD,
   OT_LONG,
+  OT_QUAD,
 };
 
 /* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum
 
 struct i386_record_s
 {
+  struct gdbarch *gdbarch;
   struct regcache *regcache;
   CORE_ADDR addr;
   int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
   uint8_t modrm;
   uint8_t mod, reg, rm;
   int ot;
+  uint8_t rex_x;
+  uint8_t rex_b;
+  int rip_offset;
+  int popl_esp_hack;
+  const int *regmap;
 };
 
 /* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
 static int
 i386_record_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
 
   if (target_read_memory (irp->addr, &irp->modrm, 1))
     {
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s 
    Return -1 if something wrong. */
 
 static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+  struct gdbarch *gdbarch = irp->gdbarch;
   uint8_t tmpu8;
-  uint16_t tmpu16;
-  uint32_t tmpu32;
+  int16_t tmpi16;
+  int32_t tmpi32;
+  ULONGEST tmpulongest;
 
   *addr = 0;
   if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
 	    }
 	  irp->addr++;
 	  scale = (tmpu8 >> 6) & 3;
-	  index = ((tmpu8 >> 3) & 7);
+	  index = ((tmpu8 >> 3) & 7) | irp->rex_x;
 	  base = (tmpu8 & 7);
 	}
+      base |= irp->rex_b;
 
       switch (irp->mod)
 	{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if ((base & 7) == 5)
 	    {
 	      base = 0xff;
-	      if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	      if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 4;
+	      *addr = tmpi32;
+	      if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+		*addr += irp->addr + irp->rip_offset;
 	    }
 	  else
 	    {
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
 				   paddress (gdbarch, irp->addr));
 	      return -1;
 	    }
+	  *addr = tmpi32;
 	  irp->addr += 4;
 	  break;
 	}
 
+      tmpulongest = 0;
       if (base != 0xff)
-	{
-	  regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+        {
+	  if (base == 4 && irp->popl_esp_hack)
+	    *addr += irp->popl_esp_hack;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+                                      &tmpulongest);
 	}
+      if (irp->aflag == 2)
+        {
+	  *addr += tmpulongest;
+        }
+      else
+        *addr = (uint32_t) (tmpulongest + *addr);
 
-      /* XXX: index == 4 is always invalid */
       if (havesib && (index != 4 || scale != 0))
 	{
-	  regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
-	  *addr += tmpu32 << scale;
+	  regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+                                      &tmpulongest);
+	  if (irp->aflag == 2)
+	    *addr += tmpulongest << scale;
+	  else
+	    *addr = (uint32_t) (*addr + (tmpulongest << scale));
 	}
     }
   else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  if (irp->rm == 6)
 	    {
 	      if (target_read_memory
-		  (irp->addr, (gdb_byte *) & tmpu16, 2))
+		  (irp->addr, (gdb_byte *) &tmpi16, 2))
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
 		  return -1;
 		}
 	      irp->addr += 2;
-	      *addr = (int16_t) tmpu16;
+	      *addr = tmpi16;
 	      irp->rm = 0;
 	      goto no_rm;
 	    }
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
 	  *addr = (int8_t) tmpu8;
 	  break;
 	case 2:
-	  if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+	  if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
 	    {
 	      if (record_debug)
 		printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
 	      return -1;
 	    }
 	  irp->addr += 2;
-	  *addr = (int16_t) tmpu16;
+	  *addr = tmpi16;
 	  break;
 	}
 
       switch (irp->rm)
 	{
 	case 0:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 1:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 2:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 3:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 4:
-	  regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_RESI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 5:
-	  regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REDI_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 6:
-	  regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBP_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	case 7:
-	  regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  *addr += tmpu32;
+	  regcache_raw_read_unsigned (irp->regcache,
+				      irp->regmap[X86_RECORD_REBX_REGNUM],
+                                      &tmpulongest);
+	  *addr = (uint32_t) (*addr + tmpulongest);
 	  break;
 	}
       *addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
 static int
 i386_record_lea_modrm (struct i386_record_s *irp)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
-  uint32_t addr;
+  struct gdbarch *gdbarch = irp->gdbarch;
+  uint64_t addr;
 
-  if (irp->override)
+  if (irp->override >= 0)
     {
       if (record_debug)
 	printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,33 @@ i386_record_lea_modrm (struct i386_recor
   return 0;
 }
 
+/* Record the push operation to "record_arch_list".
+   Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+  ULONGEST tmpulongest;
+
+  if (record_arch_list_add_reg (irp->regcache,
+				irp->regmap[X86_RECORD_RESP_REGNUM]))
+    return -1;
+  regcache_raw_read_unsigned (irp->regcache,
+			      irp->regmap[X86_RECORD_RESP_REGNUM],
+			      &tmpulongest);
+  if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+    return -1;
+
+  return 0;
+}
+
 /* Parse the current instruction and record the values of the registers and
    memory that will be changed in current instruction to "record_arch_list".
    Return -1 if something wrong. */
 
+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+    record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])
+
 int
 i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		     CORE_ADDR addr)
@@ -3151,14 +3211,22 @@ i386_process_record (struct gdbarch *gdb
   uint8_t tmpu8;
   uint16_t tmpu16;
   uint32_t tmpu32;
+  ULONGEST tmpulongest;
   uint32_t opcode;
   struct i386_record_s ir;
+  int rex = 0;
+  uint8_t rex_w = -1;
+  uint8_t rex_r = 0;
 
   memset (&ir, 0, sizeof (struct i386_record_s));
   ir.regcache = regcache;
   ir.addr = addr;
   ir.aflag = 1;
   ir.dflag = 1;
+  ir.override = -1;
+  ir.popl_esp_hack = 0;
+  ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+  ir.gdbarch = gdbarch;
 
   if (record_debug > 1)
     fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3257,22 @@ i386_process_record (struct gdbarch *gdb
 	  prefixes |= PREFIX_LOCK;
 	  break;
 	case 0x2e:
-	  ir.override = I386_CS_REGNUM;
+	  ir.override = X86_RECORD_CS_REGNUM;
 	  break;
 	case 0x36:
-	  ir.override = I386_SS_REGNUM;
+	  ir.override = X86_RECORD_SS_REGNUM;
 	  break;
 	case 0x3e:
-	  ir.override = I386_DS_REGNUM;
+	  ir.override = X86_RECORD_DS_REGNUM;
 	  break;
 	case 0x26:
-	  ir.override = I386_ES_REGNUM;
+	  ir.override = X86_RECORD_ES_REGNUM;
 	  break;
 	case 0x64:
-	  ir.override = I386_FS_REGNUM;
+	  ir.override = X86_RECORD_FS_REGNUM;
 	  break;
 	case 0x65:
-	  ir.override = I386_GS_REGNUM;
+	  ir.override = X86_RECORD_GS_REGNUM;
 	  break;
 	case 0x66:
 	  prefixes |= PREFIX_DATA;
@@ -3212,16 +3280,51 @@ i386_process_record (struct gdbarch *gdb
 	case 0x67:
 	  prefixes |= PREFIX_ADDR;
 	  break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4a:
+        case 0x4b:
+        case 0x4c:
+        case 0x4d:
+        case 0x4e:
+        case 0x4f:
+          if (ir.regmap[X86_RECORD_R8_REGNUM])
+            {
+               /* REX */
+               rex = 1;
+               rex_w = (tmpu8 >> 3) & 1;
+               rex_r = (tmpu8 & 0x4) << 1;
+               ir.rex_x = (tmpu8 & 0x2) << 2;
+               ir.rex_b = (tmpu8 & 0x1) << 3;
+            }
+          break;
 	default:
 	  goto out_prefixes;
 	  break;
 	}
     }
 out_prefixes:
-  if (prefixes & PREFIX_DATA)
-    ir.dflag ^= 1;
+  if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+    {
+      ir.dflag = 2;
+    }
+  else
+    {
+      if (prefixes & PREFIX_DATA)
+        ir.dflag ^= 1;
+    }
   if (prefixes & PREFIX_ADDR)
     ir.aflag ^= 1;
+  else if (ir.regmap[X86_RECORD_R8_REGNUM])
+    ir.aflag = 2;
 
   /* now check op code */
   opcode = (uint32_t) tmpu8;
@@ -3311,30 +3414,28 @@ reswitch:
 		}
 	      else
 		{
-		  if (ir.ot == OT_BYTE)
+                  ir.rm |= ir.rex_b;
+		  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		    ir.rm &= 0x3;
-		  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 		}
 	      break;
 	      /* OP Gv, Ev */
 	    case 1:
 	      if (i386_record_modrm (&ir))
 		return -1;
-	      if (ir.ot == OT_BYTE)
+              ir.reg |= rex_r;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.reg &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	      break;
 	      /* OP A, Iv */
 	    case 2:
-	      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	      break;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP1 */
@@ -3354,17 +3455,17 @@ reswitch:
 
 	  if (ir.mod != 3)
 	    {
+              if (opcode == 0x83)
+                ir.rip_offset = 1;
+              else
+                ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* inv */
@@ -3385,10 +3486,8 @@ reswitch:
     case 0x4d:
     case 0x4e:
     case 0x4f:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* GRP3 */
@@ -3401,28 +3500,17 @@ reswitch:
       if (i386_record_modrm (&ir))
 	return -1;
 
+      if (ir.mod != 3 && ir.reg == 0)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
       switch (ir.reg)
 	{
 	  /* test */
 	case 0:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* not */
 	case 2:
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
-	  else
-	    {
-	      if (ir.ot == OT_BYTE)
-		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
-	  break;
 	  /* neg */
 	case 3:
 	  if (ir.mod != 3)
@@ -3432,13 +3520,14 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+              ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  /* neg */
+	  if (ir.reg == 3)
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* mul */
 	case 4:
@@ -3448,15 +3537,10 @@ reswitch:
 	case 6:
 	  /* idiv */
 	case 7:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (ir.ot != OT_BYTE)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-		return -1;
-	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3470,10 +3554,6 @@ reswitch:
     case 0xfe:
       /* GRP5 */
     case 0xff:
-      if ((opcode & 1) == 0)
-	ir.ot = OT_BYTE;
-      else
-	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3562,16 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (ir.reg)
 	{
 	  /* inc */
 	case 0:
 	  /* dec */
 	case 1:
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+          else
+	    ir.ot = ir.dflag + OT_WORD;
 	  if (ir.mod != 3)
 	    {
 	      if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3579,40 @@ reswitch:
 	    }
 	  else
 	    {
-	      if (ir.ot == OT_BYTE)
+	      ir.rm |= ir.rex_b;
+	      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 		ir.rm &= 0x3;
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
+	      I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	    }
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* call */
 	case 2:
-	  /* push */
-	case 6:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lcall */
 	case 3:
-	  if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	    return -1;
-	  if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	    return -1;
-	  regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			     (gdb_byte *) & tmpu32);
-	  if (record_arch_list_add_mem
-	      ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* jmp */
 	case 4:
 	  /* ljmp */
 	case 5:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* push */
+	case 6:
+          if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+            ir.dflag = 2;
+	  if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	    return -1;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3546,22 +3627,18 @@ reswitch:
     case 0x85:
     case 0xa8:
     case 0xa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* CWDE/CBW */
     case 0x98:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* CDQ/CWD */
     case 0x99:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       break;
 
       /* imul */
@@ -3571,12 +3648,15 @@ reswitch:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.ot == OT_BYTE)
+      if (opcode == 0x69)
+        ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+      else if (opcode == 0x6b)
+        ir.rip_offset = 1;
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* xadd */
@@ -3588,28 +3668,25 @@ reswitch:
 	ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
-	  if (ir.ot == OT_BYTE)
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg */
@@ -3623,22 +3700,19 @@ reswitch:
 	return -1;
       if (ir.mod == 3)
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
-	  if (ir.ot == OT_BYTE)
+          ir.reg |= rex_r;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.reg &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
 	}
       else
 	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* cmpxchg8b */
@@ -3651,14 +3725,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
       if (i386_record_lea_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* push */
@@ -3672,6 +3743,12 @@ reswitch:
     case 0x57:
     case 0x68:
     case 0x6a:
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push es */
     case 0x06:
       /* push cs */
@@ -3680,16 +3757,36 @@ reswitch:
     case 0x16:
       /* push ds */
     case 0x1e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+	return -1;
+      break;
+
       /* push fs */
     case 0x0fa0:
       /* push gs */
     case 0x0fa8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 2;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      break;
+
+      /* pusha */
+    case 0x60:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
 	return -1;
       break;
 
@@ -3702,113 +3799,104 @@ reswitch:
     case 0x5d:
     case 0x5e:
     case 0x5f:
-      ir.ot = ir.dflag + OT_WORD;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (ir.ot == OT_BYTE)
-	opcode &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
-      break;
-
-      /* pusha */
-    case 0x60:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* popa */
     case 0x61:
-      for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	    return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
 	}
+      for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+	   tmpu8++)
+	I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
       break;
 
       /* pop */
     case 0x8f:
-      ir.ot = ir.dflag + OT_WORD;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+	ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+      else
+        ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       else
 	{
+          ir.popl_esp_hack = 1 << ir.ot;
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
       break;
 
       /* enter */
     case 0xc8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
 	return -1;
       break;
 
       /* leave */
     case 0xc9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
       break;
 
       /* pop es */
     case 0x07:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ss */
     case 0x17:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop ds */
     case 0x1f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop fs */
     case 0x0fa1:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* pop gs */
     case 0x0fa9:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* mov */
@@ -3826,19 +3914,21 @@ reswitch:
 
       if (ir.mod != 3)
 	{
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+          if (opcode == 0xc6 || opcode == 0xc7)
+	    ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
       break;
+
       /* mov */
     case 0x8a:
     case 0x8b:
@@ -3846,40 +3936,55 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+      break;
 
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+      /* mov seg */
+    case 0x8c:
+      if (i386_record_modrm (&ir))
 	return -1;
+      if (ir.reg > 5)
+	{
+	  ir.addr -= 2;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
+
+      if (ir.mod == 3)
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+      else
+	{
+	  ir.ot = OT_WORD;
+	  if (i386_record_lea_modrm (&ir))
+	    return -1;
+	}
       break;
 
       /* mov seg */
     case 0x8e:
       if (i386_record_modrm (&ir))
 	return -1;
-
       switch (ir.reg)
 	{
 	case 0:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	case 2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	case 3:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	case 4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	case 5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	default:
 	  ir.addr -= 2;
@@ -3887,38 +3992,8 @@ reswitch:
 	  goto no_support;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
-      break;
-
-      /* mov seg */
-    case 0x8c:
-      if (i386_record_modrm (&ir))
-	return -1;
-      if (ir.reg > 5)
-	{
-	  ir.addr -= 2;
-	  opcode = opcode << 8 | ir.modrm;
-	  goto no_support;
-	}
-
-      if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      else
-	{
-	  ir.ot = OT_WORD;
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* movzbS */
@@ -3931,8 +4006,7 @@ reswitch:
     case 0x0fbf:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
       break;
 
       /* lea */
@@ -3945,12 +4019,11 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       ir.ot = ir.dflag;
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* mov EAX */
@@ -3958,62 +4031,68 @@ reswitch:
     case 0xa1:
       /* xlat */
     case 0xd7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* mov EAX */
     case 0xa2:
     case 0xa3:
-      {
-	uint32_t addr;
-
-	if (ir.override)
-	  {
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-	else
-	  {
-	    if ((opcode & 1) == 0)
-	      ir.ot = OT_BYTE;
-	    else
-	      ir.ot = ir.dflag + OT_WORD;
-	    if (ir.aflag)
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & addr, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 4;
-	      }
-	    else
-	      {
-		if (target_read_memory
-		    (ir.addr, (gdb_byte *) & tmpu16, 4))
-		  {
-		    if (record_debug)
-		      printf_unfiltered (_("Process record: error reading "
-					   "memory at addr %s len = 4.\n"),
-					 paddress (gdbarch, ir.addr));
-		    return -1;
-		  }
-		ir.addr += 2;
-		addr = tmpu16;
-	      }
-	    if (record_arch_list_add_mem (addr, 1 << ir.ot))
-	      return -1;
-	  }
-      }
+      if (ir.override >= 0)
+        {
+	  if (record_debug)
+	    printf_unfiltered (_("Process record ignores the memory change "
+				 "of instruction at address 0x%s because "
+				 "it can't get the value of the segment "
+				 "register.\n"),
+			       paddress (gdbarch, ir.addr));
+	}
+      else
+	{
+          if ((opcode & 1) == 0)
+	    ir.ot = OT_BYTE;
+	  else
+	    ir.ot = ir.dflag + OT_WORD;
+	  if (ir.aflag == 2)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 8.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 8;
+	    }
+          else if (ir.aflag)
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 4.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 4;
+              addr = tmpu32;
+	    }
+          else
+	    {
+              if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+		{
+	          if (record_debug)
+		    printf_unfiltered (_("Process record: error reading "
+	                    		 "memory at addr 0x%s len = 2.\n"),
+				       paddress (gdbarch, ir.addr));
+		  return -1;
+		}
+	      ir.addr += 2;
+              addr = tmpu16;
+	    }
+	  if (record_arch_list_add_mem (addr, 1 << ir.ot))
+	    return -1;
+        }
       break;
 
       /* mov R, Ib */
@@ -4025,8 +4104,9 @@ reswitch:
     case 0xb5:
     case 0xb6:
     case 0xb7:
-      if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM])
+                                        ? ((opcode & 0x7) | ir.rex_b)
+					: ((opcode & 0x7) & 0x3));
       break;
 
       /* mov R, Iv */
@@ -4038,8 +4118,7 @@ reswitch:
     case 0xbd:
     case 0xbe:
     case 0xbf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
       break;
 
       /* xchg R, EAX */
@@ -4050,10 +4129,8 @@ reswitch:
     case 0x95:
     case 0x96:
     case 0x97:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
       break;
 
       /* xchg Ev, Gv */
@@ -4063,33 +4140,35 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod == 3)
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm != ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
 	    return -1;
 	}
-
-      if (ir.ot == OT_BYTE)
+      ir.reg |= rex_r;
+      if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* les Gv */
     case 0xc4:
       /* lds Gv */
     case 0xc5:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+	  ir.addr -= 1;
+	  goto no_support;
+	}
       /* lss Gv */
     case 0x0fb2:
       /* lfs Gv */
@@ -4107,35 +4186,32 @@ reswitch:
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-
       switch (opcode)
 	{
 	  /* les Gv */
 	case 0xc4:
-	  tmpu8 = I386_ES_REGNUM;
+	  tmpu8 = X86_RECORD_ES_REGNUM;
 	  break;
 	  /* lds Gv */
 	case 0xc5:
-	  tmpu8 = I386_DS_REGNUM;
+	  tmpu8 = X86_RECORD_DS_REGNUM;
 	  break;
 	  /* lss Gv */
 	case 0x0fb2:
-	  tmpu8 = I386_SS_REGNUM;
+	  tmpu8 = X86_RECORD_SS_REGNUM;
 	  break;
 	  /* lfs Gv */
 	case 0x0fb4:
-	  tmpu8 = I386_FS_REGNUM;
+	  tmpu8 = X86_RECORD_FS_REGNUM;
 	  break;
 	  /* lgs Gv */
 	case 0x0fb5:
-	  tmpu8 = I386_GS_REGNUM;
+	  tmpu8 = X86_RECORD_GS_REGNUM;
 	  break;
 	}
-      if (record_arch_list_add_reg (ir.regcache, tmpu8))
-	return -1;
-
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* shifts */
@@ -4149,10 +4225,8 @@ reswitch:
 	ir.ot = OT_BYTE;
       else
 	ir.ot = ir.dflag + OT_WORD;
-
       if (i386_record_modrm (&ir))
 	return -1;
-
       if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4234,12 @@ reswitch:
 	}
       else
 	{
-	  if (ir.ot == OT_BYTE)
+	  ir.rm |= ir.rex_b;
+	  if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
 	    ir.rm &= 0x3;
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
+	  I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
 	}
-
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0fa4:
@@ -4204,9 +4276,9 @@ reswitch:
       if (ir.mod != 3)
 	{
 	  /* memory */
-	  uint32_t addr;
+	  uint64_t tmpu64;
 
-	  if (i386_record_lea_modrm_addr (&ir, &addr))
+	  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 	    return -1;
 	  switch (ir.reg)
 	    {
@@ -4266,16 +4338,16 @@ reswitch:
 		  switch (ir.reg >> 4)
 		    {
 		    case 0:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4285,16 +4357,16 @@ reswitch:
 		    {
 		    case 0:
 		    case 1:
-		      if (record_arch_list_add_mem (addr, 4))
+		      if (record_arch_list_add_mem (tmpu64, 4))
 			return -1;
 		      break;
 		    case 2:
-		      if (record_arch_list_add_mem (addr, 8))
+		      if (record_arch_list_add_mem (tmpu64, 8))
 			return -1;
 		      break;
 		    case 3:
 		    default:
-		      if (record_arch_list_add_mem (addr, 2))
+		      if (record_arch_list_add_mem (tmpu64, 2))
 			return -1;
 		      break;
 		    }
@@ -4311,43 +4383,43 @@ reswitch:
 	    case 0x0e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
 		}
 	      break;
 	    case 0x0f:
 	    case 0x2f:
-	      if (record_arch_list_add_mem (addr, 2))
+	      if (record_arch_list_add_mem (tmpu64, 2))
 		return -1;
 	      break;
 	    case 0x1f:
 	    case 0x3e:
-	      if (record_arch_list_add_mem (addr, 10))
+	      if (record_arch_list_add_mem (tmpu64, 10))
 		return -1;
 	      break;
 	    case 0x2e:
 	      if (ir.dflag)
 		{
-		  if (record_arch_list_add_mem (addr, 28))
+		  if (record_arch_list_add_mem (tmpu64, 28))
 		    return -1;
-		  addr += 28;
+		  tmpu64 += 28;
 		}
 	      else
 		{
-		  if (record_arch_list_add_mem (addr, 14))
+		  if (record_arch_list_add_mem (tmpu64, 14))
 		    return -1;
-		  addr += 14;
+		  tmpu64 += 14;
 		}
-	      if (record_arch_list_add_mem (addr, 80))
+	      if (record_arch_list_add_mem (tmpu64, 80))
 		return -1;
 	      break;
 	    case 0x3f:
-	      if (record_arch_list_add_mem (addr, 8))
+	      if (record_arch_list_add_mem (tmpu64, 8))
 		return -1;
 	      break;
 	    default:
@@ -4369,123 +4441,88 @@ reswitch:
       /* insS */
     case 0x6c:
     case 0x6d:
-      {
-	uint32_t addr;
-
-	if ((opcode & 1) == 0)
-	  ir.ot = OT_BYTE;
-	else
-	  ir.ot = ir.dflag + OT_WORD;
-	if (opcode == 0xa4 || opcode == 0xa5)
-	  {
-	    if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	      return -1;
-	  }
-	if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	  return -1;
-
-	regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
-			   (gdb_byte *) & addr);
-	if (!ir.aflag)
-	  {
-	    addr &= 0xffff;
-	    /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
-	    if (record_debug)
-	      printf_unfiltered (_("Process record ignores the memory change "
-				   "of instruction at address %s because "
-				   "it can't get the value of the segment "
-				   "register.\n"),
-				 paddress (gdbarch, ir.addr));
-	  }
-
-	if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	  {
-	    uint32_t count;
-
-	    regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
-			       (gdb_byte *) & count);
-	    if (!ir.aflag)
-	      count &= 0xffff;
-
-	    regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
-			       (gdb_byte *) & tmpu32);
-	    if ((tmpu32 >> 10) & 0x1)
-	      addr -= (count - 1) * (1 << ir.ot);
-
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
-		  return -1;
-	      }
+      if ((opcode & 1) == 0)
+	ir.ot = OT_BYTE;
+      else
+	ir.ot = ir.dflag + OT_WORD;
+      regcache_raw_read_unsigned (ir.regcache,
+                                  ir.regmap[X86_RECORD_REDI_REGNUM],
+                                  &tmpulongest);
+      if (!ir.aflag)
+        {
+          tmpulongest &= 0xffff;
+          /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+          if (record_debug)
+            printf_unfiltered (_("Process record ignores the memory change "
+                                 "of instruction at address 0x%s because "
+                                 "it can't get the value of the segment "
+                                 "register.\n"),
+                               paddress (gdbarch, ir.addr));
+        }
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        {
+          ULONGEST count, eflags;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_REDI_REGNUM],
+                                      &count);
+          if (!ir.aflag)
+            count &= 0xffff;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+                                      &eflags);
+          if ((eflags >> 10) & 0x1)
+            tmpulongest -= (count - 1) * (1 << ir.ot);
+          if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+            return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+        }
+      else
+        {
+          if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+            return -1;
+        }
+      if (opcode == 0xa4 || opcode == 0xa5)
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
 
-	    if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	      return -1;
-	  }
-	else
-	  {
-	    if (ir.aflag)
-	      {
-		if (record_arch_list_add_mem (addr, 1 << ir.ot))
-		  return -1;
-	      }
-	  }
-      }
+      /* cmpsS */
+    case 0xa6:
+    case 0xa7:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lodsS */
     case 0xac:
     case 0xad:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
-      if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      break;
-
-      /* outsS */
-    case 0x6e:
-    case 0x6f:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* scasS */
     case 0xae:
     case 0xaf:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
-      /* cmpsS */
-    case 0xa6:
-    case 0xa7:
-      if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
-	return -1;
+      /* outsS */
+    case 0x6e:
+    case 0x6f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
       if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
-	{
-	  if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* port I/O */
@@ -4493,8 +4530,8 @@ reswitch:
     case 0xe5:
     case 0xec:
     case 0xed:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
     case 0xe6:
@@ -4508,48 +4545,39 @@ reswitch:
     case 0xc2:
       /* ret */
     case 0xc3:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
       /* lret im */
     case 0xca:
       /* lret */
     case 0xcb:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      break;
-
       /* iret */
     case 0xcf:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* call im */
     case 0xe8:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* lcall im */
     case 0x9a:
-      if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* jmp im */
@@ -4611,14 +4639,13 @@ reswitch:
     case 0x0f9d:
     case 0x0f9e:
     case 0x0f9f:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       ir.ot = OT_BYTE;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.mod == 3)
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
-	    return -1;
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b)
+	                                        : (ir.rm & 0x3));
       else
 	{
 	  if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4672,35 @@ reswitch:
     case 0x0f4f:
       if (i386_record_modrm (&ir))
 	return -1;
+      ir.reg |= rex_r;
       if (ir.dflag == OT_BYTE)
 	ir.reg &= 0x3;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
       break;
 
       /* flags */
       /* pushf */
     case 0x9c:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
-			 (gdb_byte *) & tmpu32);
-      if (record_arch_list_add_mem
-	  ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+        ir.dflag = 2;
+      if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+        return -1;
       break;
 
       /* popf */
     case 0x9d:
-      if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* sahf */
     case 0x9e:
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
       /* cmc */
     case 0xf5:
       /* clc */
@@ -4683,66 +4711,95 @@ reswitch:
     case 0xfc:
       /* std */
     case 0xfd:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lahf */
     case 0x9f:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       break;
 
       /* bit operations */
       /* bt/bts/btr/btc Gv, im */
     case 0x0fba:
-      /* bts */
-    case 0x0fab:
-      /* btr */
-    case 0x0fb3:
-      /* btc */
-    case 0x0fbb:
       ir.ot = ir.dflag + OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
       if (ir.reg < 4)
 	{
-	  ir.addr -= 3;
+	  ir.addr -= 2;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
-      ir.reg -= 4;
-      if (ir.reg != 0)
+      if (ir.reg != 4)
 	{
-	  if (ir.mod != 3)
-	    {
-	      if (i386_record_lea_modrm (&ir))
-		return -1;
-	    }
+          if (ir.mod == 3)
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
 	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bt Gv, Ev */
     case 0x0fa3:
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+      break;
+
+      /* bts */
+    case 0x0fab:
+      /* btr */
+    case 0x0fb3:
+      /* btc */
+    case 0x0fbb:
+      ir.ot = ir.dflag + OT_WORD;
+      if (i386_record_modrm (&ir))
+        return -1;
+      if (ir.mod == 3)
+        I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+      else
+        {
+          uint64_t tmpu64;
+          if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+            return -1;
+          regcache_raw_read_unsigned (ir.regcache,
+                                      ir.regmap[ir.reg | rex_r],
+                                      &tmpulongest);
+          switch (ir.dflag)
+            {
+            case 0:
+              tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+              break;
+            case 1:
+              tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+              break;
+            case 2:
+              tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+              break;
+            }
+          if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+            return -1;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bsf */
     case 0x0fbc:
       /* bsr */
     case 0x0fbd:
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* bcd */
@@ -4758,10 +4815,13 @@ reswitch:
     case 0xd4:
       /* aad */
     case 0xd5:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* misc */
@@ -4853,16 +4913,18 @@ reswitch:
     case 0x0fcd:
     case 0x0fce:
     case 0x0fcf:
-      if (record_arch_list_add_reg (ir.regcache, opcode & 7))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
       break;
 
       /* salc */
     case 0xd6:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      if (ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          ir.addr -= 1;
+          goto no_support;
+        }
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* loopnz */
@@ -4873,8 +4935,8 @@ reswitch:
     case 0xe2:
       /* jecxz */
     case 0xe3:
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* wrmsr */
@@ -4905,6 +4967,11 @@ reswitch:
     case 0x0f34:
       {
 	int ret;
+        if (ir.regmap[X86_RECORD_R8_REGNUM])
+          {
+            ir.addr -= 2;
+            goto no_support;
+          }
 	if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
 	  {
 	    printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4993,37 @@ reswitch:
       goto no_support;
       break;
 
+      /* syscall */
+    case 0x0f05:
+      {
+	int ret;
+	if (gdbarch_tdep (gdbarch)->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);
+	if (ret)
+	  return ret;
+      }
+      break;
+
+      /* sysret */
+    case 0x0f07:
+      printf_unfiltered (_("Process record doesn't support "
+                           "instruction sysret.\n"));
+      ir.addr -= 2;
+      goto no_support;
+      break;
+
       /* cpuid */
     case 0x0fa2:
-      if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
-	return -1;
+      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);
       break;
 
       /* hlt */
@@ -4956,10 +5044,7 @@ reswitch:
 	  /* str */
 	case 1:
 	  if (ir.mod == 3)
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  else
 	    {
 	      ir.ot = OT_WORD;
@@ -4976,8 +5061,7 @@ reswitch:
 	case 4:
 	  /* verw */
 	case 5:
-	  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	    return -1;
+          I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	default:
 	  ir.addr -= 3;
@@ -4995,7 +5079,7 @@ reswitch:
 	  /* sgdt */
 	case 0:
 	  {
-	    uint32_t addr;
+	    uint64_t tmpu64;
 
 	    if (ir.mod == 3)
 	      {
@@ -5003,8 +5087,7 @@ reswitch:
 		opcode = opcode << 8 | ir.modrm;
 		goto no_support;
 	      }
-
-	    if (ir.override)
+	    if (ir.override >= 0)
 	      {
 		if (record_debug)
 		  printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5099,21 @@ reswitch:
 	      }
 	    else
 	      {
-		if (i386_record_lea_modrm_addr (&ir, &addr))
-		  return -1;
-		if (record_arch_list_add_mem (addr, 2))
+		if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		  return -1;
-		addr += 2;
-		if (record_arch_list_add_mem (addr, 4))
+		if (record_arch_list_add_mem (tmpu64, 2))
 		  return -1;
+		tmpu64 += 2;
+                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 8))
+		      return -1;
+                  }
+                else
+                  {
+                    if (record_arch_list_add_mem (tmpu64, 4))
+		      return -1;
+                  }
 	      }
 	  }
 	  break;
@@ -5036,8 +5127,7 @@ reswitch:
 		  break;
 		  /* mwait */
 		case 1:
-		  if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-		    return -1;
+		  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 		  break;
 		default:
 		  ir.addr -= 3;
@@ -5049,7 +5139,7 @@ reswitch:
 	  else
 	    {
 	      /* sidt */
-	      if (ir.override)
+	      if (ir.override >= 0)
 		{
 		  if (record_debug)
 		    printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5151,23 @@ reswitch:
 		}
 	      else
 		{
-		  uint32_t addr;
+		  uint64_t tmpu64;
 
-		  if (i386_record_lea_modrm_addr (&ir, &addr))
+		  if (i386_record_lea_modrm_addr (&ir, &tmpu64))
 		    return -1;
-		  if (record_arch_list_add_mem (addr, 2))
+		  if (record_arch_list_add_mem (tmpu64, 2))
 		    return -1;
 		  addr += 2;
-		  if (record_arch_list_add_mem (addr, 4))
-		    return -1;
+                  if (ir.regmap[X86_RECORD_R8_REGNUM])
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 8))
+		        return -1;
+                    }
+                  else
+                    {
+                      if (record_arch_list_add_mem (tmpu64, 4))
+		        return -1;
+                    }
 		}
 	    }
 	  break;
@@ -5077,9 +5175,6 @@ reswitch:
 	case 2:
 	  /* lidt */
 	case 3:
-	  /* invlpg */
-	case 7:
-	default:
 	  if (ir.mod == 3)
 	    {
 	      ir.addr -= 3;
@@ -5091,7 +5186,7 @@ reswitch:
 	case 4:
 	  if (ir.mod == 3)
 	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
+	      if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
 		return -1;
 	    }
 	  else
@@ -5100,9 +5195,32 @@ reswitch:
 	      if (i386_record_lea_modrm (&ir))
 		return -1;
 	    }
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  break;
 	  /* lmsw */
 	case 6:
+	  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	  /* invlpg */
+	case 7:
+	  if (ir.mod == 3)
+	    {
+	      if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+	        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+	      else
+	        {
+	          ir.addr -= 3;
+	          opcode = opcode << 8 | ir.modrm;
+	          goto no_support;
+	        }
+	    }
+	  else
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+	  break;
+	default:
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
 	  break;
 	}
       break;
@@ -5115,21 +5233,21 @@ reswitch:
 
       /* arpl */
     case 0x63:
-      ir.ot = ir.dflag ? OT_LONG : OT_WORD;
       if (i386_record_modrm (&ir))
 	return -1;
-      if (ir.mod != 3)
-	{
-	  if (i386_record_lea_modrm (&ir))
-	    return -1;
-	}
+      if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+        {
+          I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]
+	                                   ? (ir.reg | rex_r) : ir.rm);
+        }
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+        {
+          ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+          if (i386_record_lea_modrm (&ir))
+            return -1;
+        }
+      if (!ir.regmap[X86_RECORD_R8_REGNUM])
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* lar */
@@ -5138,13 +5256,19 @@ reswitch:
     case 0x0f03:
       if (i386_record_modrm (&ir))
 	return -1;
-      if (record_arch_list_add_reg (ir.regcache, ir.reg))
-	return -1;
-      if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
-	return -1;
+      I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
     case 0x0f18:
+      if (i386_record_modrm (&ir))
+	return -1;
+      if (ir.mod == 3 && ir.reg == 3)
+        {
+	  ir.addr -= 3;
+	  opcode = opcode << 8 | ir.modrm;
+	  goto no_support;
+	}
       break;
 
       /* nop (multi byte) */
@@ -5165,7 +5289,7 @@ reswitch:
 	return -1;
       if ((ir.modrm & 0xc0) != 0xc0)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
@@ -5177,16 +5301,12 @@ reswitch:
 	case 4:
 	case 8:
 	  if (opcode & 2)
-	    {
-	    }
+	    I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
 	  else
-	    {
-	      if (record_arch_list_add_reg (ir.regcache, ir.rm))
-		return -1;
-	    }
+            I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
 	  break;
 	default:
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	  break;
@@ -5202,22 +5322,19 @@ reswitch:
       if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
 	  || ir.reg == 5 || ir.reg >= 8)
 	{
-	  ir.addr -= 2;
+	  ir.addr -= 3;
 	  opcode = opcode << 8 | ir.modrm;
 	  goto no_support;
 	}
       if (opcode & 2)
-	{
-	}
+        I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       else
-	{
-	  if (record_arch_list_add_reg (ir.regcache, ir.rm))
-	    return -1;
-	}
+	I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
       break;
 
       /* clts */
     case 0x0f06:
+      I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       /* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5349,8 @@ reswitch:
       break;
     }
 
-/* In the future, Maybe still need to deal with need_dasm */
-  if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
-    return -1;
+  /* In the future, maybe still need to deal with need_dasm.  */
+  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
   if (record_arch_list_add_end ())
     return -1;
 
@@ -5247,6 +5363,15 @@ no_support:
   return -1;
 }
 
+static const int i386_record_regmap[] =
+{
+  I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+  I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+  I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
 \f
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5432,8 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->sc_pc_offset = -1;
   tdep->sc_sp_offset = -1;
 
+  tdep->record_regmap = i386_record_regmap;
+
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
   struct type *i387_ext_type;
 
   /* Process record/replay target.  */
+  /* The map for registers because the AMD64's registers order
+     in GDB is not same as I386 instructions.  */
+  const int *record_regmap;
   /* Parse intx80 args.  */
   int (*i386_intx80_record) (struct regcache *regcache);
   /* Parse sysenter args.  */
   int (*i386_sysenter_record) (struct regcache *regcache);
+  /* Parse syscall args.  */
+  int (*i386_syscall_record) (struct regcache *regcache);
 };
 
 /* Floating-point registers.  */
@@ -151,6 +156,36 @@ enum i386_regnum
   I386_ST0_REGNUM		/* %st(0) */
 };
 
+/* Register numbers of RECORD_REGMAP.  */
+
+enum record_i386_regnum
+{
+  X86_RECORD_REAX_REGNUM,
+  X86_RECORD_RECX_REGNUM,
+  X86_RECORD_REDX_REGNUM,
+  X86_RECORD_REBX_REGNUM,
+  X86_RECORD_RESP_REGNUM,
+  X86_RECORD_REBP_REGNUM,
+  X86_RECORD_RESI_REGNUM,
+  X86_RECORD_REDI_REGNUM,
+  X86_RECORD_R8_REGNUM,
+  X86_RECORD_R9_REGNUM,
+  X86_RECORD_R10_REGNUM,
+  X86_RECORD_R11_REGNUM,
+  X86_RECORD_R12_REGNUM,
+  X86_RECORD_R13_REGNUM,
+  X86_RECORD_R14_REGNUM,
+  X86_RECORD_R15_REGNUM,
+  X86_RECORD_REIP_REGNUM,
+  X86_RECORD_EFLAGS_REGNUM,
+  X86_RECORD_CS_REGNUM,
+  X86_RECORD_SS_REGNUM,
+  X86_RECORD_DS_REGNUM,
+  X86_RECORD_ES_REGNUM,
+  X86_RECORD_FS_REGNUM,
+  X86_RECORD_GS_REGNUM,
+};
+
 #define I386_NUM_GREGS	16
 #define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-19 17:21       ` Hui Zhu
  2009-07-19 21:22         ` Mark Kettenis
  2009-07-20  1:39         ` Michael Snyder
@ 2009-07-25 22:07         ` Michael Snyder
  2009-07-27 16:50           ` Hui Zhu
  2009-07-25 22:20         ` Michael Snyder
  3 siblings, 1 reply; 15+ messages in thread
From: Michael Snyder @ 2009-07-25 22:07 UTC (permalink / raw)
  To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml

Hui Zhu wrote:
> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:
>>> Thanks Michael,
>>>
>>> I updated all the AMD64 patches.  Please help me review it.
>>>
>>> Thanks,
>>> Hui
>>>
>>> 2009-07-17  Hui Zhu  <teawater@gmail.com>
>>>
>>>        Add AMD64 process record instruction set support.
>>>
>>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>>        because the AMD64's registers order in GDB is not same with
>>>        I386 instructions.
>>>        Add i386_syscall_record to be the syscall function handle
>>>        interface.
>>>        (record_i386_regnum): Number for record_regmap.
>>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>>        record_regmap.
>>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>>        64 bits lea.
>>>        (i386_record_lea_modrm): Ditto.
>>>        (i386_record_push): New function.  Record the execution log
>>>        of push.
>>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>>        register.
>>>        (i386_process_record): Support AMD64 instruction set.
>>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>> Should be a "*" at the beginning of the line above.

> Thanks Michael.
> 
> I update the patches according to your mail except changelog.  Because
> It sames that we just add * at the begin of the function name.

No, we add * before a file name.  Like this:

         * amd64-tdep.c (amd64_record_regmap): For record_regmap.
         (amd64_init_abi): Set amd64_record_regmap to record_regmap.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-19 17:21       ` Hui Zhu
                           ` (2 preceding siblings ...)
  2009-07-25 22:07         ` Michael Snyder
@ 2009-07-25 22:20         ` Michael Snyder
  2009-07-28 11:03           ` Hui Zhu
  3 siblings, 1 reply; 15+ messages in thread
From: Michael Snyder @ 2009-07-25 22:20 UTC (permalink / raw)
  To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml

Hui Zhu wrote:
> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:

>> Mark Kettenis should approve it, though.
>>
> 
> 
> Thanks Michael.
> 
> I update the patches according to your mail except changelog.  Because
> It sames that we just add * at the begin of the function name.
> 
> Please help me review it.
> 
> Thanks,
> Hui
> 
> 2009-07-20  Hui Zhu  <teawater@gmail.com>
> 
>         Add AMD64 process record instruction set support.
> 
>         * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>         because the AMD64's registers order in GDB is not same with
>         I386 instructions.
>         Add i386_syscall_record to be the syscall function handle
>         interface.
>         (record_i386_regnum): Number for record_regmap.
>         * i386-tdep.c (OT_QUAD): For 64 bits.
>         (i386_record_s): Add rex_x, rex_b, rip_offset and
>         popl_esp_hack for AMD64 instruction set. And regmap for
>         record_regmap.
>         (i386_record_lea_modrm_addr): Support AMD64 instruction set
>         64 bits lea.
>         (i386_record_lea_modrm): Ditto.
>         (i386_record_push): New function.  Record the execution log
>         of push.
>         (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>         register.
>         (i386_process_record): Support AMD64 instruction set.
>         amd64-tdep.c (amd64_record_regmap): For record_regmap.
>         (amd64_init_abi): Set amd64_record_regmap to record_regmap.

	* amd64-tdep.c (...):

Except for this small nit with the changelog,
I have no further issues with this patch.
Thanks for all your revisions (and your hard work)!

Mark?  You have the final say...


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-25 22:07         ` Michael Snyder
@ 2009-07-27 16:50           ` Hui Zhu
  0 siblings, 0 replies; 15+ messages in thread
From: Hui Zhu @ 2009-07-27 16:50 UTC (permalink / raw)
  To: Michael Snyder; +Cc: Mark Kettenis, gdb-patches ml

On Sun, Jul 26, 2009 at 04:49, Michael Snyder<msnyder@vmware.com> wrote:
> Hui Zhu wrote:
>>
>> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:
>>>>
>>>> Thanks Michael,
>>>>
>>>> I updated all the AMD64 patches.  Please help me review it.
>>>>
>>>> Thanks,
>>>> Hui
>>>>
>>>> 2009-07-17  Hui Zhu  <teawater@gmail.com>
>>>>
>>>>       Add AMD64 process record instruction set support.
>>>>
>>>>       * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>>>       because the AMD64's registers order in GDB is not same with
>>>>       I386 instructions.
>>>>       Add i386_syscall_record to be the syscall function handle
>>>>       interface.
>>>>       (record_i386_regnum): Number for record_regmap.
>>>>       * i386-tdep.c (OT_QUAD): For 64 bits.
>>>>       (i386_record_s): Add rex_x, rex_b, rip_offset and
>>>>       popl_esp_hack for AMD64 instruction set. And regmap for
>>>>       record_regmap.
>>>>       (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>>>       64 bits lea.
>>>>       (i386_record_lea_modrm): Ditto.
>>>>       (i386_record_push): New function.  Record the execution log
>>>>       of push.
>>>>       (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>>>       register.
>>>>       (i386_process_record): Support AMD64 instruction set.
>>>>       amd64-tdep.c (amd64_record_regmap): For record_regmap.
>>>
>>> Should be a "*" at the beginning of the line above.
>
>> Thanks Michael.
>>
>> I update the patches according to your mail except changelog.  Because
>> It sames that we just add * at the begin of the function name.
>
> No, we add * before a file name.  Like this:
>
>        * amd64-tdep.c (amd64_record_regmap): For record_regmap.
>        (amd64_init_abi): Set amd64_record_regmap to record_regmap.
>
>

Oops,  I forgot the last one.  Really sorry for it.

2009-07-20  Hui Zhu  <teawater@gmail.com>

	Add AMD64 process record instruction set support.

	* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
	because the AMD64's registers order in GDB is not same with
	I386 instructions.
	Add i386_syscall_record to be the syscall function handle
	interface.
	(record_i386_regnum): Number for record_regmap.
	* i386-tdep.c (OT_QUAD): For 64 bits.
	(i386_record_s): Add rex_x, rex_b, rip_offset and
	popl_esp_hack for AMD64 instruction set. And regmap for
	record_regmap.
	(i386_record_lea_modrm_addr): Support AMD64 instruction set
	64 bits lea.
	(i386_record_lea_modrm): Ditto.
	(i386_record_push): New function.  Record the execution log
	of push.
	(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
	register.
	(i386_process_record): Support AMD64 instruction set.
	* amd64-tdep.c (amd64_record_regmap): For record_regmap.
	(amd64_init_abi): Set amd64_record_regmap to record_regmap.

Thanks,
Hui


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-25 22:20         ` Michael Snyder
@ 2009-07-28 11:03           ` Hui Zhu
  2009-08-03  5:37             ` Hui Zhu
  0 siblings, 1 reply; 15+ messages in thread
From: Hui Zhu @ 2009-07-28 11:03 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: Michael Snyder, gdb-patches ml

Hi Mark,

Could you please help me review this patch?

Thanks,
Hui

On Sun, Jul 26, 2009 at 06:00, Michael Snyder<msnyder@vmware.com> wrote:
> Hui Zhu wrote:
>>
>> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:
>
>>> Mark Kettenis should approve it, though.
>>>
>>
>>
>> Thanks Michael.
>>
>> I update the patches according to your mail except changelog.  Because
>> It sames that we just add * at the begin of the function name.
>>
>> Please help me review it.
>>
>> Thanks,
>> Hui
>>
>> 2009-07-20  Hui Zhu  <teawater@gmail.com>
>>
>>        Add AMD64 process record instruction set support.
>>
>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>        because the AMD64's registers order in GDB is not same with
>>        I386 instructions.
>>        Add i386_syscall_record to be the syscall function handle
>>        interface.
>>        (record_i386_regnum): Number for record_regmap.
>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>        record_regmap.
>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>        64 bits lea.
>>        (i386_record_lea_modrm): Ditto.
>>        (i386_record_push): New function.  Record the execution log
>>        of push.
>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>        register.
>>        (i386_process_record): Support AMD64 instruction set.
>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>>        (amd64_init_abi): Set amd64_record_regmap to record_regmap.
>
>        * amd64-tdep.c (...):
>
> Except for this small nit with the changelog,
> I have no further issues with this patch.
> Thanks for all your revisions (and your hard work)!
>
> Mark?  You have the final say...
>
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second   version, (instruction set support) 1/3
  2009-07-28 11:03           ` Hui Zhu
@ 2009-08-03  5:37             ` Hui Zhu
  0 siblings, 0 replies; 15+ messages in thread
From: Hui Zhu @ 2009-08-03  5:37 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: Michael Snyder, gdb-patches ml

Ping.

On Tue, Jul 28, 2009 at 09:42, Hui Zhu<teawater@gmail.com> wrote:
> Hi Mark,
>
> Could you please help me review this patch?
>
> Thanks,
> Hui
>
> On Sun, Jul 26, 2009 at 06:00, Michael Snyder<msnyder@vmware.com> wrote:
>> Hui Zhu wrote:
>>>
>>> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote:
>>
>>>> Mark Kettenis should approve it, though.
>>>>
>>>
>>>
>>> Thanks Michael.
>>>
>>> I update the patches according to your mail except changelog.  Because
>>> It sames that we just add * at the begin of the function name.
>>>
>>> Please help me review it.
>>>
>>> Thanks,
>>> Hui
>>>
>>> 2009-07-20  Hui Zhu  <teawater@gmail.com>
>>>
>>>        Add AMD64 process record instruction set support.
>>>
>>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>>        because the AMD64's registers order in GDB is not same with
>>>        I386 instructions.
>>>        Add i386_syscall_record to be the syscall function handle
>>>        interface.
>>>        (record_i386_regnum): Number for record_regmap.
>>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>>        record_regmap.
>>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>>        64 bits lea.
>>>        (i386_record_lea_modrm): Ditto.
>>>        (i386_record_push): New function.  Record the execution log
>>>        of push.
>>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>>        register.
>>>        (i386_process_record): Support AMD64 instruction set.
>>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>>>        (amd64_init_abi): Set amd64_record_regmap to record_regmap.
>>
>>        * amd64-tdep.c (...):
>>
>> Except for this small nit with the changelog,
>> I have no further issues with this patch.
>> Thanks for all your revisions (and your hard work)!
>>
>> Mark?  You have the final say...
>>
>>
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-08-03  5:37 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-07  2:38 [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 Hui Zhu
2009-07-13  0:52 ` Michael Snyder
2009-07-17  8:50   ` Hui Zhu
2009-07-18  1:20     ` Michael Snyder
2009-07-19 17:21       ` Hui Zhu
2009-07-19 21:22         ` Mark Kettenis
2009-07-20  6:14           ` Hui Zhu
2009-07-20  1:39         ` Michael Snyder
2009-07-20 10:22           ` Hui Zhu
2009-07-20 14:24             ` Hui Zhu
2009-07-25 22:07         ` Michael Snyder
2009-07-27 16:50           ` Hui Zhu
2009-07-25 22:20         ` Michael Snyder
2009-07-28 11:03           ` Hui Zhu
2009-08-03  5:37             ` Hui Zhu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox