rpms/gdb/F-13 gdb-bz578250-avx-01of10.patch, NONE, 1.1 gdb-bz578250-avx-02of10.patch, NONE, 1.1 gdb-bz578250-avx-03of10.patch, NONE, 1.1 gdb-bz578250-avx-04of10.patch, NONE, 1.1 gdb-bz578250-avx-05of10.patch, NONE, 1.1 gdb-bz578250-avx-06of10.patch, NONE, 1.1 gdb-bz578250-avx-07of10.patch, NONE, 1.1 gdb-bz578250-avx-08of10.patch, NONE, 1.1 gdb-bz578250-avx-09of10.patch, NONE, 1.1 gdb-bz578250-avx-10of10.patch, NONE, 1.1 gdb.spec, 1.423, 1.424

Jan Kratochvil jkratoch at fedoraproject.org
Sat Apr 3 21:07:05 UTC 2010


Author: jkratoch

Update of /cvs/pkgs/rpms/gdb/F-13
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv3376

Modified Files:
	gdb.spec 
Added Files:
	gdb-bz578250-avx-01of10.patch gdb-bz578250-avx-02of10.patch 
	gdb-bz578250-avx-03of10.patch gdb-bz578250-avx-04of10.patch 
	gdb-bz578250-avx-05of10.patch gdb-bz578250-avx-06of10.patch 
	gdb-bz578250-avx-07of10.patch gdb-bz578250-avx-08of10.patch 
	gdb-bz578250-avx-09of10.patch gdb-bz578250-avx-10of10.patch 
Log Message:
* Sat Apr  3 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.1-6.fc13
- Support AVX registers (BZ 578250).


gdb-bz578250-avx-01of10.patch:
 amd64-linux-nat.c                |   35 +++++
 amd64-linux-tdep.c               |   73 +++++++---
 amd64-linux-tdep.h               |    3 
 amd64-tdep.c                     |   62 ++------
 gdbserver/Makefile.in            |   30 ++--
 gdbserver/configure.srv          |   33 +++-
 gdbserver/linux-x86-low.c        |    8 -
 i386-linux-nat.c                 |   10 +
 i386-linux-tdep.c                |   66 +++++++--
 i386-linux-tdep.h                |    3 
 i386-nto-tdep.c                  |    2 
 i386-tdep.c                      |  270 ++++++++++++++-------------------------
 i386-tdep.h                      |   29 ++--
 i387-tdep.h                      |    3 
 regformats/i386/amd64-linux.dat  |   62 ++++++++
 regformats/i386/amd64.dat        |   61 ++++++++
 regformats/i386/i386-linux.dat   |   46 ++++++
 regformats/i386/i386.dat         |   45 ++++++
 regformats/reg-i386-linux.dat    |   46 ------
 regformats/reg-i386.dat          |   44 ------
 regformats/reg-x86-64-linux.dat  |   62 --------
 regformats/reg-x86-64.dat        |   59 --------
 testsuite/gdb.xml/tdesc-regs.exp |   15 ++
 23 files changed, 561 insertions(+), 506 deletions(-)

--- NEW FILE gdb-bz578250-avx-01of10.patch ---
[ Backported.  ]

commit d454b7529a5e6134ace8541b341d079534f2062a
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Mon Mar 1 15:33:29 2010 +0000

    Enable XML target descriptions for x86.
    
    gdb/
    
    2010-03-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* amd64-linux-nat.c (AMD64_LINUX_USER64_CS): New.
    	(amd64_linux_read_description): Likewise.
    	(_initialize_amd64_linux_nat): Set to_read_description to
    	amd64_linux_read_description.
    
    	* amd64-linux-tdep.c: Include "features/i386/amd64-linux.c".
    	(amd64_linux_register_name): Removed.
    	(amd64_linux_register_type): Likewise.
    	(amd64_linux_core_read_description): New.
    	(amd64_linux_init_abi): Set target description to
    	tdesc_amd64_linux if needed.  Support orig_rax in target
    	description.  Don't call set_gdbarch_register_name nor
    	set_gdbarch_register_type.  Call
    	set_gdbarch_core_read_description.
    	(_initialize_amd64_linux_tdep): Call
    	initialize_tdesc_amd64_linux.
    
    	* amd64-linux-tdep.h (tdesc_amd64_linux): New.
    
    	* amd64-tdep.c:  Include "features/i386/amd64.c".
    	(amd64_register_names): Removed.
    	(amd64_register_name): Likewise.
    	(amd64_register_type): Likewise.
    	(amd64_init_abi):  Set num_core_regs and register_names.  Set
    	target description to tdesc_amd64 if needed.  Don't call
    	set_gdbarch_register_name nor set_gdbarch_register_type.
    	(_initialize_amd64_tdep): New.
    
    	* i386-linux-nat.c (i386_linux_read_description): New.
    	(_initialize_i386_linux_nat): Set to_read_description to
    	i386_linux_read_description.
    
    	* i386-linux-tdep.c: Include "features/i386/i386-linux.c".
    	(i386_linux_register_name): Removed.
    	(i386_linux_core_read_description): New.
    	(i386_linux_read_description): Likewise.
    	(i386_linux_init_abi): Don't call set_gdbarch_register_name.
    	Set target description to tdesc_i386_linux if needed.  Support
    	orig_eax.  Set register_reggroup_p.  Call
    	set_gdbarch_core_read_description.
    	(_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux.
    
    	* i386-linux-tdep.h (tdesc_i386_linux): New.
    
    	* i386-nto-tdep.c (i386nto_regset_id): Replace I386_NUM_FREGS
    	with I387_NUM_REGS.
    
    	* i386-tdep.c: Include "features/i386/i386.c".
    	(i386_register_names): Make it const.
    	(i386_mmx_names): Likewise.
    	(i386_num_register_names): Removed.
    	(i386_register_name): Likewise.
    	(i386_eflags_type): Likewise.
    	(i386_mxcsr_type): Likewise.
    	(i386_sse_type): Likewise.
    	(i386_register_type): Likewise.
    	(i387_ext_type): Call tdesc_find_type instead of arch_float_type.
    	(i386_pseudo_register_name): New.
    	(i386_pseudo_register_type): Likewise.
    	(i386_mmx_type): Make it static.
    	(i386_gdbarch_init): Check arch.  Replace I386_NUM_FREGS with
    	I387_NUM_REGS.  Set num_core_regs and register_names.  Don't
    	call set_gdbarch_register_name nor set_gdbarch_register_type.
    	Set register_reggroup_p.  Set target description to tdesc_i386
    	if needed.  Call set_tdesc_pseudo_register_type,
    	set_tdesc_pseudo_register_name and tdesc_use_registers.
    	(_initialize_i386_tdep): Call initialize_tdesc_i386.
    	initialize_tdesc_x86_64.
    
    	* i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type,
    	i386_mxcsr_type and i386_sse_type.  Add num_core_regs,
    	register_names, tdesc and register_reggroup_p.
    	(I386_NUM_FREGS): Removed.
    	(i386_eflags_type): Likewise.
    	(i386_mxcsr_type): Likewise.
    	(i386_mmx_type): Likewise.
    	(i386_sse_type): Likewise.
    	(i386_register_name): Likewise.
    	(i386_regnum): Add I386_MXCSR_REGNUM.
    	(I386_SSE_NUM_REGS): Defined with I386_MXCSR_REGNUM.
    
    	* i387-tdep.h (I387_NUM_REGS): New.
    
    	* regformats/i386/i386-linux.dat: Generated.
    	* regformats/i386/i386.dat: Likewise.
    	* regformats/i386/amd64-linux.dat: Likewise.
    	* regformats/i386/amd64.dat: Likewise.
    
    	* regformats/reg-i386-linux.dat: Removed.
    	* regformats/reg-i386.dat: Likewise.
    	* regformats/reg-x86-64-linux.dat: Likewise.
    	* regformats/reg-x86-64.dat: Likewise.
    
    gdb/gdbserver/
    
    2010-03-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* Makefile.in (clean): Replace reg-i386.c, reg-x86-64.c,
    	reg-i386-linux.c and reg-x86-64-linux.c with i386.c, amd64.c,
    	i386-linux.c and amd64-linux.c.
    	(reg-i386.o): Removed.
    	(reg-i386.c): Likewise.
    	(reg-i386-linux.o): Likewise.
    	(reg-i386-linux.c): Likewise.
    	(reg-x86-64.o): Likewise.
    	(reg-x86-64.c): Likewise.
    	(reg-x86-64-linux.o): Likewise.
    	(reg-x86-64-linux.c): Likewise.
    	(i386.o): New.
    	(i386.c): Likewise.
    	(i386-linux.o): Likewise.
    	(i386-linux.c): Likewise.
    	(amd64.o): Likewise.
    	(amd64.c): Likewise.
    	(amd64-linux.o): Likewise.
    	(amd64-linux.c): Likewise.
    
    	* configure.srv (srv_i386_regobj): New.
    	(srv_i386_linux_regobj): Likewise.
    	(srv_amd64_regobj): Likewise.
    	(srv_amd64_linux_regobj): Likewise.
    	(srv_i386_32bit_xmlfiles): Likewise.
    	(srv_i386_64bit_xmlfiles): Likewise.
    	(srv_i386_xmlfiles): Likewise.
    	(srv_amd64_xmlfiles): Likewise.
    	(srv_i386_linux_xmlfiles): Likewise.
    	(srv_amd64_linux_xmlfiles): Likewise.
    	(i[34567]86-*-cygwin*): Set srv_regobj to $srv_i386_regobj.  Set
    	srv_xmlfiles to $srv_i386_xmlfiles.
    	(i[34567]86-*-mingw32ce*): Likewise.
    	(i[34567]86-*-mingw*): Likewise.
    	(i[34567]86-*-nto*): Likewise.
    	(i[34567]86-*-linux*): Set srv_regobj to $srv_i386_linux_regobj
    	and $srv_amd64_linux_regobj.  Set srv_xmlfiles to
    	$srv_i386_linux_xmlfiles and $srv_amd64_linux_xmlfiles.
    	(x86_64-*-linux*): Likewise.
    
    	* linux-x86-low.c (init_registers_x86_64_linux): Removed.
    	(init_registers_amd64_linux): New.
    	(x86_arch_setup): Replace init_registers_x86_64_linux with
    	init_registers_amd64_linux.
    
    gdb/testsuite/
    
    2010-03-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* gdb.xml/tdesc-regs.exp (architecture): New.  Set it for x86.
    	(load_description): Set architecture if defined.

--- ./gdb/amd64-linux-nat.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/amd64-linux-nat.c	2010-04-03 20:59:52.000000000 +0200
@@ -817,6 +817,39 @@ amd64_linux_siginfo_fixup (struct siginf
     return 0;
 }
 
+/* Get Linux/x86 target description from running target.
+
+   Value of CS segment register:
+     1. 64bit process: 0x33.
+     2. 32bit process: 0x23.
+ */
+
+#define AMD64_LINUX_USER64_CS	0x33
+
+static const struct target_desc *
+amd64_linux_read_description (struct target_ops *ops)
+{
+  unsigned long cs;
+  int tid;
+
+  /* GNU/Linux LWP ID's are process ID's.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
+
+  /* Get CS register.  */
+  errno = 0;
+  cs = ptrace (PTRACE_PEEKUSER, tid,
+	       offsetof (struct user_regs_struct, cs), 0);
+  if (errno != 0)
+    perror_with_name (_("Couldn't get CS register"));
+
+  if (cs == AMD64_LINUX_USER64_CS)
+    return tdesc_amd64_linux;
+  else
+    return tdesc_i386_linux;
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_amd64_linux_nat (void);
 
@@ -861,6 +894,8 @@ _initialize_amd64_linux_nat (void)
   linux_elfcore_write_prstatus = amd64_linux_elfcore_write_prstatus;
   linux_elfcore_write_prfpreg = amd64_linux_elfcore_write_prfpreg;
 
+  t->to_read_description = amd64_linux_read_description;
+
   /* Register the target.  */
   linux_nat_add_target (t);
   linux_nat_set_new_thread (t, amd64_linux_new_thread);
--- ./gdb/amd64-linux-tdep.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/amd64-linux-tdep.c	2010-04-03 20:59:52.000000000 +0200
@@ -37,6 +37,8 @@
 #include "solib-svr4.h"
 #include "xml-syscall.h"
 
+#include "features/i386/amd64-linux.c"
+
 /* The syscall's XML filename for i386.  */
 #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
 
@@ -234,26 +236,6 @@ static int amd64_linux_sc_reg_offset[] =
   -1				/* %gs */
 };
 
-/* Replacement register functions which know about %orig_rax.  */
-
-static const char *
-amd64_linux_register_name (struct gdbarch *gdbarch, int reg)
-{
-  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
-    return "orig_rax";
-
-  return amd64_register_name (gdbarch, reg);
-}
-
-static struct type *
-amd64_linux_register_type (struct gdbarch *gdbarch, int reg)
-{
-  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
-    return builtin_type (gdbarch)->builtin_int64;
-
-  return amd64_register_type (gdbarch, reg);
-}
-
 static int
 amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 				 struct reggroup *group)
@@ -1334,10 +1316,32 @@ amd64_linux_record_signal (struct gdbarc
   return 0;
 }
 
+/* Get Linux/x86 target description from core dump.  */
+
+static const struct target_desc *
+amd64_linux_core_read_description (struct gdbarch *gdbarch,
+				  struct target_ops *target,
+				  bfd *abfd)
+{
+  asection *section = bfd_get_section_by_name (abfd, ".reg2");
+
+  if (section == NULL)
+    return NULL;
+
+  /* Linux/x86-64.  */
+  return tdesc_amd64_linux;
+}
+
 static void
 amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const struct target_desc *tdesc = info.target_desc;
+  struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
+  const struct tdesc_feature *feature;
+  int valid_p;
+
+  gdb_assert (tdesc_data);
 
   tdep->gregset_reg_offset = amd64_linux_gregset_reg_offset;
   tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset);
@@ -1345,6 +1349,23 @@ amd64_linux_init_abi (struct gdbarch_inf
 
   amd64_init_abi (info, gdbarch);
 
+  /* Reserve a number for orig_rax.  */
+  set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
+
+  if (! tdesc_has_registers (tdesc))
+    tdesc = tdesc_amd64_linux;
+  tdep->tdesc = tdesc;
+
+  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
+  if (feature == NULL)
+    return;
+
+  valid_p = tdesc_numbered_register (feature, tdesc_data,
+				     AMD64_LINUX_ORIG_RAX_REGNUM,
+				     "orig_rax");
+  if (!valid_p)
+    return;
+
   tdep->sigtramp_p = amd64_linux_sigtramp_p;
   tdep->sigcontext_addr = amd64_linux_sigcontext_addr;
   tdep->sc_reg_offset = amd64_linux_sc_reg_offset;
@@ -1358,10 +1379,8 @@ amd64_linux_init_abi (struct gdbarch_inf
 
   /* Add the %orig_rax register used for syscall restarting.  */
   set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc);
-  set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
-  set_gdbarch_register_name (gdbarch, amd64_linux_register_name);
-  set_gdbarch_register_type (gdbarch, amd64_linux_register_type);
-  set_gdbarch_register_reggroup_p (gdbarch, amd64_linux_register_reggroup_p);
+
+  tdep->register_reggroup_p = amd64_linux_register_reggroup_p;
 
   /* Functions for 'catch syscall'.  */
   set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64);
@@ -1375,6 +1394,9 @@ amd64_linux_init_abi (struct gdbarch_inf
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
+  set_gdbarch_core_read_description (gdbarch,
+				     amd64_linux_core_read_description);
+
   /* Displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                         amd64_displaced_step_copy_insn);
@@ -1571,4 +1593,7 @@ _initialize_amd64_linux_tdep (void)
 {
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
 			  GDB_OSABI_LINUX, amd64_linux_init_abi);
+
+  /* Initialize the Linux target description  */
+  initialize_tdesc_amd64_linux ();
 }
--- ./gdb/amd64-linux-tdep.h	2010-01-01 08:31:29.000000000 +0100
+++ ./gdb/amd64-linux-tdep.h	2010-04-03 20:59:52.000000000 +0200
@@ -31,6 +31,9 @@
 /* Total number of registers for GNU/Linux.  */
 #define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1)
 
+/* Linux target description.  */
+extern struct target_desc *tdesc_amd64_linux;
+
 /* Enum that defines the syscall identifiers for amd64 linux.
    Used for process record/replay, these will be translated into
    a gdb-canonical set of syscall ids in linux-record.c.  */
--- ./gdb/amd64-tdep.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/amd64-tdep.c	2010-04-03 20:59:52.000000000 +0200
@@ -42,6 +42,8 @@
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
 
+#include "features/i386/amd64.c"
+
 /* Note that the AMD64 architecture was previously known as x86-64.
    The latter is (forever) engraved into the canonical system name as
    returned by config.guess, and used as the name for the AMD64 port
@@ -83,47 +85,6 @@ static int amd64_dummy_call_integer_regs
   9				/* %r9 */
 };
 
-/* Return the name of register REGNUM.  */
-
-const char *
-amd64_register_name (struct gdbarch *gdbarch, int regnum)
-{
-  if (regnum >= 0 && regnum < AMD64_NUM_REGS)
-    return amd64_register_names[regnum];
-
-  return NULL;
-}
-
-/* Return the GDB type object for the "standard" data type of data in
-   register REGNUM. */
-
-struct type *
-amd64_register_type (struct gdbarch *gdbarch, int regnum)
-{
-  if (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_RDI_REGNUM)
-    return builtin_type (gdbarch)->builtin_int64;
-  if (regnum == AMD64_RBP_REGNUM || regnum == AMD64_RSP_REGNUM)
-    return builtin_type (gdbarch)->builtin_data_ptr;
-  if (regnum >= AMD64_R8_REGNUM && regnum <= AMD64_R15_REGNUM)
-    return builtin_type (gdbarch)->builtin_int64;
-  if (regnum == AMD64_RIP_REGNUM)
-    return builtin_type (gdbarch)->builtin_func_ptr;
-  if (regnum == AMD64_EFLAGS_REGNUM)
-    return i386_eflags_type (gdbarch);
-  if (regnum >= AMD64_CS_REGNUM && regnum <= AMD64_GS_REGNUM)
-    return builtin_type (gdbarch)->builtin_int32;
-  if (regnum >= AMD64_ST0_REGNUM && regnum <= AMD64_ST0_REGNUM + 7)
-    return i387_ext_type (gdbarch);
-  if (regnum >= AMD64_FCTRL_REGNUM && regnum <= AMD64_FCTRL_REGNUM + 7)
-    return builtin_type (gdbarch)->builtin_int32;
-  if (regnum >= AMD64_XMM0_REGNUM && regnum <= AMD64_XMM0_REGNUM + 15)
-    return i386_sse_type (gdbarch);
-  if (regnum == AMD64_MXCSR_REGNUM)
-    return i386_mxcsr_type (gdbarch);
-
-  internal_error (__FILE__, __LINE__, _("invalid regnum"));
-}
-
 /* DWARF Register Number Mapping as defined in the System V psABI,
    section 3.6.  */
 
@@ -2158,11 +2119,19 @@ void
 amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const struct target_desc *tdesc = info.target_desc;
 
   /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
      floating-point registers.  */
   tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE;
 
+  if (! tdesc_has_registers (tdesc))
+    tdesc = tdesc_amd64;
+  tdep->tdesc = tdesc;
+
+  tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
+  tdep->register_names = amd64_register_names;
+
   /* AMD64 has an FPU and 16 SSE registers.  */
   tdep->st0_regnum = AMD64_ST0_REGNUM;
   tdep->num_xmm_regs = 16;
@@ -2178,8 +2147,6 @@ amd64_init_abi (struct gdbarch_info info
   set_gdbarch_long_double_bit (gdbarch, 128);
 
   set_gdbarch_num_regs (gdbarch, AMD64_NUM_REGS);
-  set_gdbarch_register_name (gdbarch, amd64_register_name);
-  set_gdbarch_register_type (gdbarch, amd64_register_type);
 
   /* Register numbers of various important registers.  */
   set_gdbarch_sp_regnum (gdbarch, AMD64_RSP_REGNUM); /* %rsp */
@@ -2241,6 +2208,15 @@ amd64_init_abi (struct gdbarch_info info
 
   set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target);
 }
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_amd64_tdep (void);
+
+void
+_initialize_amd64_tdep (void)
+{
+  initialize_tdesc_amd64 ();
+}
 
 
 /* The 64-bit FXSAVE format differs from the 32-bit format in the
--- ./gdb/gdbserver/Makefile.in	2010-01-04 16:03:00.000000000 +0100
+++ ./gdb/gdbserver/Makefile.in	2010-04-03 20:59:52.000000000 +0200
@@ -203,9 +203,9 @@ clean:
 	rm -f *.o ${ADD_FILES} *~
 	rm -f version.c
 	rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log
-	rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c
-	rm -f reg-sh.c reg-sparc.c reg-spu.c reg-x86-64.c reg-i386-linux.c
-	rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c
+	rm -f reg-arm.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
+	rm -f reg-sh.c reg-sparc.c reg-spu.c amd64.c i386-linux.c
+	rm -f reg-cris.c reg-crisv32.c amd64-linux.c reg-xtensa.c
 	rm -f arm-with-iwmmxt.c
 	rm -f arm-with-vfpv2.c arm-with-vfpv3.c arm-with-neon.c
 	rm -f mips-linux.c mips64-linux.c
@@ -345,12 +345,12 @@ reg-cris.c : $(srcdir)/../regformats/reg
 reg-crisv32.o : reg-crisv32.c $(regdef_h)
 reg-crisv32.c : $(srcdir)/../regformats/reg-crisv32.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-crisv32.dat reg-crisv32.c
-reg-i386.o : reg-i386.c $(regdef_h)
-reg-i386.c : $(srcdir)/../regformats/reg-i386.dat $(regdat_sh)
-	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386.dat reg-i386.c
-reg-i386-linux.o : reg-i386-linux.c $(regdef_h)
-reg-i386-linux.c : $(srcdir)/../regformats/reg-i386-linux.dat $(regdat_sh)
-	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386-linux.dat reg-i386-linux.c
+i386.o : i386.c $(regdef_h)
+i386.c : $(srcdir)/../regformats/i386/i386.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386.dat i386.c
+i386-linux.o : i386-linux.c $(regdef_h)
+i386-linux.c : $(srcdir)/../regformats/i386/i386-linux.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-linux.dat i386-linux.c
 reg-ia64.o : reg-ia64.c $(regdef_h)
 reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c
@@ -432,12 +432,12 @@ reg-sparc64.c : $(srcdir)/../regformats/
 reg-spu.o : reg-spu.c $(regdef_h)
 reg-spu.c : $(srcdir)/../regformats/reg-spu.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-spu.dat reg-spu.c
-reg-x86-64.o : reg-x86-64.c $(regdef_h)
-reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
-	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c
-reg-x86-64-linux.o : reg-x86-64-linux.c $(regdef_h)
-reg-x86-64-linux.c : $(srcdir)/../regformats/reg-x86-64-linux.dat $(regdat_sh)
-	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64-linux.dat reg-x86-64-linux.c
+amd64.o : amd64.c $(regdef_h)
+amd64.c : $(srcdir)/../regformats/i386/amd64.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64.dat amd64.c
+amd64-linux.o : amd64-linux.c $(regdef_h)
+amd64-linux.c : $(srcdir)/../regformats/i386/amd64-linux.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-linux.dat amd64-linux.c
 reg-xtensa.o : reg-xtensa.c $(regdef_h)
 reg-xtensa.c : $(srcdir)/../regformats/reg-xtensa.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-xtensa.dat reg-xtensa.c
--- ./gdb/gdbserver/configure.srv	2010-01-04 16:03:00.000000000 +0100
+++ ./gdb/gdbserver/configure.srv	2010-04-03 20:59:52.000000000 +0200
@@ -22,6 +22,18 @@
 # Default hostio_last_error implementation
 srv_hostio_err_objs="hostio-errno.o"
 
+srv_i386_regobj=i386.o
+srv_i386_linux_regobj=i386-linux.o
+srv_amd64_regobj=amd64.o
+srv_amd64_linux_regobj=amd64-linux.o
+
+srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml"
+srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-sse.xml"
+srv_i386_xmlfiles="i386/i386.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_xmlfiles="i386/amd64.xml $srv_i386_64bit_xmlfiles"
+srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/32bit-linux.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/64bit-linux.xml $srv_i386_64bit_xmlfiles"
+
 # Input is taken from the "${target}" variable.
 
 case "${target}" in
@@ -60,12 +72,15 @@ case "${target}" in
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
-  i[34567]86-*-cygwin*)	srv_regobj=reg-i386.o
+  i[34567]86-*-cygwin*)	srv_regobj="$srv_i386_regobj"
 			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
+			srv_xmlfiles="$srv_i386_xmlfiles"
 			;;
-  i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
+  i[34567]86-*-linux*)	srv_regobj="$srv_i386_linux_regobj"
+			srv_xmlfiles="$srv_i386_linux_xmlfiles"
 			if test "$gdb_cv_i386_is_x86_64" = yes ; then
-			    srv_regobj="reg-x86-64-linux.o $srv_regobj"
+			    srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
+			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
 			fi
 			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
 			srv_linux_usrregs=yes
@@ -73,20 +88,23 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   i[34567]86-*-mingw32ce*)
-			srv_regobj=reg-i386.o
+			srv_regobj="$srv_i386_regobj"
 			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
 			srv_tgtobj="${srv_tgtobj} wincecompat.o"
+			srv_xmlfiles="$srv_i386_xmlfiles"
 			# hostio_last_error implementation is in win32-low.c
 			srv_hostio_err_objs=""
 			srv_mingw=yes
 			srv_mingwce=yes
 			;;
-  i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
+  i[34567]86-*-mingw*)	srv_regobj="$srv_i386_regobj"
 			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
+			srv_xmlfiles="$srv_i386_xmlfiles"
 			srv_mingw=yes
 			;;
-  i[34567]86-*-nto*)	srv_regobj=reg-i386.o
+  i[34567]86-*-nto*)	srv_regobj="$srv_i386_regobj"
 			srv_tgtobj="nto-low.o nto-x86-low.o"
+			srv_xmlfiles="$srv_i386_xmlfiles"
 			srv_qnx="yes"
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
@@ -206,8 +224,9 @@ case "${target}" in
   spu*-*-*)		srv_regobj=reg-spu.o
 			srv_tgtobj="spu-low.o"
 			;;
-  x86_64-*-linux*)	srv_regobj="reg-x86-64-linux.o reg-i386-linux.o"
+  x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
 			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
+			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
 			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
--- ./gdb/gdbserver/linux-x86-low.c	2010-01-20 23:55:38.000000000 +0100
+++ ./gdb/gdbserver/linux-x86-low.c	2010-04-03 20:59:52.000000000 +0200
@@ -27,10 +27,10 @@
 
 #include "gdb_proc_service.h"
 
-/* Defined in auto-generated file reg-i386-linux.c.  */
+/* Defined in auto-generated file i386-linux.c.  */
 void init_registers_i386_linux (void);
-/* Defined in auto-generated file reg-x86-64-linux.c.  */
-void init_registers_x86_64_linux (void);
+/* Defined in auto-generated file amd64-linux.c.  */
+void init_registers_amd64_linux (void);
 
 #include <sys/reg.h>
 #include <sys/procfs.h>
@@ -792,7 +792,7 @@ x86_arch_setup (void)
     }
   else if (use_64bit)
     {
-      init_registers_x86_64_linux ();
+      init_registers_amd64_linux ();
 
       /* Amd64 doesn't have HAVE_LINUX_USRREGS.  */
       the_low_target.num_regs = -1;
--- ./gdb/i386-linux-nat.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/i386-linux-nat.c	2010-04-03 20:59:52.000000000 +0200
@@ -868,6 +868,14 @@ i386_linux_child_post_startup_inferior (
   super_post_startup_inferior (ptid);
 }
 
+/* Get Linux/x86 target description from running target.  */
+
+static const struct target_desc *
+i386_linux_read_description (struct target_ops *ops)
+{
+  return tdesc_i386_linux;
+}
+
 void
 _initialize_i386_linux_nat (void)
 {
@@ -897,6 +905,8 @@ _initialize_i386_linux_nat (void)
   t->to_fetch_registers = i386_linux_fetch_inferior_registers;
   t->to_store_registers = i386_linux_store_inferior_registers;
 
+  t->to_read_description = i386_linux_read_description;
+
   /* Register the target.  */
   linux_nat_add_target (t);
   linux_nat_set_new_thread (t, i386_linux_new_thread);
--- ./gdb/i386-linux-tdep.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/i386-linux-tdep.c	2010-04-03 20:59:52.000000000 +0200
@@ -46,6 +46,8 @@
 #include "linux-record.h"
 #include <stdint.h>
 
+#include "features/i386/i386-linux.c"
+
 /* Supported register note sections.  */
 static struct core_regset_section i386_linux_regset_sections[] =
 {
@@ -55,18 +57,6 @@ static struct core_regset_section i386_l
   { NULL, 0 }
 };
 
-/* Return the name of register REG.  */
-
-static const char *
-i386_linux_register_name (struct gdbarch *gdbarch, int reg)
-{
-  /* Deal with the extra "orig_eax" pseudo register.  */
-  if (reg == I386_LINUX_ORIG_EAX_REGNUM)
-    return "orig_eax";
-
-  return i386_register_name (gdbarch, reg);
-}
-
 /* Return non-zero, when the register is in the corresponding register
    group.  Put the LINUX_ORIG_EAX register in the system group.  */
 static int
@@ -570,21 +560,57 @@ static int i386_linux_sc_reg_offset[] =
   0 * 4				/* %gs */
 };
 
+/* Get Linux/x86 target description from core dump.  */
+
+static const struct target_desc *
+i386_linux_core_read_description (struct gdbarch *gdbarch,
+				  struct target_ops *target,
+				  bfd *abfd)
+{
+  asection *section = bfd_get_section_by_name (abfd, ".reg2");
+
+  if (section == NULL)
+    return NULL;
+
+  /* Linux/i386.  */
+  return tdesc_i386_linux;
+}
+
 static void
 i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const struct target_desc *tdesc = info.target_desc;
+  struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
+  const struct tdesc_feature *feature;
+  int valid_p;
+
+  gdb_assert (tdesc_data);
 
   /* GNU/Linux uses ELF.  */
   i386_elf_init_abi (info, gdbarch);
 
-  /* Since we have the extra "orig_eax" register on GNU/Linux, we have
-     to adjust a few things.  */
+  /* Reserve a number for orig_eax.  */
+  set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS);
+
+  if (! tdesc_has_registers (tdesc))
+    tdesc = tdesc_i386_linux;
+  tdep->tdesc = tdesc;
+
+  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
+  if (feature == NULL)
+    return;
+
+  valid_p = tdesc_numbered_register (feature, tdesc_data,
+				     I386_LINUX_ORIG_EAX_REGNUM,
+				     "orig_eax");
+  if (!valid_p)
+    return;
 
+  /* Add the %orig_eax register used for syscall restarting.  */
   set_gdbarch_write_pc (gdbarch, i386_linux_write_pc);
-  set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS);
-  set_gdbarch_register_name (gdbarch, i386_linux_register_name);
-  set_gdbarch_register_reggroup_p (gdbarch, i386_linux_register_reggroup_p);
+
+  tdep->register_reggroup_p = i386_linux_register_reggroup_p;
 
   tdep->gregset_reg_offset = i386_linux_gregset_reg_offset;
   tdep->gregset_num_regs = ARRAY_SIZE (i386_linux_gregset_reg_offset);
@@ -783,6 +809,9 @@ i386_linux_init_abi (struct gdbarch_info
   /* Install supported register note sections.  */
   set_gdbarch_core_regset_sections (gdbarch, i386_linux_regset_sections);
 
+  set_gdbarch_core_read_description (gdbarch,
+				     i386_linux_core_read_description);
+
   /* Displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                         simple_displaced_step_copy_insn);
@@ -811,4 +840,7 @@ _initialize_i386_linux_tdep (void)
 {
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX,
 			  i386_linux_init_abi);
+
+  /* Initialize the Linux target description  */
+  initialize_tdesc_i386_linux ();
 }
--- ./gdb/i386-linux-tdep.h	2010-01-01 08:31:34.000000000 +0100
+++ ./gdb/i386-linux-tdep.h	2010-04-03 20:59:52.000000000 +0200
@@ -35,4 +35,7 @@
 /* Total number of registers for GNU/Linux.  */
 #define I386_LINUX_NUM_REGS (I386_LINUX_ORIG_EAX_REGNUM + 1)
 
+/* Linux target description.  */
+extern struct target_desc *tdesc_i386_linux;
+
 #endif /* i386-linux-tdep.h */
--- ./gdb/i386-nto-tdep.c	2010-01-01 08:31:34.000000000 +0100
+++ ./gdb/i386-nto-tdep.c	2010-04-03 20:59:52.000000000 +0200
@@ -122,7 +122,7 @@ i386nto_regset_id (int regno)
     return NTO_REG_END;
   else if (regno < I386_NUM_GREGS)
     return NTO_REG_GENERAL;
-  else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
+  else if (regno < I386_NUM_GREGS + I387_NUM_REGS)
     return NTO_REG_FLOAT;
   else if (regno < I386_SSE_NUM_REGS)
     return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area.  */
--- ./gdb/i386-tdep.c	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/i386-tdep.c	2010-04-03 20:59:52.000000000 +0200
@@ -54,9 +54,11 @@
 #include "record.h"
 #include <stdint.h>
 
+#include "features/i386/i386.c"
+
 /* Register names.  */
 
-static char *i386_register_names[] =
+static const char *i386_register_names[] =
 {
   "eax",   "ecx",    "edx",   "ebx",
   "esp",   "ebp",    "esi",   "edi",
@@ -71,11 +73,9 @@ static char *i386_register_names[] =
   "mxcsr"
 };
 
-static const int i386_num_register_names = ARRAY_SIZE (i386_register_names);
-
 /* Register names for MMX pseudo-registers.  */
 
-static char *i386_mmx_names[] =
+static const char *i386_mmx_names[] =
 {
   "mm0", "mm1", "mm2", "mm3",
   "mm4", "mm5", "mm6", "mm7"
@@ -147,16 +147,11 @@ i386_fpc_regnum_p (struct gdbarch *gdbar
 
 /* Return the name of register REGNUM.  */
 
-const char *
-i386_register_name (struct gdbarch *gdbarch, int regnum)
+static const char *
+i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 {
-  if (i386_mmx_regnum_p (gdbarch, regnum))
-    return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
-
-  if (regnum >= 0 && regnum < i386_num_register_names)
-    return i386_register_names[regnum];
-
-  return NULL;
+  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
+  return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
 }
 
 /* Convert a dbx register number REG to the appropriate register
@@ -2112,87 +2107,22 @@ i386_return_value (struct gdbarch *gdbar
 }
 
 
-/* Construct types for ISA-specific registers.  */
-struct type *
-i386_eflags_type (struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  if (!tdep->i386_eflags_type)
-    {
-      struct type *type;
-
-      type = arch_flags_type (gdbarch, "builtin_type_i386_eflags", 4);
-      append_flags_type_flag (type, 0, "CF");
-      append_flags_type_flag (type, 1, NULL);
-      append_flags_type_flag (type, 2, "PF");
-      append_flags_type_flag (type, 4, "AF");
-      append_flags_type_flag (type, 6, "ZF");
-      append_flags_type_flag (type, 7, "SF");
-      append_flags_type_flag (type, 8, "TF");
-      append_flags_type_flag (type, 9, "IF");
-      append_flags_type_flag (type, 10, "DF");
-      append_flags_type_flag (type, 11, "OF");
-      append_flags_type_flag (type, 14, "NT");
-      append_flags_type_flag (type, 16, "RF");
-      append_flags_type_flag (type, 17, "VM");
-      append_flags_type_flag (type, 18, "AC");
-      append_flags_type_flag (type, 19, "VIF");
-      append_flags_type_flag (type, 20, "VIP");
-      append_flags_type_flag (type, 21, "ID");
-
-      tdep->i386_eflags_type = type;
-    }
-
-  return tdep->i386_eflags_type;
-}
-
-struct type *
-i386_mxcsr_type (struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  if (!tdep->i386_mxcsr_type)
-    {
-      struct type *type;
-
-      type = arch_flags_type (gdbarch, "builtin_type_i386_mxcsr", 4);
-      append_flags_type_flag (type, 0, "IE");
-      append_flags_type_flag (type, 1, "DE");
-      append_flags_type_flag (type, 2, "ZE");
-      append_flags_type_flag (type, 3, "OE");
-      append_flags_type_flag (type, 4, "UE");
-      append_flags_type_flag (type, 5, "PE");
-      append_flags_type_flag (type, 6, "DAZ");
-      append_flags_type_flag (type, 7, "IM");
-      append_flags_type_flag (type, 8, "DM");
-      append_flags_type_flag (type, 9, "ZM");
-      append_flags_type_flag (type, 10, "OM");
-      append_flags_type_flag (type, 11, "UM");
-      append_flags_type_flag (type, 12, "PM");
-      append_flags_type_flag (type, 15, "FZ");
-
-      tdep->i386_mxcsr_type = type;
-    }
-
-  return tdep->i386_mxcsr_type;
-}
-
 struct type *
 i387_ext_type (struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (!tdep->i387_ext_type)
-    tdep->i387_ext_type
-      = arch_float_type (gdbarch, -1, "builtin_type_i387_ext",
-			 floatformats_i387_ext);
+    {
+      tdep->i387_ext_type = tdesc_find_type (gdbarch, "i387_ext");
+      gdb_assert (tdep->i387_ext_type != NULL);
+    }
 
   return tdep->i387_ext_type;
 }
 
 /* Construct vector type for MMX registers.  */
-struct type *
+static struct type *
 i386_mmx_type (struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2233,84 +2163,14 @@ i386_mmx_type (struct gdbarch *gdbarch)
   return tdep->i386_mmx_type;
 }
 
-struct type *
-i386_sse_type (struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  if (!tdep->i386_sse_type)
-    {
-      const struct builtin_type *bt = builtin_type (gdbarch);
-
-      /* The type we're building is this: */
-#if 0
-      union __gdb_builtin_type_vec128i
-      {
-        int128_t uint128;
-        int64_t v2_int64[2];
-        int32_t v4_int32[4];
-        int16_t v8_int16[8];
-        int8_t v16_int8[16];
-        double v2_double[2];
-        float v4_float[4];
-      };
-#endif
-
-      struct type *t;
-
-      t = arch_composite_type (gdbarch,
-			       "__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
-      append_composite_type_field (t, "v4_float",
-				   init_vector_type (bt->builtin_float, 4));
-      append_composite_type_field (t, "v2_double",
-				   init_vector_type (bt->builtin_double, 2));
-      append_composite_type_field (t, "v16_int8",
-				   init_vector_type (bt->builtin_int8, 16));
-      append_composite_type_field (t, "v8_int16",
-				   init_vector_type (bt->builtin_int16, 8));
-      append_composite_type_field (t, "v4_int32",
-				   init_vector_type (bt->builtin_int32, 4));
-      append_composite_type_field (t, "v2_int64",
-				   init_vector_type (bt->builtin_int64, 2));
-      append_composite_type_field (t, "uint128", bt->builtin_int128);
-
-      TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "builtin_type_vec128i";
-      tdep->i386_sse_type = t;
-    }
-
-  return tdep->i386_sse_type;
-}
-
 /* Return the GDB type object for the "standard" data type of data in
-   register REGNUM.  Perhaps %esi and %edi should go here, but
-   potentially they could be used for things other than address.  */
+   register REGNUM. */
 
 static struct type *
-i386_register_type (struct gdbarch *gdbarch, int regnum)
+i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  if (regnum == I386_EIP_REGNUM)
-    return builtin_type (gdbarch)->builtin_func_ptr;
-
-  if (regnum == I386_EFLAGS_REGNUM)
-    return i386_eflags_type (gdbarch);
-
-  if (regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
-    return builtin_type (gdbarch)->builtin_data_ptr;
-
-  if (i386_fp_regnum_p (gdbarch, regnum))
-    return i387_ext_type (gdbarch);
-
-  if (i386_mmx_regnum_p (gdbarch, regnum))
-    return i386_mmx_type (gdbarch);
-
-  if (i386_sse_regnum_p (gdbarch, regnum))
-    return i386_sse_type (gdbarch);
-
-  if (regnum == I387_MXCSR_REGNUM (gdbarch_tdep (gdbarch)))
-    return i386_mxcsr_type (gdbarch);
-
-  return builtin_type (gdbarch)->builtin_int;
+  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
+  return i386_mmx_type (gdbarch);
 }
 
 /* Map a cooked register onto a raw register or memory.  For the i386,
@@ -2761,7 +2621,7 @@ i386_go32_init_abi (struct gdbarch_info 
 
   /* DJGPP does not support the SSE registers.  */
   tdep->num_xmm_regs = 0;
-  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS);
+  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I387_NUM_REGS);
 
   /* Native compiler is GCC, which uses the SVR4 register numbering
      even in COFF and STABS.  See the comment in i386_gdbarch_init,
@@ -5623,12 +5483,50 @@ i386_fast_tracepoint_valid_at (struct gd
   return 1;
 }
 
+static int
+i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
+		       struct tdesc_arch_data *tdesc_data)
+{
+  const struct target_desc *tdesc = tdep->tdesc;
+  const struct tdesc_feature *feature_core, *feature_vector;
+  int i, num_regs, valid_p;
+
+  if (! tdesc_has_registers (tdesc))
+    return 0;
+
+  /* Get core registers.  */
+  feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
+
+  /* Get SSE registers.  */
+  feature_vector = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
+
+  if (feature_core == NULL || feature_vector == NULL)
+    return 0;
+
+  valid_p = 1;
+
+  num_regs = tdep->num_core_regs;
+  for (i = 0; i < num_regs; i++)
+    valid_p &= tdesc_numbered_register (feature_core, tdesc_data, i,
+					tdep->register_names[i]);
+
+  /* Need to include %mxcsr, so add one.  */
+  num_regs += tdep->num_xmm_regs + 1;
+  for (; i < num_regs; i++)
+    valid_p &= tdesc_numbered_register (feature_vector, tdesc_data, i,
+					tdep->register_names[i]);
+
+  return valid_p;
+}
+
 
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
+  struct tdesc_arch_data *tdesc_data;
+  const struct target_desc *tdesc;
 
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
@@ -5699,12 +5597,6 @@ i386_gdbarch_init (struct gdbarch_info i
      alignment.  */
   set_gdbarch_long_double_bit (gdbarch, 96);
 
-  /* The default ABI includes general-purpose registers, 
-     floating-point registers, and the SSE registers.  */
-  set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
-  set_gdbarch_register_name (gdbarch, i386_register_name);
-  set_gdbarch_register_type (gdbarch, i386_register_type);
-
   /* Register numbers of various important registers.  */
   set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */
   set_gdbarch_pc_regnum (gdbarch, I386_EIP_REGNUM); /* %eip */
@@ -5775,11 +5667,6 @@ i386_gdbarch_init (struct gdbarch_info i
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  /* Wire in the MMX registers.  */
-  set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
-  set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
-  set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
-
   set_gdbarch_print_insn (gdbarch, i386_print_insn);
 
   set_gdbarch_dummy_id (gdbarch, i386_dummy_id);
@@ -5788,7 +5675,7 @@ i386_gdbarch_init (struct gdbarch_info i
 
   /* Add the i386 register groups.  */
   i386_add_reggroups (gdbarch);
-  set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
+  tdep->register_reggroup_p = i386_register_reggroup_p;
 
   /* Helper for function argument information.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
@@ -5806,9 +5693,49 @@ i386_gdbarch_init (struct gdbarch_info i
 
   frame_base_set_default (gdbarch, &i386_frame_base);
 
+  /* Wire in the MMX registers.  */
+  set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
+  set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
+  set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
+
+  set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type);
+  set_tdesc_pseudo_register_name (gdbarch, i386_pseudo_register_name);
+
+  /* The default ABI includes general-purpose registers, 
+     floating-point registers, and the SSE registers.  */
+  set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
+
+  /* Get the x86 target description from INFO.  */
+  tdesc = info.target_desc;
+  if (! tdesc_has_registers (tdesc))
+    tdesc = tdesc_i386;
+  tdep->tdesc = tdesc;
+
+  tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
+  tdep->register_names = i386_register_names;
+
+  tdesc_data = tdesc_data_alloc ();
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
+  info.tdep_info = (void *) tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
+  /* Target description may be changed.  */
+  tdesc = tdep->tdesc;
+
+  if (!i386_validate_tdesc_p (tdep, tdesc_data))
+    {
+      tdesc_data_cleanup (tdesc_data);
+      xfree (tdep);
+      gdbarch_free (gdbarch);
+      return NULL;
+    }
+
+  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+
+  /* Override gdbarch_register_reggroup_p set in tdesc_use_registers.  */
+  set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);
+
   /* Hook in the legacy prologue-based unwinders last (fallback).  */
   frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
@@ -5885,4 +5812,7 @@ is \"default\"."),
 
   /* Initialize the i386-specific register groups.  */
   i386_init_reggroups ();
+
+  /* Initialize the standard target descriptions.  */
+  initialize_tdesc_i386 ();
 }
--- ./gdb/i386-tdep.h	2010-04-03 20:24:51.000000000 +0200
+++ ./gdb/i386-tdep.h	2010-04-03 20:59:52.000000000 +0200
@@ -118,9 +118,21 @@ struct gdbarch_tdep
      of MMX support.  */
   int mm0_regnum;
 
+  /* Number of core registers.  */
+  int num_core_regs;
+
   /* Number of SSE registers.  */
   int num_xmm_regs;
 
+  /* Register names.  */
+  const char **register_names;
+
+  /* Target description.  */
+  const struct target_desc *tdesc;
+
+  /* Register group function.  */
+  const void *register_reggroup_p;
+
   /* Offset of saved PC in jmp_buf.  */
   int jb_pc_offset;
 
@@ -147,10 +159,7 @@ struct gdbarch_tdep
   int sc_sp_offset;
 
   /* ISA-specific data types.  */
-  struct type *i386_eflags_type;
-  struct type *i386_mxcsr_type;
   struct type *i386_mmx_type;
-  struct type *i386_sse_type;
   struct type *i387_ext_type;
 
   /* Process record/replay target.  */
@@ -199,7 +208,8 @@ enum i386_regnum
   I386_ES_REGNUM,		/* %es */
   I386_FS_REGNUM,		/* %fs */
   I386_GS_REGNUM,		/* %gs */
-  I386_ST0_REGNUM		/* %st(0) */
+  I386_ST0_REGNUM,		/* %st(0) */
+  I386_MXCSR_REGNUM = 40	/* %mxcsr */ 
 };
 
 /* Register numbers of RECORD_REGMAP.  */
@@ -233,20 +243,14 @@ enum record_i386_regnum
 };
 
 #define I386_NUM_GREGS	16
-#define I386_NUM_FREGS	16
 #define I386_NUM_XREGS  9
 
-#define I386_SSE_NUM_REGS	(I386_NUM_GREGS + I386_NUM_FREGS \
-				 + I386_NUM_XREGS)
+#define I386_SSE_NUM_REGS	(I386_MXCSR_REGNUM + 1)
 
 /* Size of the largest register.  */
 #define I386_MAX_REGISTER_SIZE	16
 
 /* Types for i386-specific registers.  */
-extern struct type *i386_eflags_type (struct gdbarch *gdbarch);
-extern struct type *i386_mxcsr_type (struct gdbarch *gdbarch);
-extern struct type *i386_mmx_type (struct gdbarch *gdbarch);
-extern struct type *i386_sse_type (struct gdbarch *gdbarch);
 extern struct type *i387_ext_type (struct gdbarch *gdbarch);
 
 /* Segment selectors.  */
@@ -266,9 +270,6 @@ extern CORE_ADDR i386_skip_main_prologue
 /* Return whether the THIS_FRAME corresponds to a sigtramp routine.  */
 extern int i386_sigtramp_p (struct frame_info *this_frame);
 
-/* Return the name of register REGNUM.  */
-extern char const *i386_register_name (struct gdbarch * gdbarch, int regnum);
-
 /* Return non-zero if REGNUM is a member of the specified group.  */
 extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 				     struct reggroup *group);
--- ./gdb/i387-tdep.h	2010-01-01 08:31:36.000000000 +0100
+++ ./gdb/i387-tdep.h	2010-04-03 20:59:52.000000000 +0200
@@ -27,6 +27,9 @@ struct regcache;
 struct type;
 struct ui_file;
 
+/* Number of i387 floating point registers.  */
+#define I387_NUM_REGS	16
+
 #define I387_ST0_REGNUM(tdep) ((tdep)->st0_regnum)
 #define I387_NUM_XMM_REGS(tdep) ((tdep)->num_xmm_regs)
 #define I387_MM0_REGNUM(tdep) ((tdep)->mm0_regnum)
--- ./gdb/regformats/i386/amd64-linux.dat	1970-01-01 01:00:00.000000000 +0100
+++ ./gdb/regformats/i386/amd64-linux.dat	2010-04-03 20:59:52.000000000 +0200
@@ -0,0 +1,62 @@
+# DO NOT EDIT: generated from i386/amd64-linux.xml
+name:amd64_linux
+xmltarget:amd64-linux.xml
+expedite:rbp,rsp,rip
+64:rax
+64:rbx
+64:rcx
+64:rdx
+64:rsi
+64:rdi
+64:rbp
+64:rsp
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:rip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+128:xmm8
+128:xmm9
+128:xmm10
+128:xmm11
+128:xmm12
+128:xmm13
+128:xmm14
+128:xmm15
+32:mxcsr
+64:orig_rax
--- ./gdb/regformats/i386/amd64.dat	1970-01-01 01:00:00.000000000 +0100
+++ ./gdb/regformats/i386/amd64.dat	2010-04-03 20:59:52.000000000 +0200
@@ -0,0 +1,61 @@
+# DO NOT EDIT: generated from i386/amd64.xml
+name:amd64
+xmltarget:amd64.xml
+expedite:rbp,rsp,rip
+64:rax
+64:rbx
+64:rcx
+64:rdx
+64:rsi
+64:rdi
+64:rbp
+64:rsp
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:rip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+128:xmm8
+128:xmm9
+128:xmm10
+128:xmm11
+128:xmm12
+128:xmm13
+128:xmm14
+128:xmm15
+32:mxcsr
--- ./gdb/regformats/i386/i386-linux.dat	1970-01-01 01:00:00.000000000 +0100
+++ ./gdb/regformats/i386/i386-linux.dat	2010-04-03 20:59:52.000000000 +0200
@@ -0,0 +1,46 @@
+# DO NOT EDIT: generated from i386/i386-linux.xml
+name:i386_linux
+xmltarget:i386-linux.xml
+expedite:ebp,esp,eip
+32:eax
+32:ecx
+32:edx
+32:ebx
+32:esp
+32:ebp
+32:esi
+32:edi
+32:eip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+32:mxcsr
+32:orig_eax
--- ./gdb/regformats/i386/i386.dat	1970-01-01 01:00:00.000000000 +0100
+++ ./gdb/regformats/i386/i386.dat	2010-04-03 20:59:52.000000000 +0200
@@ -0,0 +1,45 @@
+# DO NOT EDIT: generated from i386/i386.xml
+name:i386
+xmltarget:i386.xml
+expedite:ebp,esp,eip
+32:eax
+32:ecx
+32:edx
+32:ebx
+32:esp
+32:ebp
+32:esi
+32:edi
+32:eip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+32:mxcsr
--- ./gdb/regformats/reg-i386-linux.dat	2009-07-20 20:51:42.000000000 +0200
+++ ./gdb/regformats/reg-i386-linux.dat	1970-01-01 01:00:00.000000000 +0100
@@ -1,46 +0,0 @@
-name:i386_linux
-xmlarch:i386
-osabi:GNU/Linux
-expedite:ebp,esp,eip
-32:eax
-32:ecx
-32:edx
-32:ebx
-32:esp
-32:ebp
-32:esi
-32:edi
-32:eip
-32:eflags
-32:cs
-32:ss
-32:ds
-32:es
-32:fs
-32:gs
-80:st0
-80:st1
-80:st2
-80:st3
-80:st4
-80:st5
-80:st6
-80:st7
-32:fctrl
-32:fstat
-32:ftag
-32:fiseg
-32:fioff
-32:foseg
-32:fooff
-32:fop
-128:xmm0
-128:xmm1
-128:xmm2
-128:xmm3
-128:xmm4
-128:xmm5
-128:xmm6
-128:xmm7
-32:mxcsr
-32:orig_eax
--- ./gdb/regformats/reg-i386.dat	2008-02-28 06:54:10.000000000 +0100
+++ ./gdb/regformats/reg-i386.dat	1970-01-01 01:00:00.000000000 +0100
@@ -1,44 +0,0 @@
-name:i386
-xmlarch:i386
-expedite:ebp,esp,eip
-32:eax
-32:ecx
-32:edx
-32:ebx
-32:esp
-32:ebp
-32:esi
-32:edi
-32:eip
-32:eflags
-32:cs
-32:ss
-32:ds
-32:es
-32:fs
-32:gs
-80:st0
-80:st1
-80:st2
-80:st3
-80:st4
-80:st5
-80:st6
-80:st7
-32:fctrl
-32:fstat
-32:ftag
-32:fiseg
-32:fioff
-32:foseg
-32:fooff
-32:fop
-128:xmm0
-128:xmm1
-128:xmm2
-128:xmm3
-128:xmm4
-128:xmm5
-128:xmm6
-128:xmm7
-32:mxcsr
--- ./gdb/regformats/reg-x86-64-linux.dat	2009-07-20 20:51:42.000000000 +0200
+++ ./gdb/regformats/reg-x86-64-linux.dat	1970-01-01 01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-name:x86_64_linux
-xmlarch:i386:x86-64
-osabi:GNU/Linux
-expedite:rbp,rsp,rip
-64:rax
-64:rbx
-64:rcx
-64:rdx
-64:rsi
-64:rdi
-64:rbp
-64:rsp
-64:r8
-64:r9
-64:r10
-64:r11
-64:r12
-64:r13
-64:r14
-64:r15
-64:rip
-32:eflags
-32:cs
-32:ss
-32:ds
-32:es
-32:fs
-32:gs
-80:st0
-80:st1
-80:st2
-80:st3
-80:st4
-80:st5
-80:st6
-80:st7
-32:fctrl
-32:fstat
-32:ftag
-32:fiseg
-32:fioff
-32:foseg
-32:fooff
-32:fop
-128:xmm0
-128:xmm1
-128:xmm2
-128:xmm3
-128:xmm4
-128:xmm5
-128:xmm6
-128:xmm7
-128:xmm8
-128:xmm9
-128:xmm10
-128:xmm11
-128:xmm12
-128:xmm13
-128:xmm14
-128:xmm15
-32:mxcsr
-64:orig_rax
--- ./gdb/regformats/reg-x86-64.dat	2004-01-10 13:52:41.000000000 +0100
+++ ./gdb/regformats/reg-x86-64.dat	1970-01-01 01:00:00.000000000 +0100
@@ -1,59 +0,0 @@
-name:x86_64
-expedite:rbp,rsp,rip
-64:rax
-64:rbx
-64:rcx
-64:rdx
-64:rsi
-64:rdi
-64:rbp
-64:rsp
-64:r8
-64:r9
-64:r10
-64:r11
-64:r12
-64:r13
-64:r14
-64:r15
-64:rip
-32:eflags
-32:cs
-32:ss
-32:ds
-32:es
-32:fs
-32:gs
-80:st0
-80:st1
-80:st2
-80:st3
-80:st4
-80:st5
-80:st6
-80:st7
-32:fctrl
-32:fstat
-32:ftag
-32:fiseg
-32:fioff
-32:foseg
-32:fooff
-32:fop
-128:xmm0
-128:xmm1
-128:xmm2
-128:xmm3
-128:xmm4
-128:xmm5
-128:xmm6
-128:xmm7
-128:xmm8
-128:xmm9
-128:xmm10
-128:xmm11
-128:xmm12
-128:xmm13
-128:xmm14
-128:xmm15
-32:mxcsr
--- ./gdb/testsuite/gdb.xml/tdesc-regs.exp	2010-02-16 22:26:48.000000000 +0100
+++ ./gdb/testsuite/gdb.xml/tdesc-regs.exp	2010-04-03 20:59:52.000000000 +0200
@@ -25,6 +25,7 @@ gdb_start
 
 set core-regs ""
 set regdir ""
+set architecture ""
 switch -glob -- [istarget] {
     "*arm-*-*" {
         set core-regs {arm-core.xml}
@@ -55,6 +56,16 @@ switch -glob -- [istarget] {
 	unsupported "register tests"
 	return 0
     }
+    "i?86-*-*" {
+	set architecture "i386"
+	set regdir "i386/"
+        set core-regs {32bit-core.xml 32bit-sse.xml}
+    }
+    "x86_64-*-*" {
+	set architecture "i386:x86-64"
+	set regdir "i386/"
+        set core-regs {64bit-core.xml 64bit-sse.xml}
+    }
 }
 
 # If no core registers were specified, assume this target does not
@@ -89,12 +100,16 @@ proc load_description { file errmsg } {
     global subdir
     global gdb_prompt
     global core-regs
+    global architecture
 
     file delete "$subdir/regs.xml"
     set ifd [open "$srcdir/$subdir/$file" r]
     set ofd [open "$subdir/regs.xml" w]
     while {[gets $ifd line] >= 0} {
 	if {[regexp {<xi:include href="core-regs.xml"/>} $line]} {
+	    if {! [string equal ${architecture} ""]} {
+		puts $ofd "  <architecture>${architecture}</architecture>"
+	    }
 	    foreach src ${core-regs} {
 		puts $ofd "  <xi:include href=\"$src\"/>"
 	    }

gdb-bz578250-avx-02of10.patch:
 doc/gdb.texinfo                  |   41 ++++++++
 features/gdb-target.dtd          |   17 +++
 gdbtypes.c                       |   19 +++
 gdbtypes.h                       |    2 
 target-descriptions.c            |  192 ++++++++++++++++++++++++++++++++++++++-
 target-descriptions.h            |   10 ++
 testsuite/gdb.xml/extra-regs.xml |   18 +++
 testsuite/gdb.xml/tdesc-regs.exp |    5 +
 xml-tdesc.c                      |  164 ++++++++++++++++++++++++++++++---
 9 files changed, 442 insertions(+), 26 deletions(-)

--- NEW FILE gdb-bz578250-avx-02of10.patch ---
[ Backported.  ]

commit cb928c67c90cfb5bbb0636d91855b95e51ad275d
Author: Daniel Jacobowitz <dan at debian.org>
Date:   Mon Mar 1 17:19:21 2010 +0000

    	* gdbtypes.c (append_composite_type_field_raw): New.
    	(append_composite_type_field_aligned): Use the new function.
    	* gdbtypes.h (append_composite_type_field_raw): Declare.
    	* target-descriptions.c (struct tdesc_type_field): Add start and end.
    	(struct tdesc_type_flag): New type.
    	(struct tdesc_type): Add TDESC_TYPE_STRUCT and TDESC_TYPE_FLAGS to
    	kind.  Add size to u.u.  Add u.f for flags.
    	(tdesc_gdb_type): Handle TDESC_TYPE_STRUCT and TDESC_TYPE_FLAGS.
    	(tdesc_free_type): Likewise.
    	(tdesc_create_struct, tdesc_set_struct_size, tdesc_create_flags): New.
    	(tdesc_add_field): Handle TDESC_TYPE_STRUCT.
    	(tdesc_add_bitfield, tdesc_add_flag): New.
    	* target-descriptions.h (tdesc_create_struct, tdesc_set_struct_size)
    	(tdesc_create_flags, tdesc_add_bitfield, tdesc_add_flag): Declare.
    	* xml-tdesc.c (struct tdesc_parsing_data): Rename current_union to
    	current_type.  Add current_type_size and current_type_is_flags.
    	(tdesc_start_union): Clear the new fields.
    	(tdesc_start_struct, tdesc_start_flags): New.
    	(tdesc_start_field): Handle struct fields, including bitfields.
    	(field_attributes): Make type optional.  Add start and end.
    	(union_children): Rename to struct_union_children.
    	(union_attributes): Rename to struct_union_attributes.  Add optional
    	size.
    	(flags_attributes): New.
    	(feature_children): Add struct and flags.
    	* features/gdb-target.dtd: Add flags and struct to features.
    	Make field type optional.  Add field start and end.
    
    	doc/
    	* gdb.texinfo (Types): Describe <struct> and <flags>.
    
    	testsuite/
    	* gdb.xml/extra-regs.xml: Add struct1, struct2, and flags
    	types.  Add structreg, bitfields, and flags registers.
    	* gdb.xml/tdesc-regs.exp: Test structreg and bitfields
    	registers.

--- gdb-7.1-p0/gdb/doc/gdb.texinfo	2010-04-03 20:24:51.000000000 +0200
+++ gdb-7.1/gdb/doc/gdb.texinfo	2010-04-03 21:04:13.000000000 +0200
@@ -33115,6 +33115,47 @@ each of which has a @var{name} and a @va
 </union>
 @end smallexample
 
+ at cindex <struct>
+If a register's value is composed from several separate values, define
+it with a structure type.  There are two forms of the @samp{<struct>}
+element; a @samp{<struct>} element must either contain only bitfields
+or contain no bitfields.  If the structure contains only bitfields,
+its total size in bytes must be specified, each bitfield must have an
+explicit start and end, and bitfields are automatically assigned an
+integer type.  The field's @var{start} should be less than or
+equal to its @var{end}, and zero represents the least significant bit.
+
+ at smallexample
+<struct id="@var{id}" size="@var{size}">
+  <field name="@var{name}" start="@var{start}" end="@var{end}"/>
+  @dots{}
+</struct>
+ at end smallexample
+
+If the structure contains no bitfields, then each field has an
+explicit type, and no implicit padding is added.
+
+ at smallexample
+<struct id="@var{id}">
+  <field name="@var{name}" type="@var{type}"/>
+  @dots{}
+</struct>
+ at end smallexample
+
+ at cindex <flags>
+If a register's value is a series of single-bit flags, define it with
+a flags type.  The @samp{<flags>} element has an explicit @var{size}
+and contains one or more @samp{<field>} elements.  Each field has a
+ at var{name}, a @var{start}, and an @var{end}.  Only single-bit flags
+are supported.
+
+ at smallexample
+<flags id="@var{id}" size="@var{size}">
+  <field name="@var{name}" start="@var{start}" end="@var{end}"/>
+  @dots{}
+</flags>
+ at end smallexample
+
 @subsection Registers
 @cindex <reg>
 
--- gdb-7.1-p0/gdb/features/gdb-target.dtd	2010-01-01 08:31:48.000000000 +0100
+++ gdb-7.1/gdb/features/gdb-target.dtd	2010-04-03 21:04:13.000000000 +0200
@@ -19,7 +19,8 @@
 
 <!ELEMENT compatible	(#PCDATA)>
 
-<!ELEMENT feature	((vector | union)*, reg*)>
+<!ELEMENT feature
+	((vector | flags | struct | union )*, reg*)>
 <!ATTLIST feature
 	name		ID	#REQUIRED>
 
@@ -39,6 +40,16 @@
 	type		CDATA	#REQUIRED
 	count		CDATA	#REQUIRED>
 
+<!ELEMENT flags		(field+)>
+<!ATTLIST flags
+	id		CDATA	#REQUIRED
+	size		CDATA	#REQUIRED>
+
+<!ELEMENT struct	(field+)>
+<!ATTLIST struct
+	id		CDATA	#REQUIRED
+	size		CDATA	#IMPLIED>
+
 <!ELEMENT union		(field+)>
 <!ATTLIST union
 	id		CDATA	#REQUIRED>
@@ -46,7 +57,9 @@
 <!ELEMENT field		EMPTY>
 <!ATTLIST field
 	name		CDATA	#REQUIRED
-	type		CDATA	#REQUIRED>
+	type		CDATA	#IMPLIED
+	start		CDATA	#IMPLIED
+	end		CDATA	#IMPLIED>
 
 <!ENTITY % xinclude SYSTEM "xinclude.dtd">
 %xinclude;
--- gdb-7.1-p0/gdb/gdbtypes.c	2010-04-03 20:24:51.000000000 +0200
+++ gdb-7.1/gdb/gdbtypes.c	2010-04-03 21:04:13.000000000 +0200
@@ -3798,10 +3798,11 @@ arch_composite_type (struct gdbarch *gdb
 }
 
 /* Add new field with name NAME and type FIELD to composite type T.
-   ALIGNMENT (if non-zero) specifies the minimum field alignment.  */
-void
-append_composite_type_field_aligned (struct type *t, char *name,
-				     struct type *field, int alignment)
+   Do not set the field's position or adjust the type's length;
+   the caller should do so.  Return the new field.  */
+struct field *
+append_composite_type_field_raw (struct type *t, char *name,
+				 struct type *field)
 {
   struct field *f;
   TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1;
@@ -3811,6 +3812,16 @@ append_composite_type_field_aligned (str
   memset (f, 0, sizeof f[0]);
   FIELD_TYPE (f[0]) = field;
   FIELD_NAME (f[0]) = name;
+  return f;
+}
+
+/* Add new field with name NAME and type FIELD to composite type T.
+   ALIGNMENT (if non-zero) specifies the minimum field alignment.  */
+void
+append_composite_type_field_aligned (struct type *t, char *name,
+				     struct type *field, int alignment)
+{
+  struct field *f = append_composite_type_field_raw (t, name, field);
   if (TYPE_CODE (t) == TYPE_CODE_UNION)
     {
       if (TYPE_LENGTH (t) < TYPE_LENGTH (field))
--- gdb-7.1-p0/gdb/gdbtypes.h	2010-04-03 20:24:51.000000000 +0200
+++ gdb-7.1/gdb/gdbtypes.h	2010-04-03 21:04:13.000000000 +0200
@@ -1395,6 +1395,8 @@ extern void append_composite_type_field_
 						 char *name,
 						 struct type *field,
 						 int alignment);
+struct field *append_composite_type_field_raw (struct type *t, char *name,
+					       struct type *field);
 
 /* Helper functions to construct a bit flags type.  An initially empty
    type is created using arch_flag_type().  Flags are then added using
--- gdb-7.1-p0/gdb/target-descriptions.c	2010-02-10 19:45:02.000000000 +0100
+++ gdb-7.1/gdb/target-descriptions.c	2010-04-03 21:04:13.000000000 +0200
@@ -90,9 +90,17 @@ typedef struct tdesc_type_field
 {
   char *name;
   struct tdesc_type *type;
+  int start, end;
 } tdesc_type_field;
 DEF_VEC_O(tdesc_type_field);
 
+typedef struct tdesc_type_flag
+{
+  char *name;
+  int start;
+} tdesc_type_flag;
+DEF_VEC_O(tdesc_type_flag);
+
 typedef struct tdesc_type
 {
   /* The name of this type.  */
@@ -123,7 +131,9 @@ typedef struct tdesc_type
 
     /* Types defined by a target feature.  */
     TDESC_TYPE_VECTOR,
-    TDESC_TYPE_UNION
+    TDESC_TYPE_STRUCT,
+    TDESC_TYPE_UNION,
+    TDESC_TYPE_FLAGS
   } kind;
 
   /* Kind-specific data.  */
@@ -136,11 +146,19 @@ typedef struct tdesc_type
       int count;
     } v;
 
-    /* Union type.  */
+    /* Struct or union type.  */
     struct
     {
       VEC(tdesc_type_field) *fields;
+      LONGEST size;
     } u;
+
+    /* Flags type.  */
+    struct
+    {
+      VEC(tdesc_type_flag) *flags;
+      LONGEST size;
+    } f;
   } u;
 } *tdesc_type_p;
 DEF_VEC_P(tdesc_type_p);
@@ -652,6 +670,66 @@ tdesc_gdb_type (struct gdbarch *gdbarch,
 	return type;
       }
 
+    case TDESC_TYPE_STRUCT:
+      {
+	struct type *type, *field_type;
+	struct tdesc_type_field *f;
+	int ix;
+
+	type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+	TYPE_NAME (type) = xstrdup (tdesc_type->name);
+	TYPE_TAG_NAME (type) = TYPE_NAME (type);
+
+	for (ix = 0;
+	     VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
+	     ix++)
+	  {
+	    if (f->type == NULL)
+	      {
+		/* Bitfield.  */
+		struct field *fld;
+		struct type *field_type;
+		int bitsize, total_size;
+
+		/* This invariant should be preserved while creating
+		   types.  */
+		gdb_assert (tdesc_type->u.u.size != 0);
+		if (tdesc_type->u.u.size > 4)
+		  field_type = builtin_type (gdbarch)->builtin_uint64;
+		else
+		  field_type = builtin_type (gdbarch)->builtin_uint32;
+
+		fld = append_composite_type_field_raw (type, xstrdup (f->name),
+						       field_type);
+
+		/* For little-endian, BITPOS counts from the LSB of
+		   the structure and marks the LSB of the field.  For
+		   big-endian, BITPOS counts from the MSB of the
+		   structure and marks the MSB of the field.  Either
+		   way, it is the number of bits to the "left" of the
+		   field.  To calculate this in big-endian, we need
+		   the total size of the structure.  */
+		bitsize = f->end - f->start + 1;
+		total_size = tdesc_type->u.u.size * TARGET_CHAR_BIT;
+		if (gdbarch_bits_big_endian (gdbarch))
+		  FIELD_BITPOS (fld[0]) = total_size - f->start - bitsize;
+		else
+		  FIELD_BITPOS (fld[0]) = f->start;
+		FIELD_BITSIZE (fld[0]) = bitsize;
+	      }
+	    else
+	      {
+		field_type = tdesc_gdb_type (gdbarch, f->type);
+		append_composite_type_field (type, xstrdup (f->name),
+					     field_type);
+	      }
+	  }
+
+	if (tdesc_type->u.u.size != 0)
+	  TYPE_LENGTH (type) = tdesc_type->u.u.size;
+	return type;
+      }
+
     case TDESC_TYPE_UNION:
       {
 	struct type *type, *field_type;
@@ -668,12 +746,30 @@ tdesc_gdb_type (struct gdbarch *gdbarch,
 	    field_type = tdesc_gdb_type (gdbarch, f->type);
 	    append_composite_type_field (type, xstrdup (f->name), field_type);
 
-	    /* If any of the children of this union are vectors, flag the
+	    /* If any of the children of a union are vectors, flag the
 	       union as a vector also.  This allows e.g. a union of two
 	       vector types to show up automatically in "info vector".  */
 	    if (TYPE_VECTOR (field_type))
 	      TYPE_VECTOR (type) = 1;
 	  }
+	return type;
+      }
+
+    case TDESC_TYPE_FLAGS:
+      {
+	struct type *type, *field_type;
+	struct tdesc_type_flag *f;
+	int ix;
+
+	type = arch_flags_type (gdbarch, xstrdup (tdesc_type->name),
+				tdesc_type->u.f.size);
+	for (ix = 0;
+	     VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, ix, f);
+	     ix++)
+	  /* Note that contrary to the function name, this call will
+	     just set the properties of an already-allocated
+	     field.  */
+	  append_flags_type_flag (type, f->start, f->name);
 
 	return type;
       }
@@ -1161,6 +1257,7 @@ tdesc_free_type (struct tdesc_type *type
 
   switch (type->kind)
     {
+    case TDESC_TYPE_STRUCT:
     case TDESC_TYPE_UNION:
       {
 	struct tdesc_type_field *f;
@@ -1175,6 +1272,20 @@ tdesc_free_type (struct tdesc_type *type
       }
       break;
 
+    case TDESC_TYPE_FLAGS:
+      {
+	struct tdesc_type_flag *f;
+	int ix;
+
+	for (ix = 0;
+	     VEC_iterate (tdesc_type_flag, type->u.f.flags, ix, f);
+	     ix++)
+	  xfree (f->name);
+
+	VEC_free (tdesc_type_flag, type->u.f.flags);
+      }
+      break;
+
     default:
       break;
     }
@@ -1199,6 +1310,29 @@ tdesc_create_vector (struct tdesc_featur
 }
 
 struct tdesc_type *
+tdesc_create_struct (struct tdesc_feature *feature, const char *name)
+{
+  struct tdesc_type *type = XZALLOC (struct tdesc_type);
+
+  type->name = xstrdup (name);
+  type->kind = TDESC_TYPE_STRUCT;
+
+  VEC_safe_push (tdesc_type_p, feature->types, type);
+  return type;
+}
+
+/* Set the total length of TYPE.  Structs which contain bitfields may
+   omit the reserved bits, so the end of the last field may not
+   suffice.  */
+
+void
+tdesc_set_struct_size (struct tdesc_type *type, LONGEST size)
+{
+  gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+  type->u.u.size = size;
+}
+
+struct tdesc_type *
 tdesc_create_union (struct tdesc_feature *feature, const char *name)
 {
   struct tdesc_type *type = XZALLOC (struct tdesc_type);
@@ -1210,13 +1344,32 @@ tdesc_create_union (struct tdesc_feature
   return type;
 }
 
+struct tdesc_type *
+tdesc_create_flags (struct tdesc_feature *feature, const char *name,
+		    LONGEST size)
+{
+  struct tdesc_type *type = XZALLOC (struct tdesc_type);
+
+  type->name = xstrdup (name);
+  type->kind = TDESC_TYPE_FLAGS;
+  type->u.f.size = size;
+
+  VEC_safe_push (tdesc_type_p, feature->types, type);
+  return type;
+}
+
+/* Add a new field.  Return a temporary pointer to the field, which
+   is only valid until the next call to tdesc_add_field (the vector
+   might be reallocated).  */
+
 void
 tdesc_add_field (struct tdesc_type *type, const char *field_name,
 		 struct tdesc_type *field_type)
 {
   struct tdesc_type_field f = { 0 };
 
-  gdb_assert (type->kind == TDESC_TYPE_UNION);
+  gdb_assert (type->kind == TDESC_TYPE_UNION
+	      || type->kind == TDESC_TYPE_STRUCT);
 
   f.name = xstrdup (field_name);
   f.type = field_type;
@@ -1224,6 +1377,37 @@ tdesc_add_field (struct tdesc_type *type
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
+/* Add a new bitfield.  */
+
+void
+tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+		    int start, int end)
+{
+  struct tdesc_type_field f = { 0 };
+
+  gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+
+  f.name = xstrdup (field_name);
+  f.start = start;
+  f.end = end;
+
+  VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
+}
+
+void
+tdesc_add_flag (struct tdesc_type *type, int start,
+		const char *flag_name)
+{
+  struct tdesc_type_flag f = { 0 };
+
+  gdb_assert (type->kind == TDESC_TYPE_FLAGS);
+
+  f.name = xstrdup (flag_name);
+  f.start = start;
+
+  VEC_safe_push (tdesc_type_flag, type->u.f.flags, &f);
+}
+
 static void
 tdesc_free_feature (struct tdesc_feature *feature)
 {
--- gdb-7.1-p0/gdb/target-descriptions.h	2010-02-10 19:45:03.000000000 +0100
+++ gdb-7.1/gdb/target-descriptions.h	2010-04-03 21:04:13.000000000 +0200
@@ -205,10 +205,20 @@ struct tdesc_type *tdesc_create_vector (
 					const char *name,
 					struct tdesc_type *field_type,
 					int count);
+struct tdesc_type *tdesc_create_struct (struct tdesc_feature *feature,
+					const char *name);
+void tdesc_set_struct_size (struct tdesc_type *type, LONGEST size);
 struct tdesc_type *tdesc_create_union (struct tdesc_feature *feature,
 				       const char *name);
+struct tdesc_type *tdesc_create_flags (struct tdesc_feature *feature,
+				       const char *name,
+				       LONGEST size);
 void tdesc_add_field (struct tdesc_type *type, const char *field_name,
 		      struct tdesc_type *field_type);
+void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+			 int start, int end);
+void tdesc_add_flag (struct tdesc_type *type, int start,
+		     const char *flag_name);
 void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
 		       int regnum, int save_restore, const char *group,
 		       int bitsize, const char *type);
--- gdb-7.1-p0/gdb/testsuite/gdb.xml/extra-regs.xml	2007-02-08 22:00:36.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.xml/extra-regs.xml	2010-04-03 21:04:13.000000000 +0200
@@ -8,9 +8,27 @@
       <field name="v2" type="v2int16"/>
     </union>
 
+    <struct id="struct1">
+      <field name="v4" type="v4int8"/>
+      <field name="v2" type="v2int16"/>
+    </struct>
+
+    <struct id="struct2" size="8">
+      <field name="f1" start="0" end="34"/>
+      <field name="f2" start="63" end="63"/>
+    </struct>
+
+    <flags id="flags" size="4">
+      <field name="X" start="0" end="0"/>
+      <field name="Y" start="2" end="2"/>
+    </flags>
+
     <reg name="extrareg" bitsize="32"/>
     <reg name="uintreg" bitsize="32" type="uint32"/>
     <reg name="vecreg" bitsize="32" type="v4int8"/>
     <reg name="unionreg" bitsize="32" type="vecint"/>
+    <reg name="structreg" bitsize="64" type="struct1"/>
+    <reg name="bitfields" bitsize="64" type="struct2"/>
+    <reg name="flags" bitsize="32" type="flags"/>
   </feature>
 </target>
--- gdb-7.1-p0/gdb/testsuite/gdb.xml/tdesc-regs.exp	2010-04-03 20:59:52.000000000 +0200
+++ gdb-7.1/gdb/testsuite/gdb.xml/tdesc-regs.exp	2010-04-03 21:04:13.000000000 +0200
@@ -141,6 +141,11 @@ gdb_test "ptype \$vecreg" "type = int8_t
 gdb_test "ptype \$unionreg" \
     "type = union {\r\n *v4int8 v4;\r\n *v2int16 v2;\r\n}"
 gdb_test "ptype \$unionreg.v4" "type = int8_t \\\[4\\\]"
+gdb_test "ptype \$structreg" \
+    "type = struct struct1 {\r\n *v4int8 v4;\r\n *v2int16 v2;\r\n}"
+gdb_test "ptype \$structreg.v4" "type = int8_t \\\[4\\\]"
+gdb_test "ptype \$bitfields" \
+    "type = struct struct2 {\r\n *uint64_t f1 : 35;\r\n *uint64_t f2 : 1;\r\n}"
 
 load_description "core-only.xml" ""
 # The extra register from the previous description should be gone.
--- gdb-7.1-p0/gdb/xml-tdesc.c	2010-01-01 08:31:46.000000000 +0100
+++ gdb-7.1/gdb/xml-tdesc.c	2010-04-03 21:04:13.000000000 +0200
@@ -85,8 +85,15 @@ struct tdesc_parsing_data
      it does not have its own.  This starts at zero.  */
   int next_regnum;
 
-  /* The union we are currently parsing, or last parsed.  */
-  struct tdesc_type *current_union;
+  /* The struct or union we are currently parsing, or last parsed.  */
+  struct tdesc_type *current_type;
+
+  /* The byte size of the current struct type, if specified.  Zero
+     if not specified.  */
+  int current_type_size;
+
+  /* Whether the current type is a flags type.  */
+  int current_type_is_flags;
 };
 
 /* Handle the end of an <architecture> element and its value.  */
@@ -229,11 +236,57 @@ tdesc_start_union (struct gdb_xml_parser
   struct tdesc_parsing_data *data = user_data;
   char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
 
-  data->current_union = tdesc_create_union (data->current_feature, id);
+  data->current_type = tdesc_create_union (data->current_feature, id);
+  data->current_type_size = 0;
+  data->current_type_is_flags = 0;
+}
+
+/* Handle the start of a <struct> element.  Initialize the type and
+   record it with the current feature.  */
+
+static void
+tdesc_start_struct (struct gdb_xml_parser *parser,
+		   const struct gdb_xml_element *element,
+		   void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  struct tdesc_parsing_data *data = user_data;
+  char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
+  struct tdesc_type *type;
+
+  type = tdesc_create_struct (data->current_feature, id);
+  data->current_type = type;
+  data->current_type_size = 0;
+  data->current_type_is_flags = 0;
+
+  if (VEC_length (gdb_xml_value_s, attributes) > 1)
+    {
+      int size = (int) * (ULONGEST *)
+	VEC_index (gdb_xml_value_s, attributes, 1)->value;
+      tdesc_set_struct_size (type, size);
+      data->current_type_size = size;
+    }
+}
+
+static void
+tdesc_start_flags (struct gdb_xml_parser *parser,
+		   const struct gdb_xml_element *element,
+		   void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  struct tdesc_parsing_data *data = user_data;
+  char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
+  int length = (int) * (ULONGEST *)
+    VEC_index (gdb_xml_value_s, attributes, 1)->value;
+  struct tdesc_type *type;
+
+  type = tdesc_create_flags (data->current_feature, id, length);
+
+  data->current_type = type;
+  data->current_type_size = 0;
+  data->current_type_is_flags = 1;
 }
 
 /* Handle the start of a <field> element.  Attach the field to the
-   current union.  */
+   current struct or union.  */
 
 static void
 tdesc_start_field (struct gdb_xml_parser *parser,
@@ -241,20 +294,84 @@ tdesc_start_field (struct gdb_xml_parser
 		   void *user_data, VEC(gdb_xml_value_s) *attributes)
 {
   struct tdesc_parsing_data *data = user_data;
+  int ix = 0, length;
   struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
   struct tdesc_type *field_type;
   char *field_name, *field_type_id;
+  int start, end;
 
-  field_name = attrs[0].value;
-  field_type_id = attrs[1].value;
+  length = VEC_length (gdb_xml_value_s, attributes);
 
-  field_type = tdesc_named_type (data->current_feature, field_type_id);
-  if (field_type == NULL)
-    gdb_xml_error (parser, _("Union field \"%s\" references undefined "
-			     "type \"%s\""),
-		   field_name, field_type_id);
+  field_name = attrs[ix++].value;
+
+  if (ix < length && strcmp (attrs[ix].name, "type") == 0)
+    field_type_id = attrs[ix++].value;
+  else
+    field_type_id = NULL;
+
+  if (ix < length && strcmp (attrs[ix].name, "start") == 0)
+    start = * (ULONGEST *) attrs[ix++].value;
+  else
+    start = -1;
+
+  if (ix < length && strcmp (attrs[ix].name, "end") == 0)
+    end = * (ULONGEST *) attrs[ix++].value;
+  else
+    end = -1;
+
+  if (field_type_id != NULL)
+    {
+      if (data->current_type_is_flags)
+	gdb_xml_error (parser, _("Cannot add typed field \"%s\" to flags"), 
+		       field_name);
+      if (data->current_type_size != 0)
+	gdb_xml_error (parser,
+		       _("Explicitly sized type can not contain non-bitfield \"%s\""), 
+		       field_name);
+
+      field_type = tdesc_named_type (data->current_feature, field_type_id);
+      if (field_type == NULL)
+	gdb_xml_error (parser, _("Field \"%s\" references undefined "
+				 "type \"%s\""),
+		       field_name, field_type_id);
+
+      tdesc_add_field (data->current_type, field_name, field_type);
+    }
+  else if (start != -1 && end != -1)
+    {
+      struct tdesc_type *t = data->current_type;
+
+      if (data->current_type_is_flags)
+	tdesc_add_flag (t, start, field_name);
+      else
+	{
+	  if (data->current_type_size == 0)
+	    gdb_xml_error (parser,
+			   _("Implicitly sized type can not contain bitfield \"%s\""), 
+			   field_name);
+
+	  if (end >= 64)
+	    gdb_xml_error (parser,
+			   _("Bitfield \"%s\" goes past 64 bits (unsupported)"),
+			   field_name);
+
+	  /* Assume that the bit numbering in XML is "lsb-zero".  Most
+	     architectures other than PowerPC use this ordering.  In
+	     the future, we can add an XML tag to indicate "msb-zero"
+	     numbering.  */
+	  if (start > end)
+	    gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"),
+			   field_name);
 
-  tdesc_add_field (data->current_union, field_name, field_type);
+	  if (end >= data->current_type_size * TARGET_CHAR_BIT)
+	    gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct"));
+
+	  tdesc_add_bitfield (t, field_name, start, end);
+	}
+    }
+  else
+    gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"),
+		   field_name);
 }
 
 /* Handle the start of a <vector> element.  Initialize the type and
@@ -287,11 +404,13 @@ tdesc_start_vector (struct gdb_xml_parse
 
 static const struct gdb_xml_attribute field_attributes[] = {
   { "name", GDB_XML_AF_NONE, NULL, NULL },
-  { "type", GDB_XML_AF_NONE, NULL, NULL },
+  { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
+  { "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
-static const struct gdb_xml_element union_children[] = {
+static const struct gdb_xml_element struct_union_children[] = {
   { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
     tdesc_start_field, NULL },
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
@@ -308,8 +427,15 @@ static const struct gdb_xml_attribute re
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
-static const struct gdb_xml_attribute union_attributes[] = {
+static const struct gdb_xml_attribute struct_union_attributes[] = {
   { "id", GDB_XML_AF_NONE, NULL, NULL },
+  { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute flags_attributes[] = {
+  { "id", GDB_XML_AF_NONE, NULL, NULL },
+  { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
@@ -329,9 +455,15 @@ static const struct gdb_xml_element feat
   { "reg", reg_attributes, NULL,
     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
     tdesc_start_reg, NULL },
-  { "union", union_attributes, union_children,
+  { "struct", struct_union_attributes, struct_union_children,
+    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+    tdesc_start_struct, NULL },
+  { "union", struct_union_attributes, struct_union_children,
     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
     tdesc_start_union, NULL },
+  { "flags", flags_attributes, struct_union_children,
+    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+    tdesc_start_flags, NULL },    
   { "vector", vector_attributes, NULL,
     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
     tdesc_start_vector, NULL },

gdb-bz578250-avx-03of10.patch:
 features/i386/32bit-core.xml |   20 +++++++++++
 features/i386/32bit-sse.xml  |   16 +++++++++
 features/i386/64bit-core.xml |   20 +++++++++++
 features/i386/64bit-sse.xml  |   16 +++++++++
 features/i386/amd64-linux.c  |   35 ++++++++++++++++++++
 features/i386/amd64.c        |   35 ++++++++++++++++++++
 features/i386/i386-linux.c   |   35 ++++++++++++++++++++
 features/i386/i386.c         |   35 ++++++++++++++++++++
 target-descriptions.c        |   73 +++++++++----------------------------------
 9 files changed, 228 insertions(+), 57 deletions(-)

--- NEW FILE gdb-bz578250-avx-03of10.patch ---
[ Backported.  ]

commit 0257d639d42f896a359993ae8adb5792e280f65f
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Mon Mar 1 17:26:02 2010 +0000

    Remove TDESC_TYPE_I386_EFLAGS and TDESC_TYPE_I386_MXCSR.
    
    2010-03-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* target-descriptions.c (tdesc_type): Remove
    	TDESC_TYPE_I386_EFLAGS and TDESC_TYPE_I386_MXCSR.
    	(tdesc_predefined_types): Likewise.
    	(tdesc_gdb_type): Likewise.  Pass NULL to append_flags_type_flag
    	if flag name is empty.
    	(maint_print_c_tdesc_cmd): Handle TDESC_TYPE_FLAGS.
    
    	* features/i386/32bit-core.xml: Define i386_eflags.
    	* features/i386/64bit-core.xml: Likewise.
    
    	* features/i386/32bit-sse.xml: Define i386_mxcsr.
    	* features/i386/64bit-sse.xml: Likewise.
    
    	* features/i386/amd64-linux.c: Regenerated.
    	* features/i386/amd64.c: Likewise.
    	* features/i386/i386-linux.c: Likewise.
    	* features/i386/i386.c: Likewise.

--- gdb-7.1-p1/gdb/features/i386/32bit-core.xml	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/32bit-core.xml	2010-04-03 21:06:12.000000000 +0200
@@ -7,6 +7,26 @@
 
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.core">
+  <flags id="i386_eflags" size="4">
+    <field name="CF" start="0" end="0"/>
+    <field name="" start="1" end="1"/>
+    <field name="PF" start="2" end="2"/>
+    <field name="AF" start="4" end="4"/>
+    <field name="ZF" start="6" end="6"/>
+    <field name="SF" start="7" end="7"/>
+    <field name="TF" start="8" end="8"/>
+    <field name="IF" start="9" end="9"/>
+    <field name="DF" start="10" end="10"/>
+    <field name="OF" start="11" end="11"/>
+    <field name="NT" start="14" end="14"/>
+    <field name="RF" start="16" end="16"/>
+    <field name="VM" start="17" end="17"/>
+    <field name="AC" start="18" end="18"/>
+    <field name="VIF" start="19" end="19"/>
+    <field name="VIP" start="20" end="20"/>
+    <field name="ID" start="21" end="21"/>
+  </flags>
+
   <reg name="eax" bitsize="32" type="int32"/>
   <reg name="ecx" bitsize="32" type="int32"/>
   <reg name="edx" bitsize="32" type="int32"/>
--- gdb-7.1-p1/gdb/features/i386/32bit-sse.xml	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/32bit-sse.xml	2010-04-03 21:06:12.000000000 +0200
@@ -22,6 +22,22 @@
     <field name="v2_int64" type="v2i64"/>
     <field name="uint128" type="uint128"/>
   </union>
+  <flags id="i386_mxcsr" size="4">
+    <field name="IE" start="0" end="0"/>
+    <field name="DE" start="1" end="1"/>
+    <field name="ZE" start="2" end="2"/>
+    <field name="OE" start="3" end="3"/>
+    <field name="UE" start="4" end="4"/>
+    <field name="PE" start="5" end="5"/>
+    <field name="DAZ" start="6" end="6"/>
+    <field name="IM" start="7" end="7"/>
+    <field name="DM" start="8" end="8"/>
+    <field name="ZM" start="9" end="9"/>
+    <field name="OM" start="10" end="10"/>
+    <field name="UM" start="11" end="11"/>
+    <field name="PM" start="12" end="12"/>
+    <field name="FZ" start="15" end="15"/>
+  </flags>
 
   <reg name="xmm0" bitsize="128" type="vec128" regnum="32"/>
   <reg name="xmm1" bitsize="128" type="vec128"/>
--- gdb-7.1-p1/gdb/features/i386/64bit-core.xml	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/64bit-core.xml	2010-04-03 21:06:12.000000000 +0200
@@ -7,6 +7,26 @@
 
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.core">
+  <flags id="i386_eflags" size="4">
+    <field name="CF" start="0" end="0"/>
+    <field name="" start="1" end="1"/>
+    <field name="PF" start="2" end="2"/>
+    <field name="AF" start="4" end="4"/>
+    <field name="ZF" start="6" end="6"/>
+    <field name="SF" start="7" end="7"/>
+    <field name="TF" start="8" end="8"/>
+    <field name="IF" start="9" end="9"/>
+    <field name="DF" start="10" end="10"/>
+    <field name="OF" start="11" end="11"/>
+    <field name="NT" start="14" end="14"/>
+    <field name="RF" start="16" end="16"/>
+    <field name="VM" start="17" end="17"/>
+    <field name="AC" start="18" end="18"/>
+    <field name="VIF" start="19" end="19"/>
+    <field name="VIP" start="20" end="20"/>
+    <field name="ID" start="21" end="21"/>
+  </flags>
+
   <reg name="rax" bitsize="64" type="int64"/>
   <reg name="rbx" bitsize="64" type="int64"/>
   <reg name="rcx" bitsize="64" type="int64"/>
--- gdb-7.1-p1/gdb/features/i386/64bit-sse.xml	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/64bit-sse.xml	2010-04-03 21:06:12.000000000 +0200
@@ -22,6 +22,22 @@
     <field name="v2_int64" type="v2i64"/>
     <field name="uint128" type="uint128"/>
   </union>
+  <flags id="i386_mxcsr" size="4">
+    <field name="IE" start="0" end="0"/>
+    <field name="DE" start="1" end="1"/>
+    <field name="ZE" start="2" end="2"/>
+    <field name="OE" start="3" end="3"/>
+    <field name="UE" start="4" end="4"/>
+    <field name="PE" start="5" end="5"/>
+    <field name="DAZ" start="6" end="6"/>
+    <field name="IM" start="7" end="7"/>
+    <field name="DM" start="8" end="8"/>
+    <field name="ZM" start="9" end="9"/>
+    <field name="OM" start="10" end="10"/>
+    <field name="UM" start="11" end="11"/>
+    <field name="PM" start="12" end="12"/>
+    <field name="FZ" start="15" end="15"/>
+  </flags>
 
   <reg name="xmm0" bitsize="128" type="vec128" regnum="40"/>
   <reg name="xmm1" bitsize="128" type="vec128"/>
--- gdb-7.1-p1/gdb/features/i386/amd64-linux.c	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/amd64-linux.c	2010-04-03 21:06:12.000000000 +0200
@@ -17,6 +17,25 @@ initialize_tdesc_amd64_linux (void)
   set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+  field_type = tdesc_create_flags (feature, "i386_eflags", 4);
+  tdesc_add_flag (field_type, 0, "CF");
+  tdesc_add_flag (field_type, 1, "");
+  tdesc_add_flag (field_type, 2, "PF");
+  tdesc_add_flag (field_type, 4, "AF");
+  tdesc_add_flag (field_type, 6, "ZF");
+  tdesc_add_flag (field_type, 7, "SF");
+  tdesc_add_flag (field_type, 8, "TF");
+  tdesc_add_flag (field_type, 9, "IF");
+  tdesc_add_flag (field_type, 10, "DF");
+  tdesc_add_flag (field_type, 11, "OF");
+  tdesc_add_flag (field_type, 14, "NT");
+  tdesc_add_flag (field_type, 16, "RF");
+  tdesc_add_flag (field_type, 17, "VM");
+  tdesc_add_flag (field_type, 18, "AC");
+  tdesc_add_flag (field_type, 19, "VIF");
+  tdesc_add_flag (field_type, 20, "VIP");
+  tdesc_add_flag (field_type, 21, "ID");
+
   tdesc_create_reg (feature, "rax", 0, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "rbx", 1, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "rcx", 2, 1, NULL, 64, "int64");
@@ -93,6 +112,22 @@ initialize_tdesc_amd64_linux (void)
   field_type = tdesc_named_type (feature, "uint128");
   tdesc_add_field (type, "uint128", field_type);
 
+  field_type = tdesc_create_flags (feature, "i386_mxcsr", 4);
+  tdesc_add_flag (field_type, 0, "IE");
+  tdesc_add_flag (field_type, 1, "DE");
+  tdesc_add_flag (field_type, 2, "ZE");
+  tdesc_add_flag (field_type, 3, "OE");
+  tdesc_add_flag (field_type, 4, "UE");
+  tdesc_add_flag (field_type, 5, "PE");
+  tdesc_add_flag (field_type, 6, "DAZ");
+  tdesc_add_flag (field_type, 7, "IM");
+  tdesc_add_flag (field_type, 8, "DM");
+  tdesc_add_flag (field_type, 9, "ZM");
+  tdesc_add_flag (field_type, 10, "OM");
+  tdesc_add_flag (field_type, 11, "UM");
+  tdesc_add_flag (field_type, 12, "PM");
+  tdesc_add_flag (field_type, 15, "FZ");
+
   tdesc_create_reg (feature, "xmm0", 40, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm1", 41, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm2", 42, 1, NULL, 128, "vec128");
--- gdb-7.1-p1/gdb/features/i386/amd64.c	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/amd64.c	2010-04-03 21:06:12.000000000 +0200
@@ -15,6 +15,25 @@ initialize_tdesc_amd64 (void)
   set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64"));
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+  field_type = tdesc_create_flags (feature, "i386_eflags", 4);
+  tdesc_add_flag (field_type, 0, "CF");
+  tdesc_add_flag (field_type, 1, "");
+  tdesc_add_flag (field_type, 2, "PF");
+  tdesc_add_flag (field_type, 4, "AF");
+  tdesc_add_flag (field_type, 6, "ZF");
+  tdesc_add_flag (field_type, 7, "SF");
+  tdesc_add_flag (field_type, 8, "TF");
+  tdesc_add_flag (field_type, 9, "IF");
+  tdesc_add_flag (field_type, 10, "DF");
+  tdesc_add_flag (field_type, 11, "OF");
+  tdesc_add_flag (field_type, 14, "NT");
+  tdesc_add_flag (field_type, 16, "RF");
+  tdesc_add_flag (field_type, 17, "VM");
+  tdesc_add_flag (field_type, 18, "AC");
+  tdesc_add_flag (field_type, 19, "VIF");
+  tdesc_add_flag (field_type, 20, "VIP");
+  tdesc_add_flag (field_type, 21, "ID");
+
   tdesc_create_reg (feature, "rax", 0, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "rbx", 1, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "rcx", 2, 1, NULL, 64, "int64");
@@ -91,6 +110,22 @@ initialize_tdesc_amd64 (void)
   field_type = tdesc_named_type (feature, "uint128");
   tdesc_add_field (type, "uint128", field_type);
 
+  field_type = tdesc_create_flags (feature, "i386_mxcsr", 4);
+  tdesc_add_flag (field_type, 0, "IE");
+  tdesc_add_flag (field_type, 1, "DE");
+  tdesc_add_flag (field_type, 2, "ZE");
+  tdesc_add_flag (field_type, 3, "OE");
+  tdesc_add_flag (field_type, 4, "UE");
+  tdesc_add_flag (field_type, 5, "PE");
+  tdesc_add_flag (field_type, 6, "DAZ");
+  tdesc_add_flag (field_type, 7, "IM");
+  tdesc_add_flag (field_type, 8, "DM");
+  tdesc_add_flag (field_type, 9, "ZM");
+  tdesc_add_flag (field_type, 10, "OM");
+  tdesc_add_flag (field_type, 11, "UM");
+  tdesc_add_flag (field_type, 12, "PM");
+  tdesc_add_flag (field_type, 15, "FZ");
+
   tdesc_create_reg (feature, "xmm0", 40, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm1", 41, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm2", 42, 1, NULL, 128, "vec128");
--- gdb-7.1-p1/gdb/features/i386/i386-linux.c	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/i386-linux.c	2010-04-03 21:06:12.000000000 +0200
@@ -17,6 +17,25 @@ initialize_tdesc_i386_linux (void)
   set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+  field_type = tdesc_create_flags (feature, "i386_eflags", 4);
+  tdesc_add_flag (field_type, 0, "CF");
+  tdesc_add_flag (field_type, 1, "");
+  tdesc_add_flag (field_type, 2, "PF");
+  tdesc_add_flag (field_type, 4, "AF");
+  tdesc_add_flag (field_type, 6, "ZF");
+  tdesc_add_flag (field_type, 7, "SF");
+  tdesc_add_flag (field_type, 8, "TF");
+  tdesc_add_flag (field_type, 9, "IF");
+  tdesc_add_flag (field_type, 10, "DF");
+  tdesc_add_flag (field_type, 11, "OF");
+  tdesc_add_flag (field_type, 14, "NT");
+  tdesc_add_flag (field_type, 16, "RF");
+  tdesc_add_flag (field_type, 17, "VM");
+  tdesc_add_flag (field_type, 18, "AC");
+  tdesc_add_flag (field_type, 19, "VIF");
+  tdesc_add_flag (field_type, 20, "VIP");
+  tdesc_add_flag (field_type, 21, "ID");
+
   tdesc_create_reg (feature, "eax", 0, 1, NULL, 32, "int32");
   tdesc_create_reg (feature, "ecx", 1, 1, NULL, 32, "int32");
   tdesc_create_reg (feature, "edx", 2, 1, NULL, 32, "int32");
@@ -88,6 +107,22 @@ initialize_tdesc_i386_linux (void)
   field_type = tdesc_named_type (feature, "uint128");
   tdesc_add_field (type, "uint128", field_type);
 
+  field_type = tdesc_create_flags (feature, "i386_mxcsr", 4);
+  tdesc_add_flag (field_type, 0, "IE");
+  tdesc_add_flag (field_type, 1, "DE");
+  tdesc_add_flag (field_type, 2, "ZE");
+  tdesc_add_flag (field_type, 3, "OE");
+  tdesc_add_flag (field_type, 4, "UE");
+  tdesc_add_flag (field_type, 5, "PE");
+  tdesc_add_flag (field_type, 6, "DAZ");
+  tdesc_add_flag (field_type, 7, "IM");
+  tdesc_add_flag (field_type, 8, "DM");
+  tdesc_add_flag (field_type, 9, "ZM");
+  tdesc_add_flag (field_type, 10, "OM");
+  tdesc_add_flag (field_type, 11, "UM");
+  tdesc_add_flag (field_type, 12, "PM");
+  tdesc_add_flag (field_type, 15, "FZ");
+
   tdesc_create_reg (feature, "xmm0", 32, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm1", 33, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm2", 34, 1, NULL, 128, "vec128");
--- gdb-7.1-p1/gdb/features/i386/i386.c	2010-02-08 06:08:46.000000000 +0100
+++ gdb-7.1/gdb/features/i386/i386.c	2010-04-03 21:06:12.000000000 +0200
@@ -15,6 +15,25 @@ initialize_tdesc_i386 (void)
   set_tdesc_architecture (result, bfd_scan_arch ("i386"));
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
+  field_type = tdesc_create_flags (feature, "i386_eflags", 4);
+  tdesc_add_flag (field_type, 0, "CF");
+  tdesc_add_flag (field_type, 1, "");
+  tdesc_add_flag (field_type, 2, "PF");
+  tdesc_add_flag (field_type, 4, "AF");
+  tdesc_add_flag (field_type, 6, "ZF");
+  tdesc_add_flag (field_type, 7, "SF");
+  tdesc_add_flag (field_type, 8, "TF");
+  tdesc_add_flag (field_type, 9, "IF");
+  tdesc_add_flag (field_type, 10, "DF");
+  tdesc_add_flag (field_type, 11, "OF");
+  tdesc_add_flag (field_type, 14, "NT");
+  tdesc_add_flag (field_type, 16, "RF");
+  tdesc_add_flag (field_type, 17, "VM");
+  tdesc_add_flag (field_type, 18, "AC");
+  tdesc_add_flag (field_type, 19, "VIF");
+  tdesc_add_flag (field_type, 20, "VIP");
+  tdesc_add_flag (field_type, 21, "ID");
+
   tdesc_create_reg (feature, "eax", 0, 1, NULL, 32, "int32");
   tdesc_create_reg (feature, "ecx", 1, 1, NULL, 32, "int32");
   tdesc_create_reg (feature, "edx", 2, 1, NULL, 32, "int32");
@@ -83,6 +102,22 @@ initialize_tdesc_i386 (void)
   field_type = tdesc_named_type (feature, "uint128");
   tdesc_add_field (type, "uint128", field_type);
 
+  field_type = tdesc_create_flags (feature, "i386_mxcsr", 4);
+  tdesc_add_flag (field_type, 0, "IE");
+  tdesc_add_flag (field_type, 1, "DE");
+  tdesc_add_flag (field_type, 2, "ZE");
+  tdesc_add_flag (field_type, 3, "OE");
+  tdesc_add_flag (field_type, 4, "UE");
+  tdesc_add_flag (field_type, 5, "PE");
+  tdesc_add_flag (field_type, 6, "DAZ");
+  tdesc_add_flag (field_type, 7, "IM");
+  tdesc_add_flag (field_type, 8, "DM");
+  tdesc_add_flag (field_type, 9, "ZM");
+  tdesc_add_flag (field_type, 10, "OM");
+  tdesc_add_flag (field_type, 11, "UM");
+  tdesc_add_flag (field_type, 12, "PM");
+  tdesc_add_flag (field_type, 15, "FZ");
+
   tdesc_create_reg (feature, "xmm0", 32, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm1", 33, 1, NULL, 128, "vec128");
   tdesc_create_reg (feature, "xmm2", 34, 1, NULL, 128, "vec128");
--- gdb-7.1-p1/gdb/target-descriptions.c	2010-04-03 21:04:13.000000000 +0200
+++ gdb-7.1/gdb/target-descriptions.c	2010-04-03 21:06:12.000000000 +0200
@@ -126,8 +126,6 @@ typedef struct tdesc_type
     TDESC_TYPE_IEEE_DOUBLE,
     TDESC_TYPE_ARM_FPA_EXT,
     TDESC_TYPE_I387_EXT,
-    TDESC_TYPE_I386_EFLAGS,
-    TDESC_TYPE_I386_MXCSR,
 
     /* Types defined by a target feature.  */
     TDESC_TYPE_VECTOR,
@@ -483,9 +481,7 @@ static struct tdesc_type tdesc_predefine
   { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
   { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
   { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
-  { "i387_ext", TDESC_TYPE_I387_EXT },
-  { "i386_eflags", TDESC_TYPE_I386_EFLAGS },
-  { "i386_mxcsr", TDESC_TYPE_I386_MXCSR }
+  { "i387_ext", TDESC_TYPE_I387_EXT }
 };
 
 /* Return the type associated with ID in the context of FEATURE, or
@@ -607,57 +603,6 @@ tdesc_gdb_type (struct gdbarch *gdbarch,
       return arch_float_type (gdbarch, -1, "builtin_type_i387_ext",
 			      floatformats_i387_ext);
 
-    case TDESC_TYPE_I386_EFLAGS:
-      {
-	struct type *type;
-
-	type = arch_flags_type (gdbarch, "builtin_type_i386_eflags", 4);
-	append_flags_type_flag (type, 0, "CF");
-	append_flags_type_flag (type, 1, NULL);
-	append_flags_type_flag (type, 2, "PF");
-	append_flags_type_flag (type, 4, "AF");
-	append_flags_type_flag (type, 6, "ZF");
-	append_flags_type_flag (type, 7, "SF");
-	append_flags_type_flag (type, 8, "TF");
-	append_flags_type_flag (type, 9, "IF");
-	append_flags_type_flag (type, 10, "DF");
-	append_flags_type_flag (type, 11, "OF");
-	append_flags_type_flag (type, 14, "NT");
-	append_flags_type_flag (type, 16, "RF");
-	append_flags_type_flag (type, 17, "VM");
-	append_flags_type_flag (type, 18, "AC");
-	append_flags_type_flag (type, 19, "VIF");
-	append_flags_type_flag (type, 20, "VIP");
-	append_flags_type_flag (type, 21, "ID");
-
-	return type;
-      }
-    break;
-
-    case TDESC_TYPE_I386_MXCSR:
-      {
-	struct type *type;
-
-	type = arch_flags_type (gdbarch, "builtin_type_i386_mxcsr", 4);
-	append_flags_type_flag (type, 0, "IE");
-	append_flags_type_flag (type, 1, "DE");
-	append_flags_type_flag (type, 2, "ZE");
-	append_flags_type_flag (type, 3, "OE");
-	append_flags_type_flag (type, 4, "UE");
-	append_flags_type_flag (type, 5, "PE");
-	append_flags_type_flag (type, 6, "DAZ");
-	append_flags_type_flag (type, 7, "IM");
-	append_flags_type_flag (type, 8, "DM");
-	append_flags_type_flag (type, 9, "ZM");
-	append_flags_type_flag (type, 10, "OM");
-	append_flags_type_flag (type, 11, "UM");
-	append_flags_type_flag (type, 12, "PM");
-	append_flags_type_flag (type, 15, "FZ");
-
-	return type;
-      }
-    break;
-
     /* Types defined by a target feature.  */
     case TDESC_TYPE_VECTOR:
       {
@@ -769,7 +714,8 @@ tdesc_gdb_type (struct gdbarch *gdbarch,
 	  /* Note that contrary to the function name, this call will
 	     just set the properties of an already-allocated
 	     field.  */
-	  append_flags_type_flag (type, f->start, f->name);
+	  append_flags_type_flag (type, f->start,
+				  *f->name ? f->name : NULL);
 
 	return type;
       }
@@ -1602,6 +1548,7 @@ maint_print_c_tdesc_cmd (char *args, int
   struct tdesc_reg *reg;
   struct tdesc_type *type;
   struct tdesc_type_field *f;
+  struct tdesc_type_flag *flag;
   int ix, ix2, ix3;
 
   /* Use the global target-supplied description, not the current
@@ -1715,6 +1662,18 @@ maint_print_c_tdesc_cmd (char *args, int
 		     f->name);
 		}
 	      break;
+	    case TDESC_TYPE_FLAGS:
+	      printf_unfiltered
+		("  field_type = tdesc_create_flags (feature, \"%s\", %d);\n",
+		 type->name, (int) type->u.f.size);
+	      for (ix3 = 0;
+		   VEC_iterate (tdesc_type_flag, type->u.f.flags, ix3,
+				flag);
+		   ix3++)
+		printf_unfiltered
+		  ("  tdesc_add_flag (field_type, %d, \"%s\");\n",
+		   flag->start, flag->name);
+	      break;
 	    default:
 	      error (_("C output is not supported type \"%s\"."), type->name);
 	    }

gdb-bz578250-avx-04of10.patch:
 amd64-tdep.c                       |  118 ++++++++++++++++
 i386-tdep.c                        |  261 +++++++++++++++++++++++++++++++------
 i386-tdep.h                        |   37 +++++
 testsuite/gdb.arch/amd64-byte.exp  |  121 +++++++++++++++++
 testsuite/gdb.arch/amd64-dword.exp |  123 +++++++++++++++++
 testsuite/gdb.arch/amd64-pseudo.c  |   91 ++++++++++++
 testsuite/gdb.arch/amd64-word.exp  |  123 +++++++++++++++++
 testsuite/gdb.arch/i386-byte.exp   |   98 +++++++++++++
 testsuite/gdb.arch/i386-pseudo.c   |   51 +++++++
 testsuite/gdb.arch/i386-word.exp   |   84 +++++++++++
 10 files changed, 1065 insertions(+), 42 deletions(-)

--- NEW FILE gdb-bz578250-avx-04of10.patch ---
[ Backported.  ]

commit 9d625812f24608f99fd99e8591ef3c80d729f9b5
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Tue Mar 2 13:14:28 2010 +0000

    Support x86 pseudo byte, word and dword registers.
    
    gdb/
    
    2010-03-02  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* amd64-tdep.c (amd64_byte_names): New.
    	(amd64_word_names): Likewise.
    	(amd64_dword_names): Likewise.
    	(amd64_pseudo_register_name): Likewise.
    	(amd64_pseudo_register_read): Likewise.
    	(amd64_pseudo_register_write): Likewise.
    	(amd64_init_abi): Set num_byte_regs, num_word_regs, num_dword_regs
    	and num_mmx_regs.  Call set_gdbarch_pseudo_register_read,
    	set_gdbarch_pseudo_register_write and
    	set_tdesc_pseudo_register_name.  Don't call
    	set_gdbarch_num_pseudo_regs.  Don't set mm0_regnum.
    
    	* i386-tdep.c (i386_num_mmx_regs): Removed.
    	(i386_num_pseudo_regs): Likewise.
    	(i386_byte_names): New.
    	(i386_word_names): Likewise.
    	(i386_byte_regnum_p): Likewise.
    	(i386_word_regnum_p): Likewise.
    	(i386_mmx_regnum_p): Updated.
    	(i386_pseudo_register_name): Make it global.  Handle byte and
    	word pseudo-registers.
    	(i386_pseudo_register_read): Likewise.
    	(i386_pseudo_register_write): Likewise.
    	(i386_pseudo_register_type): Handle byte, word and dword
    	pseudo-registers
    	(i386_register_reggroup_p): Don't include pseudo
    	registers, except for MXX, in any register groups.  Don't
    	include pseudo byte, word, dword registers in general_reggroup.
    	(i386_gdbarch_init): Set num_byte_regs, num_word_regs,
    	num_dword_regs, al_regnum, ax_regnum and eax_regnum.  Put MMX
    	pseudo-registers after word pseudo-registers.  Call
    	set_gdbarch_num_pseudo_regs after calling gdbarch_init_osabi.
    
    	* i386-tdep.h (gdbarch_tdep): Add num_mmx_regs, num_byte_regs,
    	al_regnum, num_word_regs, ax_regnum, num_dword_regs and
    	eax_regnum.
    	(i386_byte_regnum_p): New.
    	(i386_word_regnum_p): Likewise.
    	(i386_dword_regnum_p): Likewise.
    	(i386_pseudo_register_name): Likewise.
    	(i386_pseudo_register_read): Likewise.
    	(i386_pseudo_register_write): Likewise.
    
    gdb/testsuite/
    
    2010-03-02  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* gdb.arch/amd64-byte.exp: New.
    	* gdb.arch/amd64-dword.exp: Likewise.
    	* gdb.arch/amd64-pseudo.c: Likewise.
    	* gdb.arch/amd64-word.exp: Likewise.
    	* gdb.arch/i386-byte.exp: Likewise.
    	* gdb.arch/i386-pseudo.c: Likewise.
    	* gdb.arch/i386-word.exp: Likewise.

--- gdb-7.1-p2/gdb/amd64-tdep.c	2010-04-03 20:59:52.000000000 +0200
+++ gdb-7.1/gdb/amd64-tdep.c	2010-04-03 21:06:52.000000000 +0200
@@ -210,6 +210,107 @@ amd64_arch_reg_to_regnum (int reg)
   return amd64_arch_regmap[reg];
 }
 
+/* Register names for byte pseudo-registers.  */
+
+static const char *amd64_byte_names[] =
+{
+  "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
+  "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
+};
+
+/* Register names for word pseudo-registers.  */
+
+static const char *amd64_word_names[] =
+{
+  "ax", "bx", "cx", "dx", "si", "di", "bp", "sp", 
+  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+
+/* Register names for dword pseudo-registers.  */
+
+static const char *amd64_dword_names[] =
+{
+  "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", 
+  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+
+/* Return the name of register REGNUM.  */
+
+static const char *
+amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (i386_byte_regnum_p (gdbarch, regnum))
+    return amd64_byte_names[regnum - tdep->al_regnum];
+  else if (i386_word_regnum_p (gdbarch, regnum))
+    return amd64_word_names[regnum - tdep->ax_regnum];
+  else if (i386_dword_regnum_p (gdbarch, regnum))
+    return amd64_dword_names[regnum - tdep->eax_regnum];
+  else
+    return i386_pseudo_register_name (gdbarch, regnum);
+}
+
+static void
+amd64_pseudo_register_read (struct gdbarch *gdbarch,
+			    struct regcache *regcache,
+			    int regnum, gdb_byte *buf)
+{
+  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (i386_byte_regnum_p (gdbarch, regnum))
+    {
+      int gpnum = regnum - tdep->al_regnum;
+
+      /* Extract (always little endian).  */
+      regcache_raw_read (regcache, gpnum, raw_buf);
+      memcpy (buf, raw_buf, 1);
+    }
+  else if (i386_dword_regnum_p (gdbarch, regnum))
+    {
+      int gpnum = regnum - tdep->eax_regnum;
+      /* Extract (always little endian).  */
+      regcache_raw_read (regcache, gpnum, raw_buf);
+      memcpy (buf, raw_buf, 4);
+    }
+  else
+    i386_pseudo_register_read (gdbarch, regcache, regnum, buf);
+}
+
+static void
+amd64_pseudo_register_write (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     int regnum, const gdb_byte *buf)
+{
+  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (i386_byte_regnum_p (gdbarch, regnum))
+    {
+      int gpnum = regnum - tdep->al_regnum;
+
+      /* Read ...  */
+      regcache_raw_read (regcache, gpnum, raw_buf);
+      /* ... Modify ... (always little endian).  */
+      memcpy (raw_buf, buf, 1);
+      /* ... Write.  */
+      regcache_raw_write (regcache, gpnum, raw_buf);
+    }
+  else if (i386_dword_regnum_p (gdbarch, regnum))
+    {
+      int gpnum = regnum - tdep->eax_regnum;
+
+      /* Read ...  */
+      regcache_raw_read (regcache, gpnum, raw_buf);
+      /* ... Modify ... (always little endian).  */
+      memcpy (raw_buf, buf, 4);
+      /* ... Write.  */
+      regcache_raw_write (regcache, gpnum, raw_buf);
+    }
+  else
+    i386_pseudo_register_write (gdbarch, regcache, regnum, buf);
+}
+
 
 
 /* Return the union class of CLASS1 and CLASS2.  See the psABI for
@@ -2132,6 +2233,19 @@ amd64_init_abi (struct gdbarch_info info
   tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
   tdep->register_names = amd64_register_names;
 
+  tdep->num_byte_regs = 16;
+  tdep->num_word_regs = 16;
+  tdep->num_dword_regs = 16;
+  /* Avoid wiring in the MMX registers for now.  */
+  tdep->num_mmx_regs = 0;
+
+  set_gdbarch_pseudo_register_read (gdbarch,
+				    amd64_pseudo_register_read);
+  set_gdbarch_pseudo_register_write (gdbarch,
+				     amd64_pseudo_register_write);
+
+  set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name);
+
   /* AMD64 has an FPU and 16 SSE registers.  */
   tdep->st0_regnum = AMD64_ST0_REGNUM;
   tdep->num_xmm_regs = 16;
@@ -2183,10 +2297,6 @@ amd64_init_abi (struct gdbarch_info info
 
   set_gdbarch_skip_prologue (gdbarch, amd64_skip_prologue);
 
-  /* Avoid wiring in the MMX registers for now.  */
-  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);
--- gdb-7.1-p2/gdb/i386-tdep.c	2010-04-03 20:59:52.000000000 +0200
+++ gdb-7.1/gdb/i386-tdep.c	2010-04-03 21:06:52.000000000 +0200
@@ -81,17 +81,72 @@ static const char *i386_mmx_names[] =
   "mm4", "mm5", "mm6", "mm7"
 };
 
-static const int i386_num_mmx_regs = ARRAY_SIZE (i386_mmx_names);
+/* Register names for byte pseudo-registers.  */
+
+static const char *i386_byte_names[] =
+{
+  "al", "cl", "dl", "bl", 
+  "ah", "ch", "dh", "bh"
+};
+
+/* Register names for word pseudo-registers.  */
+
+static const char *i386_word_names[] =
+{
+  "ax", "cx", "dx", "bx",
+  "sp", "bp", "si", "di"
+};
+
+/* MMX register?  */
 
 static int
 i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  int mm0_regnum = gdbarch_tdep (gdbarch)->mm0_regnum;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int mm0_regnum = tdep->mm0_regnum;
 
   if (mm0_regnum < 0)
     return 0;
 
-  return (regnum >= mm0_regnum && regnum < mm0_regnum + i386_num_mmx_regs);
+  regnum -= mm0_regnum;
+  return regnum >= 0 && regnum < tdep->num_mmx_regs;
+}
+
+/* Byte register?  */
+
+int
+i386_byte_regnum_p (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  regnum -= tdep->al_regnum;
+  return regnum >= 0 && regnum < tdep->num_byte_regs;
+}
+
+/* Word register?  */
+
+int
+i386_word_regnum_p (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  regnum -= tdep->ax_regnum;
+  return regnum >= 0 && regnum < tdep->num_word_regs;
+}
+
+/* Dword register?  */
+
+int
+i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int eax_regnum = tdep->eax_regnum;
+
+  if (eax_regnum < 0)
+    return 0;
+
+  regnum -= eax_regnum;
+  return regnum >= 0 && regnum < tdep->num_dword_regs;
 }
 
 /* SSE register?  */
@@ -147,11 +202,18 @@ i386_fpc_regnum_p (struct gdbarch *gdbar
 
 /* Return the name of register REGNUM.  */
 
-static const char *
+const char *
 i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 {
-  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
-  return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (i386_mmx_regnum_p (gdbarch, regnum))
+    return i386_mmx_names[regnum - I387_MM0_REGNUM (tdep)];
+  else if (i386_byte_regnum_p (gdbarch, regnum))
+    return i386_byte_names[regnum - tdep->al_regnum];
+  else if (i386_word_regnum_p (gdbarch, regnum))
+    return i386_word_names[regnum - tdep->ax_regnum];
+
+  internal_error (__FILE__, __LINE__, _("invalid regnum"));
 }
 
 /* Convert a dbx register number REG to the appropriate register
@@ -2169,8 +2231,20 @@ i386_mmx_type (struct gdbarch *gdbarch)
 static struct type *
 i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
-  return i386_mmx_type (gdbarch);
+  if (i386_mmx_regnum_p (gdbarch, regnum))
+    return i386_mmx_type (gdbarch);
+  else
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      if (i386_byte_regnum_p (gdbarch, regnum))
+	return bt->builtin_int8;
+      else if (i386_word_regnum_p (gdbarch, regnum))
+	return bt->builtin_int16;
+      else if (i386_dword_regnum_p (gdbarch, regnum))
+	return bt->builtin_int32;
+    }
+
+  internal_error (__FILE__, __LINE__, _("invalid regnum"));
 }
 
 /* Map a cooked register onto a raw register or memory.  For the i386,
@@ -2192,41 +2266,104 @@ i386_mmx_regnum_to_fp_regnum (struct reg
   return (I387_ST0_REGNUM (tdep) + fpreg);
 }
 
-static void
+void
 i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buf)
 {
+  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
-      gdb_byte mmx_buf[MAX_REGISTER_SIZE];
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Extract (always little endian).  */
-      regcache_raw_read (regcache, fpnum, mmx_buf);
-      memcpy (buf, mmx_buf, register_size (gdbarch, regnum));
+      regcache_raw_read (regcache, fpnum, raw_buf);
+      memcpy (buf, raw_buf, register_size (gdbarch, regnum));
     }
   else
-    regcache_raw_read (regcache, regnum, buf);
+    {
+      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+      if (i386_word_regnum_p (gdbarch, regnum))
+	{
+	  int gpnum = regnum - tdep->ax_regnum;
+
+	  /* Extract (always little endian).  */
+	  regcache_raw_read (regcache, gpnum, raw_buf);
+	  memcpy (buf, raw_buf, 2);
+	}
+      else if (i386_byte_regnum_p (gdbarch, regnum))
+	{
+	  /* Check byte pseudo registers last since this function will
+	     be called from amd64_pseudo_register_read, which handles
+	     byte pseudo registers differently.  */
+	  int gpnum = regnum - tdep->al_regnum;
+
+	  /* Extract (always little endian).  We read both lower and
+	     upper registers.  */
+	  regcache_raw_read (regcache, gpnum % 4, raw_buf);
+	  if (gpnum >= 4)
+	    memcpy (buf, raw_buf + 1, 1);
+	  else
+	    memcpy (buf, raw_buf, 1);
+	}
+      else
+	internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
 }
 
-static void
+void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
+  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
-      gdb_byte mmx_buf[MAX_REGISTER_SIZE];
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Read ...  */
-      regcache_raw_read (regcache, fpnum, mmx_buf);
+      regcache_raw_read (regcache, fpnum, raw_buf);
       /* ... Modify ... (always little endian).  */
-      memcpy (mmx_buf, buf, register_size (gdbarch, regnum));
+      memcpy (raw_buf, buf, register_size (gdbarch, regnum));
       /* ... Write.  */
-      regcache_raw_write (regcache, fpnum, mmx_buf);
+      regcache_raw_write (regcache, fpnum, raw_buf);
     }
   else
-    regcache_raw_write (regcache, regnum, buf);
+    {
+      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+      if (i386_word_regnum_p (gdbarch, regnum))
+	{
+	  int gpnum = regnum - tdep->ax_regnum;
+
+	  /* Read ...  */
+	  regcache_raw_read (regcache, gpnum, raw_buf);
+	  /* ... Modify ... (always little endian).  */
+	  memcpy (raw_buf, buf, 2);
+	  /* ... Write.  */
+	  regcache_raw_write (regcache, gpnum, raw_buf);
+	}
+      else if (i386_byte_regnum_p (gdbarch, regnum))
+	{
+	  /* Check byte pseudo registers last since this function will
+	     be called from amd64_pseudo_register_read, which handles
+	     byte pseudo registers differently.  */
+	  int gpnum = regnum - tdep->al_regnum;
+
+	  /* Read ...  We read both lower and upper registers.  */
+	  regcache_raw_read (regcache, gpnum % 4, raw_buf);
+	  /* ... Modify ... (always little endian).  */
+	  if (gpnum >= 4)
+	    memcpy (raw_buf + 1, buf, 1);
+	  else
+	    memcpy (raw_buf, buf, 1);
+	  /* ... Write.  */
+	  regcache_raw_write (regcache, gpnum % 4, raw_buf);
+	}
+      else
+	internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
 }
 
 
@@ -2663,22 +2800,46 @@ int
 i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 			  struct reggroup *group)
 {
-  int sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum)
-		      || i386_mxcsr_regnum_p (gdbarch, regnum));
-  int fp_regnum_p = (i386_fp_regnum_p (gdbarch, regnum)
-		     || i386_fpc_regnum_p (gdbarch, regnum));
-  int mmx_regnum_p = (i386_mmx_regnum_p (gdbarch, regnum));
+  int sse_regnum_p, fp_regnum_p, mmx_regnum_p, byte_regnum_p,
+      word_regnum_p, dword_regnum_p;
+
+  /* Don't include pseudo registers, except for MMX, in any register
+     groups.  */
+  byte_regnum_p = i386_byte_regnum_p (gdbarch, regnum);
+  if (byte_regnum_p)
+    return 0;
 
+  word_regnum_p = i386_word_regnum_p (gdbarch, regnum);
+  if (word_regnum_p)
+    return 0;
+
+  dword_regnum_p = i386_dword_regnum_p (gdbarch, regnum);
+  if (dword_regnum_p)
+    return 0;
+
+  mmx_regnum_p = i386_mmx_regnum_p (gdbarch, regnum);
   if (group == i386_mmx_reggroup)
     return mmx_regnum_p;
+
+  sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum)
+		  || i386_mxcsr_regnum_p (gdbarch, regnum));
   if (group == i386_sse_reggroup)
     return sse_regnum_p;
   if (group == vector_reggroup)
-    return (mmx_regnum_p || sse_regnum_p);
+    return mmx_regnum_p || sse_regnum_p;
+
+  fp_regnum_p = (i386_fp_regnum_p (gdbarch, regnum)
+		 || i386_fpc_regnum_p (gdbarch, regnum));
   if (group == float_reggroup)
     return fp_regnum_p;
+
   if (group == general_reggroup)
-    return (!fp_regnum_p && !mmx_regnum_p && !sse_regnum_p);
+    return (!fp_regnum_p
+	    && !mmx_regnum_p
+	    && !sse_regnum_p
+	    && !byte_regnum_p
+	    && !word_regnum_p
+	    && !dword_regnum_p);
 
   return default_register_reggroup_p (gdbarch, regnum, group);
 }
@@ -5527,6 +5688,7 @@ i386_gdbarch_init (struct gdbarch_info i
   struct gdbarch *gdbarch;
   struct tdesc_arch_data *tdesc_data;
   const struct target_desc *tdesc;
+  int mm0_regnum;
 
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
@@ -5563,11 +5725,6 @@ i386_gdbarch_init (struct gdbarch_info i
 
   tdep->st0_regnum = I386_ST0_REGNUM;
 
-  /* The MMX registers are implemented as pseudo-registers.  Put off
-     calculating the register number for %mm0 until we know the number
-     of raw registers.  */
-  tdep->mm0_regnum = 0;
-
   /* I386_NUM_XREGS includes %mxcsr, so substract one.  */
   tdep->num_xmm_regs = I386_NUM_XREGS - 1;
 
@@ -5693,8 +5850,7 @@ i386_gdbarch_init (struct gdbarch_info i
 
   frame_base_set_default (gdbarch, &i386_frame_base);
 
-  /* Wire in the MMX registers.  */
-  set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
+  /* Pseudo registers may be changed by amd64_init_abi.  */
   set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
   set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
 
@@ -5714,12 +5870,24 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
   tdep->register_names = i386_register_names;
 
+  tdep->num_byte_regs = 8;
+  tdep->num_word_regs = 8;
+  tdep->num_dword_regs = 0;
+  tdep->num_mmx_regs = 8;
+
   tdesc_data = tdesc_data_alloc ();
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.tdep_info = (void *) tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
+  /* Wire in pseudo registers.  Number of pseudo registers may be
+     changed.  */
+  set_gdbarch_num_pseudo_regs (gdbarch, (tdep->num_byte_regs
+					 + tdep->num_word_regs
+					 + tdep->num_dword_regs
+					 + tdep->num_mmx_regs));
+
   /* Target description may be changed.  */
   tdesc = tdep->tdesc;
 
@@ -5736,6 +5904,28 @@ i386_gdbarch_init (struct gdbarch_info i
   /* Override gdbarch_register_reggroup_p set in tdesc_use_registers.  */
   set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);
 
+  /* Make %al the first pseudo-register.  */
+  tdep->al_regnum = gdbarch_num_regs (gdbarch);
+  tdep->ax_regnum = tdep->al_regnum + tdep->num_byte_regs;
+
+  mm0_regnum = tdep->ax_regnum + tdep->num_word_regs;
+  if (tdep->num_dword_regs)
+    {
+      /* Support dword pseudo-registesr if it hasn't been disabled,  */
+      tdep->eax_regnum = mm0_regnum;
+      mm0_regnum = tdep->eax_regnum + tdep->num_dword_regs;
+    }
+  else
+    tdep->eax_regnum = -1;
+
+  if (tdep->num_mmx_regs != 0)
+    {
+      /* Support MMX pseudo-registesr if MMX hasn't been disabled,  */
+      tdep->mm0_regnum = mm0_regnum;
+    }
+  else
+    tdep->mm0_regnum = -1;
+
   /* Hook in the legacy prologue-based unwinders last (fallback).  */
   frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
@@ -5747,11 +5937,6 @@ i386_gdbarch_init (struct gdbarch_info i
     set_gdbarch_regset_from_core_section (gdbarch,
 					  i386_regset_from_core_section);
 
-  /* Unless support for MMX has been disabled, make %mm0 the first
-     pseudo-register.  */
-  if (tdep->mm0_regnum == 0)
-    tdep->mm0_regnum = gdbarch_num_regs (gdbarch);
-
   set_gdbarch_skip_permanent_breakpoint (gdbarch,
 					 i386_skip_permanent_breakpoint);
 
--- gdb-7.1-p2/gdb/i386-tdep.h	2010-04-03 20:59:52.000000000 +0200
+++ gdb-7.1/gdb/i386-tdep.h	2010-04-03 21:06:52.000000000 +0200
@@ -114,10 +114,32 @@ struct gdbarch_tdep
      absence of an FPU.  */
   int st0_regnum;
 
+  /* Number of MMX registers.  */
+  int num_mmx_regs;
+
   /* Register number for %mm0.  Set this to -1 to indicate the absence
      of MMX support.  */
   int mm0_regnum;
 
+  /* Number of byte registers.  */
+  int num_byte_regs;
+
+  /* Register pseudo number for %al.  */
+  int al_regnum;
+
+  /* Number of pseudo word registers.  */
+  int num_word_regs;
+
+  /* Register number for %ax.  */
+  int ax_regnum;
+
+  /* Number of pseudo dword registers.  */
+  int num_dword_regs;
+
+  /* Register number for %eax.  Set this to -1 to indicate the absence
+     of pseudo dword register support.  */
+  int eax_regnum;
+
   /* Number of core registers.  */
   int num_core_regs;
 
@@ -253,6 +275,21 @@ enum record_i386_regnum
 /* Types for i386-specific registers.  */
 extern struct type *i387_ext_type (struct gdbarch *gdbarch);
 
+/* Checks of different pseudo-registers.  */
+extern int i386_byte_regnum_p (struct gdbarch *gdbarch, int regnum);
+extern int i386_word_regnum_p (struct gdbarch *gdbarch, int regnum);
+extern int i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum);
+
+extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch,
+					      int regnum);
+
+extern void i386_pseudo_register_read (struct gdbarch *gdbarch,
+				       struct regcache *regcache,
+				       int regnum, gdb_byte *buf);
+extern void i386_pseudo_register_write (struct gdbarch *gdbarch,
+					struct regcache *regcache,
+					int regnum, const gdb_byte *buf);
+
 /* Segment selectors.  */
 #define I386_SEL_RPL	0x0003  /* Requester's Privilege Level mask.  */
 #define I386_SEL_UPL	0x0003	/* User Privilige Level. */
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/amd64-byte.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/amd64-byte.exp	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,121 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb at gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget x86_64-*-* ] } {
+    verbose "Skipping amd64 byte register tests."
+    return
+}
+
+set testfile "amd64-byte"
+set srcfile amd64-pseudo.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug]] != "" } {
+    untested ${testfile}
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set nr_regs 14
+set byte_regs(1) al
+set byte_regs(2) bl
+set byte_regs(3) cl
+set byte_regs(4) dl
+set byte_regs(5) sil
+set byte_regs(6) dil
+set byte_regs(7) r8l
+set byte_regs(8) r9l
+set byte_regs(9) r10l
+set byte_regs(10) r11l
+set byte_regs(11) r12l
+set byte_regs(12) r13l
+set byte_regs(13) r14l
+set byte_regs(14) r15l
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set first breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    gdb_test "print/x \$$byte_regs($r)" \
+        ".. = 0x[format %x $r]1" \
+        "check contents of %$byte_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set second breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    gdb_test "print/x \$$byte_regs($r)" \
+        ".. = 0x[format %x $r]1" \
+        "check contents of %$byte_regs($r)"
+}
+
+for { set r 1 } { $r <= 6  } { incr r } {
+  gdb_test "set var \$$byte_regs($r) = $r" "" "set %$byte_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "third breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set third breakpoint in main"
+gdb_continue_to_breakpoint "continue to third breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    gdb_test "print \$$byte_regs($r)" \
+        ".. = $r" \
+        "check contents of %$byte_regs($r)"
+}
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+  gdb_test "set var \$$byte_regs($r) = $r" "" "set %$byte_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "forth breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set forth breakpoint in main"
+gdb_continue_to_breakpoint "continue to forth breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    gdb_test "print \$$byte_regs($r)" \
+        ".. = $r" \
+        "check contents of %$byte_regs($r)"
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/amd64-dword.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/amd64-dword.exp	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,123 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb at gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget x86_64-*-* ] } {
+    verbose "Skipping amd64 dword register tests."
+    return
+}
+
+set testfile "amd64-dword"
+set srcfile amd64-pseudo.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug]] != "" } {
+    untested ${testfile}
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set nr_regs 14
+set dword_regs(1) eax
+set dword_regs(2) ebx
+set dword_regs(3) ecx
+set dword_regs(4) edx
+set dword_regs(5) esi
+set dword_regs(6) edi
+set dword_regs(7) r8d
+set dword_regs(8) r9d
+set dword_regs(9) r10d
+set dword_regs(10) r11d
+set dword_regs(11) r12d
+set dword_regs(12) r13d
+set dword_regs(13) r14d
+set dword_regs(14) r15d
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set first breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    set hex [format %x $r]
+    gdb_test "print/x \$$dword_regs($r)" \
+	".. = 0x${hex}4${hex}3${hex}2${hex}1" \
+        "check contents of %$dword_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set second breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    set hex [format %x $r]
+    gdb_test "print/x \$$dword_regs($r)" \
+	".. = 0x${hex}4${hex}3${hex}2${hex}1" \
+        "check contents of %$dword_regs($r)"
+}
+
+for { set r 1 } { $r <= 6  } { incr r } {
+  gdb_test "set var \$$dword_regs($r) = $r" "" "set %$dword_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "third breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set third breakpoint in main"
+gdb_continue_to_breakpoint "continue to third breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    gdb_test "print \$$dword_regs($r)" \
+        ".. = $r" \
+        "check contents of %$dword_regs($r)"
+}
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+  gdb_test "set var \$$dword_regs($r) = $r" "" "set %$dword_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "forth breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set forth breakpoint in main"
+gdb_continue_to_breakpoint "continue to forth breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    gdb_test "print \$$dword_regs($r)" \
+        ".. = $r" \
+        "check contents of %$dword_regs($r)"
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/amd64-pseudo.c	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/amd64-pseudo.c	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,91 @@
+/* Test program for byte registers.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+
+int data[] = {
+  0x14131211,
+  0x24232221,
+  0x34333231,
+  0x44434241,
+  0x54535251,
+  0x64636261,
+  0x74737271,
+  0x84838281,
+  0x94939291,
+  0xa4a3a2a1,
+  0xb4b3b2b1,
+  0xc4c3c2c1,
+  0xd4d3d2d1,
+  0xe4e3e2e1,
+};
+
+int
+main (int argc, char **argv)
+{
+  asm ("mov 0(%0), %%eax\n\t"
+       "mov 4(%0), %%ebx\n\t"
+       "mov 8(%0), %%ecx\n\t"
+       "mov 12(%0), %%edx\n\t"
+       "mov 16(%0), %%esi\n\t"
+       "mov 20(%0), %%edi\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "eax", "ebx", "ecx", "edx", "esi", "edi");
+  asm ("nop"); /* first breakpoint here */
+
+  asm ("mov 24(%0), %%r8d\n\t"
+       "mov 28(%0), %%r9d\n\t"
+       "mov 32(%0), %%r10d\n\t"
+       "mov 36(%0), %%r11\n\t"
+       "mov 40(%0), %%r12d\n\t"
+       "mov 44(%0), %%r13d\n\t"
+       "mov 48(%0), %%r14d\n\t"
+       "mov 52(%0), %%r15d\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
+  asm ("nop"); /* second breakpoint here */
+
+  asm ("mov %%eax, 0(%0)\n\t"
+       "mov %%ebx, 4(%0)\n\t"
+       "mov %%ecx, 8(%0)\n\t"
+       "mov %%edx, 12(%0)\n\t"
+       "mov %%esi, 16(%0)\n\t"
+       "mov %%edi, 20(%0)\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "eax", "ebx", "ecx", "edx", "esi", "edi");
+  asm ("nop"); /* third breakpoint here */
+
+  asm ("mov %%r8d, 24(%0)\n\t"
+       "mov %%r9d, 28(%0)\n\t"
+       "mov %%r10d, 32(%0)\n\t"
+       "mov %%r11d, 36(%0)\n\t"
+       "mov %%r12d, 40(%0)\n\t"
+       "mov %%r13d, 44(%0)\n\t"
+       "mov %%r14d, 48(%0)\n\t"
+       "mov %%r15d, 52(%0)\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
+  puts ("Bye!"); /* forth breakpoint here */
+
+  return 0;
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/amd64-word.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/amd64-word.exp	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,123 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb at gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget x86_64-*-* ] } {
+    verbose "Skipping amd64 word register tests."
+    return
+}
+
+set testfile "amd64-word"
+set srcfile amd64-pseudo.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug]] != "" } {
+    untested ${testfile}
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set nr_regs 14
+set word_regs(1) ax
+set word_regs(2) bx
+set word_regs(3) cx
+set word_regs(4) dx
+set word_regs(5) si
+set word_regs(6) di
+set word_regs(7) r8w
+set word_regs(8) r9w
+set word_regs(9) r10w
+set word_regs(10) r11w
+set word_regs(11) r12w
+set word_regs(12) r13w
+set word_regs(13) r14w
+set word_regs(14) r15w
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set first breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    set hex [format %x $r]
+    gdb_test "print/x \$$word_regs($r)" \
+        ".. = 0x${hex}2${hex}1" \
+        "check contents of %$word_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set second breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    set hex [format %x $r]
+    gdb_test "print/x \$$word_regs($r)" \
+        ".. = 0x${hex}2${hex}1" \
+        "check contents of %$word_regs($r)"
+}
+
+for { set r 1 } { $r <= 6  } { incr r } {
+  gdb_test "set var \$$word_regs($r) = $r" "" "set %$word_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "third breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set third breakpoint in main"
+gdb_continue_to_breakpoint "continue to third breakpoint in main"
+
+for { set r 1 } { $r <= 6  } { incr r } {
+    gdb_test "print \$$word_regs($r)" \
+        ".. = $r" \
+        "check contents of %$word_regs($r)"
+}
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+  gdb_test "set var \$$word_regs($r) = $r" "" "set %$word_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "forth breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set forth breakpoint in main"
+gdb_continue_to_breakpoint "continue to forth breakpoint in main"
+
+for { set r 7 } { $r <= $nr_regs  } { incr r } {
+    gdb_test "print \$$word_regs($r)" \
+        ".. = $r" \
+        "check contents of %$word_regs($r)"
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/i386-byte.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/i386-byte.exp	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,98 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb at gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget i?86-*-*] } {
+    verbose "Skipping i386 byte register tests."
+    return
+}
+
+set testfile "i386-byte"
+set srcfile i386-pseudo.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug]] != "" } {
+    untested ${testfile}
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set byte_regs(1) al
+set byte_regs(2) bl
+set byte_regs(3) cl
+set byte_regs(4) dl
+set byte_regs(5) ah
+set byte_regs(6) bh
+set byte_regs(7) ch
+set byte_regs(8) dh
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set first breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+for { set r 1 } { $r <= 4  } { incr r } {
+    gdb_test "print/x \$$byte_regs($r)" \
+        ".. = 0x[format %x $r]1" \
+        "check contents of %$byte_regs($r)"
+    set h [expr $r + 4]
+    gdb_test "print/x \$$byte_regs($h)" \
+        ".. = 0x[format %x $r]2" \
+        "check contents of %$byte_regs($h)"
+}
+
+for { set r 1 } { $r <= 4  } { incr r } {
+  gdb_test "set var \$$byte_regs($r) = $r" "" "set %$byte_regs($r)"
+  set h [expr $r + 4]
+  gdb_test "set var \$$byte_regs($h) = $h" "" "set %$byte_regs($h)"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set second breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+for { set r 1 } { $r <= 4  } { incr r } {
+    gdb_test "print \$$byte_regs($r)" \
+        ".. = $r" \
+        "check contents of %$byte_regs($r)"
+    set h [expr $r + 4]
+    gdb_test "print \$$byte_regs($h)" \
+        ".. = $h" \
+        "check contents of %$byte_regs($h)"
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/i386-pseudo.c	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/i386-pseudo.c	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,51 @@
+/* Test program for byte registers.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+
+int data[] = {
+  0x14131211,
+  0x24232221,
+  0x34333231,
+  0x44434241,
+};
+
+int
+main (int argc, char **argv)
+{
+  asm ("mov 0(%0), %%eax\n\t"
+       "mov 4(%0), %%ebx\n\t"
+       "mov 8(%0), %%ecx\n\t"
+       "mov 12(%0), %%edx\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "eax", "ebx", "ecx", "edx");
+  asm ("nop"); /* first breakpoint here */
+
+  asm ("mov %%eax, 0(%0)\n\t"
+       "mov %%ebx, 4(%0)\n\t"
+       "mov %%ecx, 8(%0)\n\t"
+       "mov %%edx, 12(%0)\n\t"
+       : /* no output operands */
+       : "r" (data) 
+       : "eax", "ebx", "ecx", "edx");
+  puts ("Bye!"); /* second breakpoint here */
+
+  return 0;
+}
--- gdb-7.1-p2/gdb/testsuite/gdb.arch/i386-word.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.1/gdb/testsuite/gdb.arch/i386-word.exp	2010-04-03 21:06:52.000000000 +0200
@@ -0,0 +1,84 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb at gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget i?86-*-*] } {
+    verbose "Skipping i386 word register tests."
+    return
+}
+
+set testfile "i386-word"
+set srcfile i386-pseudo.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug]] != "" } {
+    untested ${testfile}
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set word_regs(1) ax
+set word_regs(2) bx
+set word_regs(3) cx
+set word_regs(4) dx
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set first breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+for { set r 1 } { $r <= 4  } { incr r } {
+    gdb_test "print/x \$$word_regs($r)" \
+        ".. = 0x[format %x $r]2[format %x $r]1" \
+        "check contents of %$word_regs($r)"
+}
+
+for { set r 1 } { $r <= 4  } { incr r } {
+  gdb_test "set var \$$word_regs($r) = $r" "" "set %$word_regs($r)"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*${srcfile}.*" \
+         "set second breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+for { set r 1 } { $r <= 4  } { incr r } {
+    gdb_test "print \$$word_regs($r)" \
+        ".. = $r" \
+        "check contents of %$word_regs($r)"
+}

gdb-bz578250-avx-05of10.patch:
 NEWS |    8 ++++++++
 1 file changed, 8 insertions(+)

--- NEW FILE gdb-bz578250-avx-05of10.patch ---
[ Backported.  ]

commit 6448aace637843e8e7c021d7f8c5d5d5fdd71974
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Wed Mar 3 20:19:48 2010 +0000

    Mention improvement for X86 general purpose registers.
    
    2010-03-03  H.J. Lu  <hongjiu.lu at intel.com>
    	    Eli Zaretskii  <eliz at gnu.org>
    
    	* NEWS: Add X86 general purpose registers section.

--- gdb-7.1-p3/gdb/NEWS	2010-03-18 22:01:55.000000000 +0100
+++ gdb-7.1/gdb/NEWS	2010-04-03 21:07:46.000000000 +0200
@@ -438,6 +438,14 @@ GDB will now correctly handle all of:
     now support hardware watchpoints, and will use them automatically
     as appropriate.
 
+* X86 general purpose registers
+
+  GDB now supports reading/writing byte, word and double-word x86
+  general purpose registers directly.  This means you can use, say,
+  $ah or $ax to refer, respectively, to the byte register AH and
+  16-bit word register AX that are actually portions of the 32-bit
+  register EAX or 64-bit register RAX.
+
 * Python scripting
 
   GDB now has support for scripting using Python.  Whether this is

gdb-bz578250-avx-06of10.patch:
 amd64-tdep.c |    2 +-
 i386-tdep.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- NEW FILE gdb-bz578250-avx-06of10.patch ---
[ Backported.  ]

commit 49f8d1c24c639d891f58a3b9feda425833b702fb
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Fri Mar 12 15:12:34 2010 +0000

    Restore sp for x86.
    
    2010-03-12  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* amd64-tdep.c (amd64_word_names): Replace "sp" with "".
    	* i386-tdep.c (i386_word_names): Likewise.

--- gdb-7.1-p4/gdb/amd64-tdep.c	2010-04-03 21:06:52.000000000 +0200
+++ gdb-7.1/gdb/amd64-tdep.c	2010-04-03 21:08:21.000000000 +0200
@@ -222,7 +222,7 @@ static const char *amd64_byte_names[] =
 
 static const char *amd64_word_names[] =
 {
-  "ax", "bx", "cx", "dx", "si", "di", "bp", "sp", 
+  "ax", "bx", "cx", "dx", "si", "di", "bp", "", 
   "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
 };
 
--- gdb-7.1-p4/gdb/i386-tdep.c	2010-04-03 21:06:52.000000000 +0200
+++ gdb-7.1/gdb/i386-tdep.c	2010-04-03 21:08:21.000000000 +0200
@@ -94,7 +94,7 @@ static const char *i386_byte_names[] =
 static const char *i386_word_names[] =
 {
   "ax", "cx", "dx", "bx",
-  "sp", "bp", "si", "di"
+  "", "bp", "si", "di"
 };
 
 /* MMX register?  */

gdb-bz578250-avx-07of10.patch:
 NEWS            |    5 +++
 doc/gdb.texinfo |    6 ++++
 i386-tdep.c     |    4 +++
 remote.c        |   74 ++++++++++++++++++++++++++++++++++++++++++++++----------
 remote.h        |    1 
 5 files changed, 78 insertions(+), 12 deletions(-)

--- NEW FILE gdb-bz578250-avx-07of10.patch ---
[ Backported.  ]

commit d5ea7042210f5ad319ad19910bce13fd5717c6d6
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Tue Mar 30 15:45:08 2010 +0000

    Add xmlRegisters= to qSupported packet.
    
    gdb/
    
    2010-03-30  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* NEWS: Mention xmlRegisters= in qSupported packet.
    
    	* i386-tdep.c: Include "remote.h".
    	(_initialize_i386_tdep): Call register_remote_support_xml.
    
    	* remote.c (remote_support_xml): New.
    	(register_remote_support_xml): Likewise.
    	(remote_query_supported_append): Likewise.
    	(remote_query_supported): Support remote_support_xml.
    
    	* remote.h (register_remote_support_xml): New.
    
    gdb/doc/
    
    2010-03-30  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* gdb.texinfo (General Query Packets): Add xmlRegisters.

--- gdb-7.1-p5/gdb/NEWS	2010-04-03 21:07:46.000000000 +0200
+++ gdb-7.1/gdb/NEWS	2010-04-03 21:10:06.000000000 +0200
@@ -1,6 +1,11 @@
 		What has changed in GDB?
 	     (Organized release by release)
 
+*** Changes since GDB 7.1
+
+* GDB now sends xmlRegisters= in qSupported packet to indicate that
+  it understands register description.
+
 *** Changes in GDB 7.1
 
 * C++ Improvements
--- gdb-7.1-p5/gdb/doc/gdb.texinfo	2010-04-03 21:04:13.000000000 +0200
+++ gdb-7.1/gdb/doc/gdb.texinfo	2010-04-03 21:09:29.000000000 +0200
@@ -30292,6 +30292,12 @@ extensions to the remote protocol.  @val
 extensions unless the stub also reports that it supports them by
 including @samp{multiprocess+} in its @samp{qSupported} reply.
 @xref{multiprocess extensions}, for details.
+
+ at item xmlRegisters
+This feature indicates that @value{GDBN} supports the XML target
+description.  If the stub sees @samp{xmlRegisters=} with target
+specific strings separated by a comma, it will report register
+description.
 @end table
 
 Stubs should ignore any unknown values for
--- gdb-7.1-p5/gdb/i386-tdep.c	2010-04-03 21:08:21.000000000 +0200
+++ gdb-7.1/gdb/i386-tdep.c	2010-04-03 21:09:29.000000000 +0200
@@ -44,6 +44,7 @@
 #include "value.h"
 #include "dis-asm.h"
 #include "disasm.h"
+#include "remote.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -6000,4 +6001,7 @@ is \"default\"."),
 
   /* Initialize the standard target descriptions.  */
   initialize_tdesc_i386 ();
+
+  /* Tell remote stub that we support XML target description.  */
+  register_remote_support_xml ("i386");
 }
--- gdb-7.1-p5/gdb/remote.c	2010-04-03 20:24:51.000000000 +0200
+++ gdb-7.1/gdb/remote.c	2010-04-03 21:09:29.000000000 +0200
@@ -3467,6 +3467,53 @@ static struct protocol_feature remote_pr
     PACKET_bs },
 };
 
+static char *remote_support_xml;
+
+/* Register string appended to "xmlRegisters=" in qSupported query.  */
+
+void
+register_remote_support_xml (const char *xml ATTRIBUTE_UNUSED)
+{
+#if defined(HAVE_LIBEXPAT)
+  if (remote_support_xml == NULL)
+    remote_support_xml = concat ("xmlRegisters=", xml, NULL);
+  else
+    {
+      char *copy = xstrdup (remote_support_xml + 13);
+      char *p = strtok (copy, ",");
+
+      do
+	{
+	  if (strcmp (p, xml) == 0)
+	    {
+	      /* already there */
+	      xfree (copy);
+	      return;
+	    }
+	}
+      while ((p = strtok (NULL, ",")) != NULL);
+      xfree (copy);
+
+      p = concat (remote_support_xml, ",", xml, NULL);
+      xfree (remote_support_xml);
+      remote_support_xml = p;
+    }
+#endif
+}
+
+static char *
+remote_query_supported_append (char *msg, const char *append)
+{
+  if (msg)
+    {
+      char *p = concat (msg, ";", append, NULL);
+      xfree (msg);
+      return p;
+    }
+  else
+    return xstrdup (append);
+}
+
 static void
 remote_query_supported (void)
 {
@@ -3485,24 +3532,27 @@ remote_query_supported (void)
   rs->buf[0] = 0;
   if (remote_protocol_packets[PACKET_qSupported].support != PACKET_DISABLE)
     {
+      char *q = NULL;
       const char *qsupported = gdbarch_qsupported (target_gdbarch);
+
+      if (rs->extended)
+	q = remote_query_supported_append (q, "multiprocess+");
+      
       if (qsupported)
+	q = remote_query_supported_append (q, qsupported);
+
+      if (remote_support_xml)
+	q = remote_query_supported_append (q, remote_support_xml);
+
+      if (q)
 	{
-	  char *q;
-	  if (rs->extended)
-	    q = concat ("qSupported:multiprocess+;", qsupported, NULL);
-	  else
-	    q = concat ("qSupported:", qsupported, NULL);
-	  putpkt (q);
+	  char *p = concat ("qSupported:", q, NULL);
 	  xfree (q);
+	  putpkt (p);
+	  xfree (p);
 	}
       else
-	{
-	  if (rs->extended)
-	    putpkt ("qSupported:multiprocess+");
-	  else
-	    putpkt ("qSupported");
-	}
+	putpkt ("qSupported");
 
       getpkt (&rs->buf, &rs->buf_size, 0);
 
--- gdb-7.1-p5/gdb/remote.h	2010-01-01 08:31:41.000000000 +0100
+++ gdb-7.1/gdb/remote.h	2010-04-03 21:09:29.000000000 +0200
@@ -66,6 +66,7 @@ extern void (*deprecated_target_wait_loo
 
 void register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
 				     const struct target_desc *tdesc);
+void register_remote_support_xml (const char *);
 
 void remote_file_put (const char *local_file, const char *remote_file,
 		      int from_tty);

gdb-bz578250-avx-08of10.patch:
 gdb.texinfo |   11 +++++++++++
 1 file changed, 11 insertions(+)

--- NEW FILE gdb-bz578250-avx-08of10.patch ---
[ Backported.  ]

commit 684341392f3ca6703dc28dac548d3051811bff47
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Tue Mar 30 18:37:03 2010 +0000

    Add org.gnu.gdb.i386.avx.
    
    2010-03-30  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* gdb.texinfo (i386 Features): Add org.gnu.gdb.i386.avx.

--- gdb-7.1-p6/gdb/doc/gdb.texinfo	2010-04-03 21:09:29.000000000 +0200
+++ gdb-7.1/gdb/doc/gdb.texinfo	2010-04-03 21:10:57.000000000 +0200
@@ -33380,6 +33380,17 @@ describe registers:
 @samp{mxcsr}
 @end itemize
 
+The @samp{org.gnu.gdb.i386.avx} feature is optional.  It should
+describe the upper 128 bits of @sc{ymm} registers:
+
+ at itemize @minus
+ at item
+ at samp{ymm0h} through @samp{ymm7h} for i386
+ at item
+ at samp{ymm0h} through @samp{ymm15h} for amd64
+ at item 
+ at end itemize
+
 The @samp{org.gnu.gdb.i386.linux} feature is optional.  It should
 describe a single register, @samp{orig_eax}.
 

gdb-bz578250-avx-09of10.patch:
 amd64-tdep.c                      |   48 ++++++++++++++++++++++++++++++--------
 testsuite/gdb.arch/amd64-byte.exp |   30 ++++++++++++++++++++---
 2 files changed, 64 insertions(+), 14 deletions(-)

--- NEW FILE gdb-bz578250-avx-09of10.patch ---
[ Backported.  ]

commit 5362e5e1dc4cfac24fbd58773aaa7a82c615b662
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Thu Apr 1 20:02:07 2010 +0000

    Support "ah", "bh", "ch", "dh" on amd64.
    
    gdb/
    
    2010-04-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* amd64-tdep.c (amd64_byte_names): Add "ah", "bh", "ch", "dh".
    	(AMD64_NUM_LOWER_BYTE_REGS): New.
    	(amd64_pseudo_register_read): Handle "ah", "bh", "ch", "dh".
    	(amd64_pseudo_register_write): Likewise.
    	(amd64_init_abi): Set num_byte_regs to 20.
    
    gdb/testsuite/
    
    2010-04-01  H.J. Lu  <hongjiu.lu at intel.com>
    
    	* gdb.arch/amd64-byte.exp: Check "ah", "bh", "ch", "dh".

--- gdb-7.1-p7/gdb/amd64-tdep.c	2010-04-03 21:08:21.000000000 +0200
+++ gdb-7.1/gdb/amd64-tdep.c	2010-04-03 21:11:41.000000000 +0200
@@ -215,9 +215,13 @@ amd64_arch_reg_to_regnum (int reg)
 static const char *amd64_byte_names[] =
 {
   "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
-  "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
+  "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l",
+  "ah", "bh", "ch", "dh"
 };
 
+/* Number of lower byte registers.  */
+#define AMD64_NUM_LOWER_BYTE_REGS 16
+
 /* Register names for word pseudo-registers.  */
 
 static const char *amd64_word_names[] =
@@ -263,8 +267,18 @@ amd64_pseudo_register_read (struct gdbar
       int gpnum = regnum - tdep->al_regnum;
 
       /* Extract (always little endian).  */
-      regcache_raw_read (regcache, gpnum, raw_buf);
-      memcpy (buf, raw_buf, 1);
+      if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
+	{
+	  /* Special handling for AH, BH, CH, DH.  */
+	  regcache_raw_read (regcache,
+			     gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
+	  memcpy (buf, raw_buf + 1, 1);
+	}
+      else
+	{
+	  regcache_raw_read (regcache, gpnum, raw_buf);
+	  memcpy (buf, raw_buf, 1);
+	}
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
@@ -289,12 +303,26 @@ amd64_pseudo_register_write (struct gdba
     {
       int gpnum = regnum - tdep->al_regnum;
 
-      /* Read ...  */
-      regcache_raw_read (regcache, gpnum, raw_buf);
-      /* ... Modify ... (always little endian).  */
-      memcpy (raw_buf, buf, 1);
-      /* ... Write.  */
-      regcache_raw_write (regcache, gpnum, raw_buf);
+      if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
+	{
+	  /* Read ... AH, BH, CH, DH.  */
+	  regcache_raw_read (regcache,
+			     gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
+	  /* ... Modify ... (always little endian).  */
+	  memcpy (raw_buf + 1, buf, 1);
+	  /* ... Write.  */
+	  regcache_raw_write (regcache,
+			      gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
+	}
+      else
+	{
+	  /* Read ...  */
+	  regcache_raw_read (regcache, gpnum, raw_buf);
+	  /* ... Modify ... (always little endian).  */
+	  memcpy (raw_buf, buf, 1);
+	  /* ... Write.  */
+	  regcache_raw_write (regcache, gpnum, raw_buf);
+	}
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
@@ -2233,7 +2261,7 @@ amd64_init_abi (struct gdbarch_info info
   tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
   tdep->register_names = amd64_register_names;
 
-  tdep->num_byte_regs = 16;
+  tdep->num_byte_regs = 20;
   tdep->num_word_regs = 16;
   tdep->num_dword_regs = 16;
   /* Avoid wiring in the MMX registers for now.  */
--- gdb-7.1-p7/gdb/testsuite/gdb.arch/amd64-byte.exp	2010-04-03 21:06:52.000000000 +0200
+++ gdb-7.1/gdb/testsuite/gdb.arch/amd64-byte.exp	2010-04-03 21:11:41.000000000 +0200
@@ -52,7 +52,6 @@ if ![runto_main] then {
     gdb_suppress_tests
 }
 
-set nr_regs 14
 set byte_regs(1) al
 set byte_regs(2) bl
 set byte_regs(3) cl
@@ -67,6 +66,10 @@ set byte_regs(11) r12l
 set byte_regs(12) r13l
 set byte_regs(13) r14l
 set byte_regs(14) r15l
+set byte_regs(15) ah
+set byte_regs(16) bh
+set byte_regs(17) ch
+set byte_regs(18) dh
 
 gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
          "Breakpoint .* at .*${srcfile}.*" \
@@ -79,12 +82,19 @@ for { set r 1 } { $r <= 6  } { incr r } 
         "check contents of %$byte_regs($r)"
 }
 
+for { set r 1 } { $r <= 4  } { incr r } {
+    set h [expr $r + 14]
+    gdb_test "print/x \$$byte_regs($h)" \
+        ".. = 0x[format %x $r]2" \
+        "check contents of %$byte_regs($h)"
+}
+
 gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
          "Breakpoint .* at .*${srcfile}.*" \
          "set second breakpoint in main"
 gdb_continue_to_breakpoint "continue to second breakpoint in main"
 
-for { set r 7 } { $r <= $nr_regs  } { incr r } {
+for { set r 7 } { $r <= 14  } { incr r } {
     gdb_test "print/x \$$byte_regs($r)" \
         ".. = 0x[format %x $r]1" \
         "check contents of %$byte_regs($r)"
@@ -94,6 +104,11 @@ for { set r 1 } { $r <= 6  } { incr r } 
   gdb_test "set var \$$byte_regs($r) = $r" "" "set %$byte_regs($r)"
 }
 
+for { set r 1 } { $r <= 4  } { incr r } {
+  set h [expr $r + 14]
+  gdb_test "set var \$$byte_regs($h) = $h" "" "set %$byte_regs($h)"
+}
+
 gdb_test "break [gdb_get_line_number "third breakpoint here"]" \
          "Breakpoint .* at .*${srcfile}.*" \
          "set third breakpoint in main"
@@ -105,7 +120,14 @@ for { set r 1 } { $r <= 6  } { incr r } 
         "check contents of %$byte_regs($r)"
 }
 
-for { set r 7 } { $r <= $nr_regs  } { incr r } {
+for { set r 1 } { $r <= 4  } { incr r } {
+    set h [expr $r + 14]
+    gdb_test "print \$$byte_regs($h)" \
+        ".. = $h" \
+        "check contents of %$byte_regs($h)"
+}
+
+for { set r 7 } { $r <= 14  } { incr r } {
   gdb_test "set var \$$byte_regs($r) = $r" "" "set %$byte_regs($r)"
 }
 
@@ -114,7 +136,7 @@ gdb_test "break [gdb_get_line_number "fo
          "set forth breakpoint in main"
 gdb_continue_to_breakpoint "continue to forth breakpoint in main"
 
-for { set r 7 } { $r <= $nr_regs  } { incr r } {
+for { set r 7 } { $r <= 14  } { incr r } {
     gdb_test "print \$$byte_regs($r)" \
         ".. = $r" \
         "check contents of %$byte_regs($r)"

gdb-bz578250-avx-10of10.patch:
 bfd/ChangeLog.xstate                    |   14 
 gdb/ChangeLog.avx                       |  306 +++++++
 gdb/ChangeLog.pseudo                    |  189 ++++
 gdb/ChangeLog.xcr                       | 1304 ++++++++++++++++++++++++++++++++
 gdb/ChangeLog.xml                       |  464 +++++++++++
 gdb/ChangeLog.xstate                    |  384 +++++++++
 gdb/amd64-linux-nat.c                   |  123 ++-
 gdb/amd64-linux-tdep.c                  |   42 +
 gdb/amd64-linux-tdep.h                  |    6 
 gdb/amd64-tdep.c                        |  127 +++
 gdb/amd64-tdep.h                        |   20 
 gdb/common/i386-xstate.h                |   41 +
 gdb/config/djgpp/fnchange.lst           |    8 
 gdb/doc/ChangeLog.xcr                   |   31 
 gdb/doc/ChangeLog.xml                   |   28 
 gdb/features/Makefile                   |   12 
 gdb/features/i386/32bit-avx.xml         |   18 
 gdb/features/i386/64bit-avx.xml         |   26 
 gdb/features/i386/Makefile              |    5 
 gdb/features/i386/amd64-avx-linux.c     |  171 ++++
 gdb/features/i386/amd64-avx-linux.xml   |   18 
 gdb/features/i386/amd64-avx.c           |  166 ++++
 gdb/features/i386/amd64-avx.xml         |   16 
 gdb/features/i386/i386-avx-linux.c      |  147 +++
 gdb/features/i386/i386-avx-linux.xml    |   18 
 gdb/features/i386/i386-avx.c            |  142 +++
 gdb/features/i386/i386-avx.xml          |   16 
 gdb/gdbserver/ChangeLog.avx             |   84 ++
 gdb/gdbserver/ChangeLog.xcr             |  373 +++++++++
 gdb/gdbserver/ChangeLog.xml             |   68 +
 gdb/gdbserver/ChangeLog.xstate          |   89 ++
 gdb/gdbserver/Makefile.in               |   14 
 gdb/gdbserver/configure.srv             |   20 
 gdb/gdbserver/i387-fp.c                 |  267 ++++++
 gdb/gdbserver/i387-fp.h                 |    5 
 gdb/gdbserver/linux-arm-low.c           |    8 
 gdb/gdbserver/linux-crisv32-low.c       |    4 
 gdb/gdbserver/linux-low.c               |   55 +
 gdb/gdbserver/linux-low.h               |    6 
 gdb/gdbserver/linux-m68k-low.c          |    6 
 gdb/gdbserver/linux-mips-low.c          |    6 
 gdb/gdbserver/linux-ppc-low.c           |    8 
 gdb/gdbserver/linux-s390-low.c          |    4 
 gdb/gdbserver/linux-sh-low.c            |    4 
 gdb/gdbserver/linux-sparc-low.c         |    6 
 gdb/gdbserver/linux-x86-low.c           |  174 ++++
 gdb/gdbserver/linux-xtensa-low.c        |    6 
 gdb/gdbserver/server.c                  |    5 
 gdb/gdbserver/target.h                  |    7 
 gdb/i386-linux-nat.c                    |  133 +++
 gdb/i386-linux-tdep.c                   |   71 +
 gdb/i386-linux-tdep.h                   |   31 
 gdb/i386-tdep.c                         |  331 +++++++-
 gdb/i386-tdep.h                         |   34 
 gdb/i387-tdep.c                         |  513 ++++++++++++
 gdb/i387-tdep.h                         |   14 
 gdb/regformats/i386/amd64-avx-linux.dat |   78 +
 gdb/regformats/i386/amd64-avx.dat       |   77 +
 gdb/regformats/i386/i386-avx-linux.dat  |   54 +
 gdb/regformats/i386/i386-avx.dat        |   53 +
 gdb/testsuite/ChangeLog.pseudo          |   26 
 gdb/testsuite/ChangeLog.xcr             |    6 
 gdb/testsuite/ChangeLog.xml             |    4 
 gdb/testsuite/gdb.arch/i386-avx.c       |  128 +++
 gdb/testsuite/gdb.arch/i386-avx.exp     |  110 ++
 gdb/testsuite/gdb.arch/i386-cpuid.h     |  235 ++++-
 include/elf/ChangeLog.xstate            |    8 
 67 files changed, 6785 insertions(+), 182 deletions(-)

--- NEW FILE gdb-bz578250-avx-10of10.patch ---
[ Backported.  ]

git://git.kernel.org/pub/scm/devel/gdb/hjl/avx.git
hjl/avxh
aebae36c2a8b73ae51319fff54fc39f220f0824a

--- ./bfd/ChangeLog.xstate	1970-01-01 01:00:00.000000000 +0100
+++ ./bfd/ChangeLog.xstate	2010-04-03 21:12:32.000000000 +0200
@@ -0,0 +1,14 @@
+2010-01-27  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* elf.c (elfcore_grok_note): Replace NT_386_XSTATE with
+	NT_X86_XSTATE.
+	(elfcore_write_xstatereg): Likewise.
+
+2010-01-27  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* elf-bfd.h (elfcore_write_xstatereg): New.
+
+	* elf.c (elfcore_grok_xstatereg): New.
+	(elfcore_write_xstatereg): Likewise.
+	(elfcore_grok_note): Handle NT_386_XSTATE.
+	(elfcore_write_register_note): Handle .reg-xstate section.
--- ./gdb/ChangeLog.avx	1970-01-01 01:00:00.000000000 +0100
+++ ./gdb/ChangeLog.avx	2010-04-03 21:12:32.000000000 +0200
@@ -0,0 +1,306 @@
+2010-03-04  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* common/i386-xstate.h (I386_XSTATE_SSE_MASK_STRING): Removed.
+	(I386_XSTATE_AVX_MASK_STRING): Likewise.
+	(I386_XSTATE_MAX_MASK_STRING): Likewise.
+	(I386_XSTATE_SSE_SIZE_STRING): Likewise.
+	(I386_XSTATE_AVX_SIZE_STRING): Likewise.
+	(I386_XSTATE_MAX_SIZE_STRING): Likewise.
+
+	* i386-tdep.c (i386_gdbarch_init): Replace
+	I386_XSTATE_MAX_SIZE_STRING/I386_XSTATE_MAX_MASK_STRING with
+	I386_XSTATE_MAX_SIZE/I386_XSTATE_MAX_MASK.
+
+2010-03-04  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-tdep.c (amd64_supply_xstateregset): Don't check
+	sizeof_xstateregset.
+	(amd64_collect_xstateregset): Likewise.
+	(amd64_regset_from_core_section): Likewise.
+	(amd64_init_abi): Don't set sizeof_xstateregset.
+
+	* i386-tdep.c (i386_supply_xstateregset): Don't check
+	sizeof_xstateregset.
+	(i386_collect_xstateregset): Likewise.
+	(i386_regset_from_core_section): Likewise.
+	(i386_gdbarch_init): Don't set sizeof_xstateregset.
+
+	* i386-tdep.h (gdbarch_tdep): Remove sizeof_xstateregset.
+
+2010-03-04  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-linux-nat.c (amd64_linux_read_description): Call
+	i386_linux_update_xstateregset.
+	* i386-linux-nat.c (i386_linux_read_description): Likewise.
+
+	* i386-linux-tdep.c (i386_linux_update_xstateregset): New.
+	* i386-linux-tdep.h (i386_linux_update_xstateregset): Likewise.
+
+2010-03-03  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-linux-nat.c (xstate_size): New.
+	(xstate_size_n_of_int64): Likewise.
+	(amd64_linux_fetch_inferior_registers): Updated.
+	(amd64_linux_store_inferior_registers): Likewise.
+	(amd64_linux_read_description): Use I386_XSTATE_SSE_SIZE
+	instead of I386_XSTATE_MAX_SIZE.  Set xstate_size and
+	xstate_size_n_of_int64.
+
+	* i386-linux-nat.c (xstate_size): New.
+	(xstate_size_n_of_int64): Likewise.
+	(fetch_xstateregs): Updated.
+	(store_xstateregs): Likewise.
+	(i386_linux_read_description): Use I386_XSTATE_SSE_SIZE
+	instead of I386_XSTATE_MAX_SIZE.  Set xstate_size and
+	xstate_size_n_of_int64.
+
+	* common/i386-xstate.h (I386_XSTATE_SIZE): New.
+
+2010-03-02  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* config/djgpp/fnchange.lst: Add x86 AVX XML files.
+
+2010-03-02  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-linux-nat.c (XSTATE_MAX_SIZE_N_OF_INT64): New.
+	(amd64_linux_fetch_inferior_registers): Updated.
+	(amd64_linux_store_inferior_registers): Likewise.
+	(amd64_linux_read_description): Likewise.
+	* amd64-linux-tdep.c (amd64_linux_core_read_description): Likewise.
+
+	* i386-linux-nat.c  (XSTATE_MAX_SIZE_N_OF_INT64): New.
+	(fetch_xstateregs): Updated.
+	(store_xstateregs): Likewise.
+	(i386_linux_read_description): Likewise.
+
+	* i386-linux-tdep.c (i386_linux_core_read_xcr0): Updated.
+	(i386_linux_core_read_xcr0): Likewise.
+	(i386_linux_core_read_description): Likewise.
+
+	* i386-tdep.c (i386_register_reggroup_p): Updated.
+	(i386_validate_tdesc_p): Likewise.
+	(i386_gdbarch_init): Likewise.
+
+	* i387-tdep.c (i387_supply_fxsave): Updated.
+	(i387_collect_xsave): Likewise.
+
+	* common/i386-xstate.h: Change XSTATE to I386_XSTATE in macros.
+
+2010-03-02  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* Makefile.in (i386-xstate.o): Removed.
+
+	* amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Use
+	XSTATE_MAX_SIZE_N_OF_INT64 and XSTATE_MAX_SIZE.
+	(amd64_linux_store_inferior_registers): Likewise.
+	(amd64_linux_read_description): Add static xcr0 and get it
+	from I386_LINUX_XSAVE_XCR0_OFFSET.  Use XSTATE_MAX_SIZE_N_OF_INT64
+	and XSTATE_MAX_SIZE.
+	(_initialize_amd64_linux_nat): Don't call i386_xstate_init.
+
+	* configure.ac: Remove check for cpuid.h.
+	* config.in: Regenerated.
+	* configure: Likewise.
+
+	* i386-linux-nat.c (fetch_xstateregs): Use
+	XSTATE_MAX_SIZE_N_OF_INT64 and XSTATE_MAX_SIZE.
+	(store_xstateregs): Likewise.
+	(i386_linux_read_description): Add static xcr0 and get it
+	from I386_LINUX_XSAVE_XCR0_OFFSET.  Use XSTATE_MAX_SIZE_N_OF_INT64
+	and XSTATE_MAX_SIZE.
+	(_initialize_i386_linux_nat): Don't call i386_xstate_init.
+
+	* common/i386-cpuid.h: Removed.
+	* common/i386-xstate.c: Likewise.
+
+	* common/i386-xstate.h (xstate_status): Removed.
+	(i386_xstate_type): Likewise.
+	(i386_xstate): Likewise.
+	(i386_xstate_init): Likewise.
+	(XSTATE_MAX_SIZE_N_OF_INT64): New.
+
+	* config/i386/linux.mh (NATDEPFILES): Remove i386-xstate.o.
+	* config/i386/linux64.mh (NATDEPFILES): Likewise.
+
+2010-02-01  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-linux-tdep.c (amd64_linux_g_packet_size): Make it const.
+	* amd64-tdep.c (amd64_g_packet_size): Likewise.
+	* i386-linux-tdep.c (i386_linux_g_packet_size): Likewise.
+	* i386-tdep.c (i386_g_packet_size): Likewise.
+
+	* i386-linux-tdep.c (i386_linux_init_abi): Remove
+	i386_linux_g_packet_size.
+
+	* i386-tdep.c (i386_register_g_packet_guesses): Updated.
+	* i386-tdep.h (i386_register_g_packet_guesses): Likewise.
+
+2010-02-01  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* amd64-linux-tdep.c (amd64_linux_g_packet_size): Add key.
+	* i386-linux-tdep.c (i386_linux_g_packet_size): Likewise.
+	* i386-tdep.c (i386_g_packet_size): Likewise.
+
+	* amd64-tdep.c (amd64_g_packet_size): New.
+	(amd64_init_abi): Call i386_register_g_packet_guesses.
+
+	* i386-tdep.c (I386_PROPERTY_SSE): Removed.
+	(I386_PROPERTY_AVX): Likewise.
+	(i386_tdesc_sse): Likewise.
+	(i386_tdesc_avx): Likewise.
+	(i386_init_tdesc): Likewise.
+	(i386_register_g_packet_guesses): Updated.
+	(i386_gdbarch_vector_unit_init): Likewise.
+
+	* i386-tdep.h (I386_PROPERTY_SSE): New.
+	(I386_PROPERTY_AVX): Likewise.
+	(AMD64_PROPERTY_SSE): Likewise.
+	(AMD64_PROPERTY_AVX): Likewise.
+	(i386_g_packet_size): Add key.
+	(i386_register_g_packet_guesses): Updated.
+
+2010-01-31  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* regformats/reg-i386-avx-linux.dat: Add a comment for osabi.
+	* regformats/reg-x86-64-avx-linux.dat: Likewise.
+
+2010-01-31  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* regformats/reg-i386-avx-linux.dat: Add a comment for xmlarch.
+	* regformats/reg-i386-avx.dat: Likewise.
+	* regformats/reg-x86-64-avx-linux.dat: Likewise.
+	* regformats/reg-x86-64-avx.dat: Likewise.
+
[...7872 lines suppressed...]
+
+#if defined(__i386__) && defined(__PIC__)
+/* %ebx may be the PIC register.  */
+#if __GNUC__ >= 3
+#define __cpuid(level, a, b, c, d)			\
+  __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchg{l}\t{%%}ebx, %1\n\t"			\
+	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d)		\
+  __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchg{l}\t{%%}ebx, %1\n\t"			\
+	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level), "2" (count))
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+   nor alternatives in i386 code.  */
+#define __cpuid(level, a, b, c, d)			\
+  __asm__ ("xchgl\t%%ebx, %1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchgl\t%%ebx, %1\n\t"			\
+	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d)		\
+  __asm__ ("xchgl\t%%ebx, %1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchgl\t%%ebx, %1\n\t"			\
+	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level), "2" (count))
+#endif
+#else
+#define __cpuid(level, a, b, c, d)			\
+  __asm__ ("cpuid\n\t"					\
+	   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d)		\
+  __asm__ ("cpuid\n\t"					\
+	   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level), "2" (count))
+#endif
+
+/* Return highest supported input value for cpuid instruction.  ext can
+   be either 0x0 or 0x8000000 to return highest supported value for
+   basic or extended cpuid information.  Function returns 0 if cpuid
+   is not supported or whatever cpuid returns in eax register.  If sig
+   pointer is non-null, then first four bytes of the signature
+   (as found in ebx register) are returned in location pointed by sig.  */
+
+static __inline unsigned int
+__get_cpuid_max (unsigned int __ext, unsigned int *__sig)
+{
+  unsigned int __eax, __ebx, __ecx, __edx;
+
+#ifndef __x86_64__
+#if __GNUC__ >= 3
+  /* See if we can use cpuid.  On AMD64 we always can.  */
+  __asm__ ("pushf{l|d}\n\t"
+	   "pushf{l|d}\n\t"
+	   "pop{l}\t%0\n\t"
+	   "mov{l}\t{%0, %1|%1, %0}\n\t"
+	   "xor{l}\t{%2, %0|%0, %2}\n\t"
+	   "push{l}\t%0\n\t"
+	   "popf{l|d}\n\t"
+	   "pushf{l|d}\n\t"
+	   "pop{l}\t%0\n\t"
+	   "popf{l|d}\n\t"
+	   : "=&r" (__eax), "=&r" (__ebx)
+	   : "i" (0x00200000));
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+   nor alternatives in i386 code.  */
+  __asm__ ("pushfl\n\t"
+	   "pushfl\n\t"
+	   "popl\t%0\n\t"
+	   "movl\t%0, %1\n\t"
+	   "xorl\t%2, %0\n\t"
+	   "pushl\t%0\n\t"
+	   "popfl\n\t"
+	   "pushfl\n\t"
+	   "popl\t%0\n\t"
+	   "popfl\n\t"
+	   : "=&r" (__eax), "=&r" (__ebx)
+	   : "i" (0x00200000));
+#endif
 
-   Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+  if (!((__eax ^ __ebx) & 0x00200000))
+    return 0;
+#endif
 
-   This file is part of GDB.
+  /* Host supports cpuid.  Return highest supported cpuid input value.  */
+  __cpuid (__ext, __eax, __ebx, __ecx, __edx);
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
+  if (__sig)
+    *__sig = __ebx;
 
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+  return __eax;
+}
 
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+/* Return cpuid data for requested cpuid level, as found in returned
+   eax, ebx, ecx and edx registers.  The function checks if cpuid is
+   supported and returns 1 for valid cpuid information or 0 for
+   unsupported cpuid level.  All pointers are required to be non-null.  */
+
+static __inline int
+__get_cpuid (unsigned int __level,
+	     unsigned int *__eax, unsigned int *__ebx,
+	     unsigned int *__ecx, unsigned int *__edx)
+{
+  unsigned int __ext = __level & 0x80000000;
 
-/* Used by 20020523-2.c and i386-sse-6.c, and possibly others.  */
-/* Plagarized from 20020523-2.c.  */
-/* Plagarized from gcc.  */
+  if (__get_cpuid_max (__ext, 0) < __level)
+    return 0;
 
-#define bit_CMOV (1 << 15)
-#define bit_MMX (1 << 23)
-#define bit_SSE (1 << 25)
-#define bit_SSE2 (1 << 26)
+  __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
+  return 1;
+}
 
 #ifndef NOINLINE
 #define NOINLINE __attribute__ ((noinline))
@@ -35,41 +191,10 @@ unsigned int i386_cpuid (void) NOINLINE;
 unsigned int NOINLINE
 i386_cpuid (void)
 {
-  int fl1, fl2;
-
-#ifndef __x86_64__
-  /* See if we can use cpuid.  On AMD64 we always can.  */
-  __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
-	   "pushl %0; popfl; pushfl; popl %0; popfl"
-	   : "=&r" (fl1), "=&r" (fl2)
-	   : "i" (0x00200000));
-  if (((fl1 ^ fl2) & 0x00200000) == 0)
-    return (0);
-#endif
+  unsigned int eax, ebx, ecx, edx;
 
-  /* Host supports cpuid.  See if cpuid gives capabilities, try
-     CPUID(0).  Preserve %ebx and %ecx; cpuid insn clobbers these, we
-     don't need their CPUID values here, and %ebx may be the PIC
-     register.  */
-#ifdef __x86_64__
-  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
-	   : "=a" (fl1) : "0" (0) : "rdx", "cc");
-#else
-  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
-	   : "=a" (fl1) : "0" (0) : "edx", "cc");
-#endif
-  if (fl1 == 0)
-    return (0);
-
-  /* Invoke CPUID(1), return %edx; caller can examine bits to
-     determine what's supported.  */
-#ifdef __x86_64__
-  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
-	   : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
-#else
-  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
-	   : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
-#endif
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
 
-  return fl2;
+  return edx;
 }
--- ./include/elf/ChangeLog.xstate	1970-01-01 01:00:00.000000000 +0100
+++ ./include/elf/ChangeLog.xstate	2010-04-03 21:12:32.000000000 +0200
@@ -0,0 +1,8 @@
+2010-01-27  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* common.h (NT_386_XSTATE): Renamed to ...
+	(NT_X86_XSTATE): This.
+
+2010-01-27  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* common.h (NT_386_XSTATE): New.


Index: gdb.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/F-13/gdb.spec,v
retrieving revision 1.423
retrieving revision 1.424
diff -u -p -r1.423 -r1.424
--- gdb.spec	3 Apr 2010 10:24:55 -0000	1.423
+++ gdb.spec	3 Apr 2010 21:07:04 -0000	1.424
@@ -36,7 +36,7 @@ Version: 7.1
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 5%{?_with_upstream:.upstream}%{dist}
+Release: 6%{?_with_upstream:.upstream}%{dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and GFDL and BSD and Public Domain
 Group: Development/Debuggers
@@ -444,6 +444,18 @@ Patch437: gdb-using-directive-leak.patch
 # Fix dangling displays in separate debuginfo (BZ 574483).
 Patch438: gdb-bz574483-display-sepdebug.patch
 
+# Support AVX registers (BZ 578250).
+Patch439: gdb-bz578250-avx-01of10.patch
+Patch440: gdb-bz578250-avx-02of10.patch
+Patch441: gdb-bz578250-avx-03of10.patch
+Patch442: gdb-bz578250-avx-04of10.patch
+Patch443: gdb-bz578250-avx-05of10.patch
+Patch444: gdb-bz578250-avx-06of10.patch
+Patch445: gdb-bz578250-avx-07of10.patch
+Patch446: gdb-bz578250-avx-08of10.patch
+Patch447: gdb-bz578250-avx-09of10.patch
+Patch448: gdb-bz578250-avx-10of10.patch
+
 BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa}
 Requires: readline%{?_isa}
 BuildRequires: readline-devel%{?_isa}
@@ -699,6 +711,16 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc
 %patch436 -p1
 %patch437 -p1
 %patch438 -p1
+%patch439 -p1
+%patch440 -p1
+%patch441 -p1
+%patch442 -p1
+%patch443 -p1
+%patch444 -p1
+%patch445 -p1
+%patch446 -p1
+%patch447 -p1
+%patch448 -p1
 
 %patch415 -p1
 %patch393 -p1
@@ -1031,6 +1053,9 @@ fi
 %endif
 
 %changelog
+* Sat Apr  3 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.1-6.fc13
+- Support AVX registers (BZ 578250).
+
 * Sat Apr  3 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.1-5.fc13
 - Fix dangling displays in separate debuginfo (BZ 574483).
 



More information about the scm-commits mailing list