diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b2a9b91cea5..340b66bd16f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2013-06-19  Mike Frysinger  <vapier@gentoo.org>
+
+	* Makefile.in (HFILES_NO_SRCDIR): Add common/i386-cpuid.h and
+	common/i386-gcc-cpuid.h.
+	* common/i386-cpuid.h: New wrapper header around i386-gcc-cpuid.h.
+	* common/i386-gcc-cpuid.h: Rename from testsuite/gdb.arch/i386-cpuid.h.
+	Copy the latest version from upstream gcc.
+	* common/linux-btrace.c: Include i386-cpuid.h.
+	(intel_supports_btrace): Delete x86 ifdefs and replace inline asm with
+	call to i386_cpuid.
+	(cpu_supports_btrace): Likewise.
+	* go32-nat.c: Include i386-cpuid.h.
+	(go32_sysinfo): Add (disabled) calls to i386_cpuid with comments.
+
 2013-06-19  Doug Evans  <dje@google.com>
 
 	* symfile.c (symfile_bfd_open): Delete unnecessary declaration.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a6336a291d8..71058e509e6 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -850,7 +850,7 @@ common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
 common/format.h common/host-defs.h utils.h common/queue.h common/gdb_string.h \
 common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
 gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h common/linux-btrace.h \
-ctf.h
+ctf.h common/i386-cpuid.h common/i386-gcc-cpuid.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
diff --git a/gdb/common/i386-cpuid.h b/gdb/common/i386-cpuid.h
new file mode 100644
index 00000000000..8bb28c533d3
--- /dev/null
+++ b/gdb/common/i386-cpuid.h
@@ -0,0 +1,63 @@
+/* C API for x86 cpuid insn.
+   Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This file 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, 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/>.  */
+
+#ifndef I386_CPUID_COMMON_H
+#define I386_CPUID_COMMON_H
+
+/* Always include the header for the cpu bit defines.  */
+#include "i386-gcc-cpuid.h"
+
+#if defined(__i386__) || defined(__x86_64__)
+
+/* 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.  Pointers may be non-null.  */
+
+static __inline int
+i386_cpuid (unsigned int __level,
+	    unsigned int *__eax, unsigned int *__ebx,
+	    unsigned int *__ecx, unsigned int *__edx)
+{
+  unsigned int __scratch;
+
+  if (!__eax)
+    __eax = &__scratch;
+  if (!__ebx)
+    __ebx = &__scratch;
+  if (!__ecx)
+    __ecx = &__scratch;
+  if (!__edx)
+    __edx = &__scratch;
+
+  return __get_cpuid (__level, __eax, __ebx, __ecx, __edx);
+}
+
+#else
+
+static __inline int
+i386_cpuid (unsigned int __level,
+	    unsigned int *__eax, unsigned int *__ebx,
+	    unsigned int *__ecx, unsigned int *__edx)
+{
+  return 0;
+}
+
+#endif /* i386 && x86_64 */
+
+#endif /* I386_CPUID_COMMON_H */
diff --git a/gdb/testsuite/gdb.arch/i386-cpuid.h b/gdb/common/i386-gcc-cpuid.h
similarity index 59%
rename from gdb/testsuite/gdb.arch/i386-cpuid.h
rename to gdb/common/i386-gcc-cpuid.h
index 084a083006c..e045ba83bed 100644
--- a/gdb/testsuite/gdb.arch/i386-cpuid.h
+++ b/gdb/common/i386-gcc-cpuid.h
@@ -1,6 +1,8 @@
-/* Helper file for i386 platform.  Runtime check for MMX/SSE/SSE2/AVX
- * support. Copied from gcc 4.4.
- *
+/*
+ * Helper cpuid.h file copied from gcc-4.8.0.  Code in gdb should not
+ * include this directly, but pull in i386-cpuid.h and use that func.
+ */
+/*
  * Copyright (C) 2007-2013 Free Software Foundation, Inc.
  *
  * This file is free software; you can redistribute it and/or modify it
@@ -26,6 +28,7 @@
 /* %ecx */
 #define bit_SSE3	(1 << 0)
 #define bit_PCLMUL	(1 << 1)
+#define bit_LZCNT	(1 << 5)
 #define bit_SSSE3	(1 << 9)
 #define bit_FMA		(1 << 12)
 #define bit_CMPXCHG16B	(1 << 13)
@@ -37,6 +40,8 @@
 #define bit_XSAVE	(1 << 26)
 #define bit_OSXSAVE	(1 << 27)
 #define bit_AVX		(1 << 28)
+#define bit_F16C	(1 << 29)
+#define bit_RDRND	(1 << 30)
 
 /* %edx */
 #define bit_CMPXCHG8B	(1 << 8)
@@ -51,49 +56,133 @@
 #define bit_LAHF_LM	(1 << 0)
 #define bit_ABM		(1 << 5)
 #define bit_SSE4a	(1 << 6)
+#define bit_PRFCHW	(1 << 8)
 #define bit_XOP         (1 << 11)
 #define bit_LWP 	(1 << 15)
 #define bit_FMA4        (1 << 16)
+#define bit_TBM         (1 << 21)
 
 /* %edx */
+#define bit_MMXEXT	(1 << 22)
 #define bit_LM		(1 << 29)
 #define bit_3DNOWP	(1 << 30)
 #define bit_3DNOW	(1 << 31)
 
+/* Extended Features (%eax == 7) */
+#define bit_FSGSBASE	(1 << 0)
+#define bit_BMI	(1 << 3)
+#define bit_HLE	(1 << 4)
+#define bit_AVX2	(1 << 5)
+#define bit_BMI2	(1 << 8)
+#define bit_RTM	(1 << 11)
+#define bit_RDSEED	(1 << 18)
+#define bit_ADX	(1 << 19)
+
+/* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */
+#define bit_XSAVEOPT	(1 << 0)
+
+/* Signatures for different CPU implementations as returned in uses
+   of cpuid with level 0.  */
+#define signature_AMD_ebx	0x68747541
+#define signature_AMD_ecx	0x444d4163
+#define signature_AMD_edx	0x69746e65
+
+#define signature_CENTAUR_ebx	0x746e6543
+#define signature_CENTAUR_ecx	0x736c7561
+#define signature_CENTAUR_edx	0x48727561
+
+#define signature_CYRIX_ebx	0x69727943
+#define signature_CYRIX_ecx	0x64616574
+#define signature_CYRIX_edx	0x736e4978
+
+#define signature_INTEL_ebx	0x756e6547
+#define signature_INTEL_ecx	0x6c65746e
+#define signature_INTEL_edx	0x49656e69
+
+#define signature_TM1_ebx	0x6e617254
+#define signature_TM1_ecx	0x55504361
+#define signature_TM1_edx	0x74656d73
+
+#define signature_TM2_ebx	0x756e6547
+#define signature_TM2_ecx	0x3638784d
+#define signature_TM2_edx	0x54656e69
+
+#define signature_NSC_ebx	0x646f6547
+#define signature_NSC_ecx	0x43534e20
+#define signature_NSC_edx	0x79622065
+
+#define signature_NEXGEN_ebx	0x4778654e
+#define signature_NEXGEN_ecx	0x6e657669
+#define signature_NEXGEN_edx	0x72446e65
+
+#define signature_RISE_ebx	0x65736952
+#define signature_RISE_ecx	0x65736952
+#define signature_RISE_edx	0x65736952
+
+#define signature_SIS_ebx	0x20536953
+#define signature_SIS_ecx	0x20536953
+#define signature_SIS_edx	0x20536953
+
+#define signature_UMC_ebx	0x20434d55
+#define signature_UMC_ecx	0x20434d55
+#define signature_UMC_edx	0x20434d55
+
+#define signature_VIA_ebx	0x20414956
+#define signature_VIA_ecx	0x20414956
+#define signature_VIA_edx	0x20414956
+
+#define signature_VORTEX_ebx	0x74726f56
+#define signature_VORTEX_ecx	0x436f5320
+#define signature_VORTEX_edx	0x36387865
 
 #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"			\
+  __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t"			\
 	   "cpuid\n\t"					\
-	   "xchg{l}\t{%%}ebx, %1\n\t"			\
-	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   "xchg{l}\t{%%}ebx, %k1\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"			\
+  __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t"			\
 	   "cpuid\n\t"					\
-	   "xchg{l}\t{%%}ebx, %1\n\t"			\
-	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   "xchg{l}\t{%%}ebx, %k1\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"			\
+  __asm__ ("xchgl\t%%ebx, %k1\n\t"			\
 	   "cpuid\n\t"					\
-	   "xchgl\t%%ebx, %1\n\t"			\
-	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   "xchgl\t%%ebx, %k1\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"			\
+  __asm__ ("xchgl\t%%ebx, %k1\n\t"			\
 	   "cpuid\n\t"					\
-	   "xchgl\t%%ebx, %1\n\t"			\
-	   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\
+	   "xchgl\t%%ebx, %k1\n\t"			\
+	   : "=a" (a), "=&r" (b), "=c" (c), "=d" (d)	\
 	   : "0" (level), "2" (count))
 #endif
+#elif defined(__x86_64__) && (defined(__code_model_medium__) || defined(__code_model_large__)) && defined(__PIC__)
+/* %rbx may be the PIC register.  */
+#define __cpuid(level, a, b, c, d)			\
+  __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchg{q}\t{%%}rbx, %q1\n\t"			\
+	   : "=a" (a), "=&r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d)		\
+  __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t"			\
+	   "cpuid\n\t"					\
+	   "xchg{q}\t{%%}rbx, %q1\n\t"			\
+	   : "=a" (a), "=&r" (b), "=c" (c), "=d" (d)	\
+	   : "0" (level), "2" (count))
 #else
 #define __cpuid(level, a, b, c, d)			\
   __asm__ ("cpuid\n\t"					\
@@ -118,9 +207,9 @@ __get_cpuid_max (unsigned int __ext, unsigned int *__sig)
 {
   unsigned int __eax, __ebx, __ecx, __edx;
 
-#ifndef __x86_64__
-#if __GNUC__ >= 3
+#ifdef __i386__
   /* See if we can use cpuid.  On AMD64 we always can.  */
+#if __GNUC__ >= 3
   __asm__ ("pushf{l|d}\n\t"
 	   "pushf{l|d}\n\t"
 	   "pop{l}\t%0\n\t"
@@ -181,20 +270,3 @@ __get_cpuid (unsigned int __level,
   __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
   return 1;
 }
-
-#ifndef NOINLINE
-#define NOINLINE __attribute__ ((noinline))
-#endif
-
-unsigned int i386_cpuid (void) NOINLINE;
-
-unsigned int NOINLINE
-i386_cpuid (void)
-{
-  unsigned int eax, ebx, ecx, edx;
-
-  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
-    return 0;
-
-  return edx;
-}
diff --git a/gdb/common/linux-btrace.c b/gdb/common/linux-btrace.c
index 1f9a00188a4..0ec13bbb029 100644
--- a/gdb/common/linux-btrace.c
+++ b/gdb/common/linux-btrace.c
@@ -31,6 +31,7 @@
 #include "regcache.h"
 #include "gdbthread.h"
 #include "gdb_wait.h"
+#include "i386-cpuid.h"
 
 #if HAVE_LINUX_PERF_EVENT_H
 
@@ -339,13 +340,10 @@ kernel_supports_btrace (void)
 static int
 intel_supports_btrace (void)
 {
-#if defined __i386__ || defined __x86_64__
   unsigned int cpuid, model, family;
 
-  __asm__ __volatile__ ("movl   $1, %%eax;"
-			"cpuid;"
-			: "=a" (cpuid)
-			:: "%ebx", "%ecx", "%edx");
+  if (!i386_cpuid (1, &cpuid, NULL, NULL, NULL))
+    return 0;
 
   family = (cpuid >> 8) & 0xf;
   model = (cpuid >> 4) & 0xf;
@@ -376,12 +374,6 @@ intel_supports_btrace (void)
     }
 
   return 1;
-
-#else /* !defined __i386__ && !defined __x86_64__ */
-
-  return 0;
-
-#endif /* !defined __i386__ && !defined __x86_64__ */
 }
 
 /* Check whether the cpu supports branch tracing.  */
@@ -389,22 +381,15 @@ intel_supports_btrace (void)
 static int
 cpu_supports_btrace (void)
 {
-#if defined __i386__ || defined __x86_64__
+  unsigned int ebx, ecx, edx;
   char vendor[13];
 
-  __asm__ __volatile__ ("xorl   %%ebx, %%ebx;"
-			"xorl   %%ecx, %%ecx;"
-			"xorl   %%edx, %%edx;"
-			"movl   $0,    %%eax;"
-			"cpuid;"
-			"movl   %%ebx,  %0;"
-			"movl   %%edx,  %1;"
-			"movl   %%ecx,  %2;"
-			: "=m" (vendor[0]),
-			  "=m" (vendor[4]),
-			  "=m" (vendor[8])
-			:
-			: "%eax", "%ebx", "%ecx", "%edx");
+  if (!i386_cpuid (0, NULL, &ebx, &ecx, &edx))
+    return 0;
+
+  memcpy (&vendor[0], &ebx, 4);
+  memcpy (&vendor[4], &ecx, 4);
+  memcpy (&vendor[8], &edx, 4);
   vendor[12] = '\0';
 
   if (strcmp (vendor, "GenuineIntel") == 0)
@@ -412,12 +397,6 @@ cpu_supports_btrace (void)
 
   /* Don't know about others.  Let's assume they do.  */
   return 1;
-
-#else /* !defined __i386__ && !defined __x86_64__ */
-
-  return 0;
-
-#endif /* !defined __i386__ && !defined __x86_64__ */
 }
 
 /* See linux-btrace.h.  */
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index 0d9bb9d574b..a3f75b29a00 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -96,6 +96,7 @@
 #include "buildsym.h"
 #include "i387-tdep.h"
 #include "i386-tdep.h"
+#include "i386-cpuid.h"
 #include "value.h"
 #include "regcache.h"
 #include "gdb_string.h"
@@ -1141,6 +1142,21 @@ go32_sysinfo (char *arg, int from_tty)
   else if (u.machine[0] == 'i' && u.machine[1] > 4)
     {
       /* CPUID with EAX = 0 returns the Vendor ID.  */
+#if 0
+      /* Ideally we would use i386_cpuid(), but it needs someone to run
+         native tests first to make sure things actually work.  They should.
+         http://sourceware.org/ml/gdb-patches/2013-05/msg00164.html  */
+      unsigned int eax, ebx, ecx, edx;
+
+      if (i386_cpuid (0, &eax, &ebx, &ecx, &edx))
+	{
+	  cpuid_max = eax;
+	  memcpy (&vendor[0], &ebx, 4);
+	  memcpy (&vendor[4], &ecx, 4);
+	  memcpy (&vendor[8], &edx, 4);
+	  cpuid_vendor[12] = '\0';
+	}
+#else
       __asm__ __volatile__ ("xorl   %%ebx, %%ebx;"
 			    "xorl   %%ecx, %%ecx;"
 			    "xorl   %%edx, %%edx;"
@@ -1157,6 +1173,7 @@ go32_sysinfo (char *arg, int from_tty)
 			    :
 			    : "%eax", "%ebx", "%ecx", "%edx");
       cpuid_vendor[12] = '\0';
+#endif
     }
 
   printf_filtered ("CPU Type.......................%s", u.machine);
@@ -1182,6 +1199,10 @@ go32_sysinfo (char *arg, int from_tty)
       int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
       unsigned cpu_family, cpu_model;
 
+#if 0
+      /* See comment above about cpuid usage.  */
+      i386_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
+#else
       __asm__ __volatile__ ("movl   $1, %%eax;"
 			    "cpuid;"
 			    : "=a" (cpuid_eax),
@@ -1189,6 +1210,7 @@ go32_sysinfo (char *arg, int from_tty)
 			      "=d" (cpuid_edx)
 			    :
 			    : "%ecx");
+#endif
       brand_idx = cpuid_ebx & 0xff;
       cpu_family = (cpuid_eax >> 8) & 0xf;
       cpu_model  = (cpuid_eax >> 4) & 0xf;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7fb31d47127..5e359e220b9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2013-06-19  Mike Frysinger  <vapier@gentoo.org>
+
+	* gdb.arch/i386-avx.c (have_avx): Change __get_cpuid call to i386_cpuid.
+	* gdb.arch/i386-avx.exp (additional_flags): Add -I${srcdir}/../common.
+	* gdb.arch/i386-cpuid.h: Moved to ../common/i386-gcc-cpuid.h.
+	* gdb.arch/i386-sse.c: Call new i386_cpuid function.
+	* gdb.arch/i386-see.exp (additional_flags): Add -I${srcdir}/../common.
+
 2013-06-19  Luis Machado  <lgustavo@codesourcery.com>
 
 	* gdb.base/subst.exp: Delete default rules before further
diff --git a/gdb/testsuite/gdb.arch/i386-avx.c b/gdb/testsuite/gdb.arch/i386-avx.c
index bcfa18fb0e5..7fd12172c39 100644
--- a/gdb/testsuite/gdb.arch/i386-avx.c
+++ b/gdb/testsuite/gdb.arch/i386-avx.c
@@ -53,7 +53,7 @@ have_avx (void)
 {
   unsigned int eax, ebx, ecx, edx;
 
-  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+  if (!i386_cpuid (1, &eax, &ebx, &ecx, &edx))
     return 0;
 
   if ((ecx & (bit_AVX | bit_OSXSAVE)) == (bit_AVX | bit_OSXSAVE))
diff --git a/gdb/testsuite/gdb.arch/i386-avx.exp b/gdb/testsuite/gdb.arch/i386-avx.exp
index 964806cfb4d..bbbc6f4ed4f 100644
--- a/gdb/testsuite/gdb.arch/i386-avx.exp
+++ b/gdb/testsuite/gdb.arch/i386-avx.exp
@@ -34,7 +34,7 @@ if [get_compiler_info] {
 
 set additional_flags ""
 if [test_compiler_info gcc*] {
-    set additional_flags "additional_flags=-mavx"
+    set additional_flags "additional_flags=-mavx -I${srcdir}/../common"
 }
 
 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } {
diff --git a/gdb/testsuite/gdb.arch/i386-sse.c b/gdb/testsuite/gdb.arch/i386-sse.c
index d4315275265..8617c8ad36c 100644
--- a/gdb/testsuite/gdb.arch/i386-sse.c
+++ b/gdb/testsuite/gdb.arch/i386-sse.c
@@ -51,7 +51,10 @@ v4sf_t data[] =
 int
 have_sse (void)
 {
-  int edx = i386_cpuid ();
+  int edx;
+
+  if (!i386_cpuid (1, NULL, NULL, NULL, &edx))
+    return 0;
 
   if (edx & bit_SSE)
     return 1;
diff --git a/gdb/testsuite/gdb.arch/i386-sse.exp b/gdb/testsuite/gdb.arch/i386-sse.exp
index 5923ecae9a9..c62a3a0b86e 100644
--- a/gdb/testsuite/gdb.arch/i386-sse.exp
+++ b/gdb/testsuite/gdb.arch/i386-sse.exp
@@ -34,7 +34,7 @@ if [get_compiler_info] {
 
 set additional_flags ""
 if [test_compiler_info gcc*] {
-    set additional_flags "additional_flags=-msse"
+    set additional_flags "additional_flags=-msse -I${srcdir}/../common"
 }
 
 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } {