diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index d6eed2f..d82e95a 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -624,6 +624,8 @@ end arch iwmmxt2
 #   [option <name> add|remove <isa-list>]*
 #   [optalias <name> <optname>]*
 #   [costs <name>]
+#   [vendor <vendor-id>
+#    [part <part-id> [minrev [maxrev]]]
 # end cpu <name>
 #
 # If omitted, cname is formed from transforming the cpuname to convert
@@ -633,6 +635,14 @@ end arch iwmmxt2
 # Each add option must have a distinct feature set and each remove
 # option must similarly have a distinct feature set.  Option aliases can be
 # added with the optalias statement.
+# Vendor, part and revision information is used for native CPU and architecture
+# detection.  All values must be in hex (lower case) with the leading '0x'
+# omitted.  For example the cortex-a9 will have vendor 41 and part c09.
+# Revision information is used to match a subrange of part
+# revisions: minrev <= detected <= maxrev.
+# If a minrev or maxrev are omitted then minrev defaults to zero and maxrev
+# to infinity.
+# Revision information is not implemented yet; no part uses it.
 
 # V4 Architecture Processors
 begin cpu arm8
@@ -878,6 +888,8 @@ begin cpu arm926ej-s
  architecture armv5tej+fp
  option nofp remove ALL_FP
  costs 9e
+ vendor 41
+ part 926
 end cpu arm926ej-s
 
 begin cpu arm1026ej-s
@@ -886,6 +898,8 @@ begin cpu arm1026ej-s
  architecture armv5tej+fp
  option nofp remove ALL_FP
  costs 9e
+ vendor 41
+ part a26
 end cpu arm1026ej-s
 
 
@@ -902,6 +916,8 @@ begin cpu arm1136jf-s
  tune flags LDSCHED
  architecture armv6j+fp
  costs 9e
+ vendor 41
+ part b36
 end cpu arm1136jf-s
 
 begin cpu arm1176jz-s
@@ -916,6 +932,8 @@ begin cpu arm1176jzf-s
  tune flags LDSCHED
  architecture armv6kz+fp
  costs 9e
+ vendor 41
+ part b76
 end cpu arm1176jzf-s
 
 begin cpu mpcorenovfp
@@ -928,6 +946,8 @@ begin cpu mpcore
  tune flags LDSCHED
  architecture armv6k+fp
  costs 9e
+ vendor 41
+ part b02
 end cpu mpcore
 
 begin cpu arm1156t2-s
@@ -942,6 +962,8 @@ begin cpu arm1156t2f-s
  tune flags LDSCHED
  architecture armv6t2+fp
  costs v6t2
+ vendor 41
+ part b56
 end cpu arm1156t2f-s
 
 
@@ -951,6 +973,8 @@ begin cpu cortex-m1
  tune flags LDSCHED
  architecture armv6s-m
  costs v6m
+ vendor 41
+ part c21
 end cpu cortex-m1
 
 begin cpu cortex-m0
@@ -958,6 +982,8 @@ begin cpu cortex-m0
  tune flags LDSCHED
  architecture armv6s-m
  costs v6m
+ vendor 41
+ part c20
 end cpu cortex-m0
 
 begin cpu cortex-m0plus
@@ -1022,6 +1048,8 @@ begin cpu cortex-a5
  option nosimd remove ALL_SIMD
  option nofp remove ALL_FP
  costs cortex_a5
+ vendor 41
+ part c05
 end cpu cortex-a5
 
 begin cpu cortex-a7
@@ -1031,6 +1059,8 @@ begin cpu cortex-a7
  option nosimd remove ALL_SIMD
  option nofp remove ALL_FP
  costs cortex_a7
+ vendor 41
+ part c07
 end cpu cortex-a7
 
 begin cpu cortex-a8
@@ -1039,6 +1069,8 @@ begin cpu cortex-a8
  architecture armv7-a+simd
  option nofp remove ALL_FP
  costs cortex_a8
+ vendor 41
+ part c08
 end cpu cortex-a8
 
 begin cpu cortex-a9
@@ -1048,6 +1080,8 @@ begin cpu cortex-a9
  option nosimd remove ALL_SIMD
  option nofp remove ALL_FP
  costs cortex_a9
+ vendor 41
+ part c09
 end cpu cortex-a9
 
 begin cpu cortex-a12
@@ -1057,6 +1091,8 @@ begin cpu cortex-a12
  architecture armv7ve+simd
  option nofp remove ALL_FP
  costs cortex_a12
+ vendor 41
+ part c0d
 end cpu cortex-a12
 
 begin cpu cortex-a15
@@ -1065,6 +1101,8 @@ begin cpu cortex-a15
  architecture armv7ve+simd
  option nofp remove ALL_FP
  costs cortex_a15
+ vendor 41
+ part c0f
 end cpu cortex-a15
 
 begin cpu cortex-a17
@@ -1073,6 +1111,8 @@ begin cpu cortex-a17
  architecture armv7ve+simd
  option nofp remove ALL_FP
  costs cortex_a12
+ vendor 41
+ part c0e
 end cpu cortex-a17
 
 begin cpu cortex-r4
@@ -1087,6 +1127,8 @@ begin cpu cortex-r4f
  tune flags LDSCHED
  architecture armv7-r+fp
  costs cortex
+ vendor 41
+ part c14
 end cpu cortex-r4f
 
 begin cpu cortex-r5
@@ -1096,6 +1138,8 @@ begin cpu cortex-r5
  option nofp.dp remove FP_DBL
  option nofp remove ALL_FP
  costs cortex
+ vendor 41
+ part c15
 end cpu cortex-r5
 
 begin cpu cortex-r7
@@ -1104,6 +1148,8 @@ begin cpu cortex-r7
  architecture armv7-r+idiv+fp
  option nofp remove ALL_FP
  costs cortex
+ vendor 41
+ part c17
 end cpu cortex-r7
 
 begin cpu cortex-r8
@@ -1113,6 +1159,8 @@ begin cpu cortex-r8
  architecture armv7-r+idiv+fp
  option nofp remove ALL_FP
  costs cortex
+ vendor 41
+ part c18
 end cpu cortex-r8
 
 begin cpu cortex-m7
@@ -1131,6 +1179,8 @@ begin cpu cortex-m4
  architecture armv7e-m+fp
  option nofp remove ALL_FP
  costs v7m
+ vendor 41
+ part c24
 end cpu cortex-m4
 
 begin cpu cortex-m3
@@ -1139,6 +1189,8 @@ begin cpu cortex-m3
  architecture armv7-m
  isa quirk_cm3_ldrd
  costs v7m
+ vendor 41
+ part c23
 end cpu cortex-m3
 
 begin cpu marvell-pj4
@@ -1177,6 +1229,8 @@ begin cpu cortex-a32
  option crypto add FP_ARMv8 CRYPTO
  option nofp remove ALL_FP
  costs cortex_a35
+ vendor 41
+ part d01
 end cpu cortex-a32
 
 begin cpu cortex-a35
@@ -1187,6 +1241,8 @@ begin cpu cortex-a35
  option crypto add FP_ARMv8 CRYPTO
  option nofp remove ALL_FP
  costs cortex_a35
+ vendor 41
+ part d04
 end cpu cortex-a35
 
 begin cpu cortex-a53
@@ -1196,6 +1252,8 @@ begin cpu cortex-a53
  option crypto add FP_ARMv8 CRYPTO
  option nofp remove ALL_FP
  costs cortex_a53
+ vendor 41
+ part d03
 end cpu cortex-a53
 
 begin cpu cortex-a57
@@ -1204,6 +1262,8 @@ begin cpu cortex-a57
  architecture armv8-a+crc+simd
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
+ vendor 41
+ part d07
 end cpu cortex-a57
 
 begin cpu cortex-a72
@@ -1213,6 +1273,8 @@ begin cpu cortex-a72
  architecture armv8-a+crc+simd
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
+ vendor 41
+ part d08
 end cpu cortex-a72
 
 begin cpu cortex-a73
@@ -1222,6 +1284,8 @@ begin cpu cortex-a73
  architecture armv8-a+crc+simd
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
+ vendor 41
+ part d09
 end cpu cortex-a73
 
 begin cpu exynos-m1
@@ -1286,6 +1350,8 @@ begin cpu cortex-a55
  option crypto add FP_ARMv8 CRYPTO
  option nofp remove ALL_FP
  costs cortex_a53
+ vendor 41
+ part d05
 end cpu cortex-a55
 
 begin cpu cortex-a75
@@ -1295,6 +1361,8 @@ begin cpu cortex-a75
  architecture armv8.2-a+fp16+dotprod+simd
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
+ vendor 41
+ part d0a
 end cpu cortex-a75
 
 begin cpu cortex-a76
@@ -1304,6 +1372,8 @@ begin cpu cortex-a76
  architecture armv8.2-a+fp16+dotprod+simd
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
+ vendor 41
+ part d0b
 end cpu cortex-a76
 
 # ARMv8.2 A-profile ARM DynamIQ big.LITTLE implementations
@@ -1349,6 +1419,8 @@ begin cpu cortex-r52
  architecture armv8-r+crc+simd
  option nofp.dp remove FP_DBL ALL_SIMD
  costs cortex
+ vendor 41
+ part d13
 end cpu cortex-r52
 
 # FPU entries
diff --git a/gcc/config/arm/driver-arm.c b/gcc/config/arm/driver-arm.c
index 356a5e6..dab3d4e 100644
--- a/gcc/config/arm/driver-arm.c
+++ b/gcc/config/arm/driver-arm.c
@@ -25,58 +25,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "configargs.h"
 
-struct vendor_cpu {
+struct vendor_cpu
+{
   const char *part_no;
   const char *arch_name;
   const char *cpu_name;
 };
 
-static struct vendor_cpu arm_cpu_table[] = {
-    {"0x926", "armv5te", "arm926ej-s"},
-    {"0xa26", "armv5te", "arm1026ej-s"},
-    {"0xb02", "armv6k", "mpcore"},
-    {"0xb36", "armv6j", "arm1136jf-s"},
-    {"0xb56", "armv6t2", "arm1156t2f-s"},
-    /* armv6kz is the correct spelling for ARMv6KZ but may not be supported in
-       the version of binutils used.  The incorrect spelling is supported in
-       legacy and current binutils so that is used instead.  */
-    {"0xb76", "armv6zk", "arm1176jzf-s"},
-    {"0xc05", "armv7-a", "cortex-a5"},
-    {"0xc07", "armv7ve", "cortex-a7"},
-    {"0xc08", "armv7-a", "cortex-a8"},
-    {"0xc09", "armv7-a", "cortex-a9"},
-    {"0xc0d", "armv7ve", "cortex-a12"},
-    {"0xc0e", "armv7ve", "cortex-a17"},
-    {"0xc0f", "armv7ve", "cortex-a15"},
-    {"0xd01", "armv8-a+crc", "cortex-a32"},
-    {"0xd04", "armv8-a+crc", "cortex-a35"},
-    {"0xd03", "armv8-a+crc", "cortex-a53"},
-    {"0xd07", "armv8-a+crc", "cortex-a57"},
-    {"0xd08", "armv8-a+crc", "cortex-a72"},
-    {"0xd09", "armv8-a+crc", "cortex-a73"},
-    {"0xd05", "armv8.2-a+fp16+dotprod", "cortex-a55"},
-    {"0xd0a", "armv8.2-a+fp16+dotprod", "cortex-a75"},
-    {"0xd0b", "armv8.2-a+fp16+dotprod", "cortex-a76"},
-    {"0xc14", "armv7-r", "cortex-r4"},
-    {"0xc15", "armv7-r", "cortex-r5"},
-    {"0xc17", "armv7-r", "cortex-r7"},
-    {"0xc18", "armv7-r", "cortex-r8"},
-    {"0xd13", "armv8-r+crc", "cortex-r52"},
-    {"0xc20", "armv6-m", "cortex-m0"},
-    {"0xc21", "armv6-m", "cortex-m1"},
-    {"0xc23", "armv7-m", "cortex-m3"},
-    {"0xc24", "armv7e-m", "cortex-m4"},
-    {NULL, NULL, NULL}
-};
-
-static struct {
+struct vendor
+{
   const char *vendor_no;
   const struct vendor_cpu *vendor_parts;
-} vendors[] = {
-    {"0x41", arm_cpu_table},
-    {NULL, NULL}
 };
 
+#include "arm-native.h"
+
 /* This will be called by the spec parser in gcc.c when it sees
    a %:local_cpu_detect(args) construct.  Currently it will be called
    with either "arch", "cpu" or "tune" as argument depending on if
@@ -112,14 +75,14 @@ host_detect_local_cpu (int argc, const char **argv)
 
   while (fgets (buf, sizeof (buf), f) != NULL)
     {
-      /* Ensure that CPU implementer is ARM (0x41).  */
+      /* Find the vendor table associated with this implementer.  */
       if (strncmp (buf, "CPU implementer", sizeof ("CPU implementer") - 1) == 0)
 	{
 	  int i;
-	  for (i = 0; vendors[i].vendor_no != NULL; i++)
-	    if (strstr (buf, vendors[i].vendor_no) != NULL)
+	  for (i = 0; vendors_table[i].vendor_no != NULL; i++)
+	    if (strstr (buf, vendors_table[i].vendor_no) != NULL)
 	      {
-		cpu_table = vendors[i].vendor_parts;
+		cpu_table = vendors_table[i].vendor_parts;
 		break;
 	      }
 	}
diff --git a/gcc/config/arm/parsecpu.awk b/gcc/config/arm/parsecpu.awk
index 4111680..aabe1b0 100644
--- a/gcc/config/arm/parsecpu.awk
+++ b/gcc/config/arm/parsecpu.awk
@@ -21,6 +21,7 @@
 # where <cmd> is one of:
 #	data: Print the standard 'C' data tables for the CPUs
 #	common-data: Print the 'C' data for shared driver/compiler files
+#	native: Print the data structures used by the native driver
 #	headers: Print the standard 'C' headers for the CPUs
 #	isa: Generate the arm-isa.h header
 #	md: Print the machine description fragment
@@ -391,6 +392,31 @@ function gen_comm_data () {
     print "};"
 }
 
+function gen_native () {
+    boilerplate("C")
+
+    for (vendor in vendor_ids) {
+	print "static struct vendor_cpu vendor"vendor"_cpu_table[] = {"
+	ncpus = split (cpu_list, cpus)
+
+	for (n = 1; n <= ncpus; n++) {
+	    if ((cpus[n] in cpu_vendor) && (cpus[n] in cpu_part)	\
+		&& cpu_vendor[cpus[n]] == vendor) {
+		print "  {\"0x"cpu_part[cpus[n]]"\", \""cpu_arch[cpus[n]]"\", \""cpus[n]"\"},"
+	    }
+	}
+	print "  {NULL, NULL, NULL}"
+	print "};"
+    }
+
+    print "\nstatic struct vendor vendors_table[] = {"
+    for (vendor in vendor_ids) {
+	print "  {\"0x"vendor"\", vendor"vendor"_cpu_table},"
+    }
+    print "  {NULL, NULL}"
+    print "};"
+}
+
 function gen_md () {
     boilerplate("md")
 
@@ -726,6 +752,23 @@ BEGIN {
     parse_ok = 1
 }
 
+/^[ 	]*vendor / {
+    if (NF != 2) fatal("syntax: vendor <vendor-id>")
+    if (cpu_name == "") fatal("\"vendor\" outside of cpu block")
+    cpu_vendor[cpu_name] = $2
+    vendor_ids[$2] = 1
+    parse_ok = 1
+}
+
+/^[ 	]*part / {
+    if (NF < 2 || NF > 4) fatal("syntax: part <part-id> [minrev [maxrev]]")
+    if (cpu_name == "") fatal("\"part\" outside of cpu block")
+    cpu_part[cpu_name] = $2
+    if (NF > 2) cpu_minrev[cpu_name] = $3
+    if (NF == 4) cpu_maxrev[cpu_name] = $4
+    parse_ok = 1
+}
+
 /^end cpu / {
     if (NF != 3) fatal("syntax: end cpu <name>")
     if (cpu_name != $3) fatal("mimatched end cpu")
@@ -734,6 +777,9 @@ BEGIN {
 	gsub(/[-+.]/, "_", cpu_cnames[cpu_name])
     }
     if (! (cpu_name in cpu_arch)) fatal("cpu definition lacks an architecture")
+    if ((cpu_name in cpu_part) && !(cpu_name in cpu_vendor)) {
+	fatal("part number specified for " cpu_name " but no vendor")
+    }
     cpu_list = cpu_list " " cpu_name
     cpu_name = ""
     parse_ok = 1
@@ -751,6 +797,8 @@ END {
 	gen_data()
     } else if (cmd == "common-data") {
 	gen_comm_data()
+    } else if (cmd == "native") {
+	gen_native()
     } else if (cmd == "headers") {
 	gen_headers()
     } else if (cmd == "isa") {
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index b918e51..c3a8c77 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -110,6 +110,14 @@ s-arm-cdata: $(srcdir)/config/arm/parsecpu.awk \
 	$(SHELL) $(srcdir)/../move-if-change tmp-arm-cpu-cdata.h arm-cpu-cdata.h
 	$(STAMP) s-arm-cdata
 
+arm-native.h: s-arm-native ; @true
+s-arm-native: $(srcdir)/config/arm/parsecpu.awk \
+  $(srcdir)/config/arm/arm-cpus.in
+	$(AWK) -f $(srcdir)/config/arm/parsecpu.awk -v cmd=native \
+		$(srcdir)/config/arm/arm-cpus.in > tmp-arm-native.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-arm-native.h arm-native.h
+	$(STAMP) s-arm-native
+
 aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
     coretypes.h $(TM_H) $(TM_P_H) $(RTL_H) $(TREE_H) output.h $(C_COMMON_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
@@ -145,3 +153,5 @@ arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \
 		$(srcdir)/config/arm/arm-c.c
 
 arm-common.o: arm-cpu-cdata.h
+
+driver-arm.o: arm-native.h
