diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c
index 76c357b4258..32cf36e94f6 100644
--- a/gcc/common/config/arm/arm-common.c
+++ b/gcc/common/config/arm/arm-common.c
@@ -309,7 +309,16 @@ arm_print_hint_for_cpu_option (const char *target,
 {
   auto_vec<const char*> candidates;
   for (; list->common.name != NULL; list++)
-    candidates.safe_push (list->common.name);
+    {
+      candidates.safe_push (list->common.name);
+      if (list->aliases)
+	{
+	  for (const cpu_alias *alias = list->aliases; alias->name != NULL;
+	       alias++)
+	    if (alias->visible)
+	      candidates.safe_push (alias->name);
+	}
+    }
 
 #ifdef HAVE_LOCAL_CPU_DETECT
   /* Add also "native" as possible value.  */
@@ -345,6 +354,16 @@ arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
       if (strncmp (entry->common.name, target, len) == 0
 	  && entry->common.name[len] == '\0')
 	return entry;
+
+      /* Match against any legal alias for this CPU candidate.  */
+      if (entry->aliases)
+	{
+	  for (const cpu_alias *alias = entry->aliases; alias->name != NULL;
+	       alias++)
+	    if (strncmp (alias->name, target, len) == 0
+		&& alias->name[len] == '\0')
+	      return entry;
+	}
     }
 
   if (complain)
diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index d82e95a2266..61b17b57af7 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -617,6 +617,7 @@ end arch iwmmxt2
 # format:
 # begin cpu <name>
 #   [cname <c-compatible-name>]
+#   [alias <name>+]
 #   [tune for <cpu-name>]
 #   [tune flags <list>]
 #   architecture <name>
@@ -630,6 +631,9 @@ end arch iwmmxt2
 #
 # If omitted, cname is formed from transforming the cpuname to convert
 # non-valid punctuation characters to '_'.
+# Any number of alias names may be specified for a CPU.  If the name starts
+# with a '!' then it will be recognized as a valid name, but will not
+# be printed in any help text listing permitted CPUs.
 # If specified, tune for specifies a CPU target to use for tuning this core.
 # isa flags are appended to those defined by the architecture.
 # Each add option must have a distinct feature set and each remove
@@ -658,29 +662,12 @@ begin cpu arm810
 end cpu arm810
 
 begin cpu strongarm
+ alias strongarm110 !strongarm1100 !strongarm1110
  tune flags LDSCHED STRONG
  architecture armv4
  costs strongarm
 end cpu strongarm
 
-begin cpu strongarm110
- tune flags LDSCHED STRONG
- architecture armv4
- costs strongarm
-end cpu strongarm110
-
-begin cpu strongarm1100
- tune flags LDSCHED STRONG
- architecture armv4
- costs strongarm
-end cpu strongarm1100
-
-begin cpu strongarm1110
- tune flags LDSCHED STRONG
- architecture armv4
- costs strongarm
-end cpu strongarm1110
-
 begin cpu fa526
  tune flags LDSCHED
  architecture armv4
diff --git a/gcc/config/arm/arm-generic.md b/gcc/config/arm/arm-generic.md
index 81200fa499a..da97303c758 100644
--- a/gcc/config/arm/arm-generic.md
+++ b/gcc/config/arm/arm-generic.md
@@ -122,8 +122,7 @@ (define_insn_reservation "mult" 16
 (define_insn_reservation "mult_ldsched_strongarm" 3
   (and (eq_attr "generic_sched" "yes")
        (and (eq_attr "ldsched" "yes") 
-	    (and (eq_attr "tune"
-		  "strongarm,strongarm110,strongarm1100,strongarm1110")
+	    (and (eq_attr "tune" "strongarm")
 		 (ior (eq_attr "mul32" "yes")
 		      (eq_attr "mul64" "yes")))))
   "core*2")
@@ -131,8 +130,7 @@ (define_insn_reservation "mult_ldsched_strongarm" 3
 (define_insn_reservation "mult_ldsched" 4
   (and (eq_attr "generic_sched" "yes")
        (and (eq_attr "ldsched" "yes") 
-	    (and (eq_attr "tune"
-		  "!strongarm,strongarm110,strongarm1100,strongarm1110")
+	    (and (eq_attr "tune" "!strongarm")
 	         (ior (eq_attr "mul32" "yes")
 		      (eq_attr "mul64" "yes")))))
   "core*4")
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cea98669111..8d6d2395b84 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -498,6 +498,16 @@ struct arm_build_target
 
 extern struct arm_build_target arm_active_target;
 
+/* Table entry for a CPU alias.  */
+struct cpu_alias
+{
+  /* The alias name.  */
+  const char *const name;
+  /* True if the name should be displayed in help text listing cpu names.  */
+  bool visible;
+};
+
+/* Table entry for an architectural feature extension.  */
 struct cpu_arch_extension
 {
   /* Feature name.  */
@@ -511,6 +521,7 @@ struct cpu_arch_extension
   const enum isa_feature isa_bits[isa_num_bits];
 };
 
+/* Common elements of both CPU and architectural options.  */
 struct cpu_arch_option
 {
   /* Name for this option.  */
@@ -521,6 +532,7 @@ struct cpu_arch_option
   enum isa_feature isa_bits[isa_num_bits];
 };
 
+/* Table entry for an architecture entry.  */
 struct arch_option
 {
   /* Common option fields.  */
@@ -535,10 +547,13 @@ struct arch_option
   enum processor_type tune_id;
 };
 
+/* Table entry for a CPU entry.  */
 struct cpu_option
 {
   /* Common option fields.  */
   cpu_arch_option common;
+  /* List of aliases for this CPU.  */
+  const struct cpu_alias *aliases;
   /* Architecture upon which this CPU is based.  */
   enum arch_type arch;
 };
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index eacee746a39..623b79f3322 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -33,15 +33,6 @@ Enum(processor_type) String(arm810) Value( TARGET_CPU_arm810)
 EnumValue
 Enum(processor_type) String(strongarm) Value( TARGET_CPU_strongarm)
 
-EnumValue
-Enum(processor_type) String(strongarm110) Value( TARGET_CPU_strongarm110)
-
-EnumValue
-Enum(processor_type) String(strongarm1100) Value( TARGET_CPU_strongarm1100)
-
-EnumValue
-Enum(processor_type) String(strongarm1110) Value( TARGET_CPU_strongarm1110)
-
 EnumValue
 Enum(processor_type) String(fa526) Value( TARGET_CPU_fa526)
 
diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md
index f64c1ef176d..47dc516e2a7 100644
--- a/gcc/config/arm/arm-tune.md
+++ b/gcc/config/arm/arm-tune.md
@@ -22,7 +22,6 @@
 
 (define_attr "tune"
 	"arm8,arm810,strongarm,
-	strongarm110,strongarm1100,strongarm1110,
 	fa526,fa626,arm7tdmi,
 	arm7tdmis,arm710t,arm720t,
 	arm740t,arm9,arm9tdmi,
diff --git a/gcc/config/arm/parsecpu.awk b/gcc/config/arm/parsecpu.awk
index aabe1b0c64c..ba2dee5fdcb 100644
--- a/gcc/config/arm/parsecpu.awk
+++ b/gcc/config/arm/parsecpu.awk
@@ -261,6 +261,18 @@ function gen_comm_data () {
 	    print "  { NULL, false, false, {isa_nobit}}"
 	    print "};\n"
 	}
+
+	if (cpus[n] in cpu_aliases) {
+	    print "static const cpu_alias cpu_aliastab_" \
+		cpu_cnames[cpus[n]] "[] = {"
+	    naliases = split (cpu_aliases[cpus[n]], aliases)
+	    for (alias = 1; alias <= naliases; alias++) {
+		print "  { \"" aliases[alias] "\", " \
+		    cpu_alias_visible[cpus[n],aliases[alias]] "},"
+	    }
+	    print "  { NULL, false}"
+	    print "};\n"
+	}
     }
 
     print "const cpu_option all_cores[] ="
@@ -295,12 +307,16 @@ function gen_comm_data () {
 	}
 	print_isa_bits_for(all_isa_bits, "      ")
 	print "\n    },"
+	# aliases
+	if (cpus[n] in cpu_aliases) {
+	    print "    cpu_aliastab_" cpu_cnames[cpus[n]] ","
+	} else print "    NULL,"
 	# arch
 	print "    TARGET_ARCH_" arch_cnames[feats[1]]
 	print "  },"
     }
 
-    print "  {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
+    print "  {{NULL, NULL, {isa_nobit}}, NULL, TARGET_ARCH_arm_none}"
     print "};"
 
     narchs = split (arch_list, archs)
@@ -486,13 +502,17 @@ function gen_opt () {
 function check_cpu (name) {
     exts = split (name, extensions, "+")
 
-    if (! (extensions[1] in cpu_cnames)) {
-	return "error"
+    cpu_name = extensions[1]
+    if (! (cpu_name in cpu_cnames)) {
+	if (! (cpu_name in cpu_all_aliases)) {
+	    return "error"
+	}
+	cpu_name = cpu_all_aliases[cpu_name]
     }
 
     for (n = 2; n <= exts; n++) {
-	if (!((extensions[1], extensions[n]) in cpu_opt_remove)	\
-	    && !((extensions[1], extensions[n]) in cpu_optaliases)) {
+	if (!((cpu_name, extensions[n]) in cpu_opt_remove)	\
+	    && !((cpu_name, extensions[n]) in cpu_optaliases)) {
 	    return "error"
 	}
     }
@@ -642,6 +662,12 @@ BEGIN {
     toplevel()
     cpu_name = $3
     parse_ok = 1
+    if (cpu_name in cpu_cnames) {
+	fatal(cpu_name " is already defined")
+    }
+    if (cpu_name in cpu_all_aliases) {
+	fatal(cpu_name " has already been defined as an alias")
+    }
 }
 
 /^[ 	]*cname / {
@@ -651,6 +677,33 @@ BEGIN {
     parse_ok = 1
 }
 
+/^[ 	]*alias / {
+    if (NF < 2) fatal("syntax: alias <name>+")
+    if (cpu_name == "") fatal("\"alias\" outside of cpu block")
+    alias_count = NF
+    for (n = 2; n <= alias_count; n++) {
+	visible = "true"
+	alias = $n
+	if (alias ~ /!.*/) {
+	    visible = "false"
+	    gsub(/^!/, "", alias)
+	}
+	if (alias in cpu_cnames) {
+	    fatal(alias " is already defined as a cpu name")
+	}
+	if (n == 2) {
+	    cpu_aliases[cpu_name] = alias
+	} else cpu_aliases[cpu_name] = cpu_aliases[cpu_name] " " alias
+	cpu_alias_visible[cpu_name,alias] = visible
+	if (alias in cpu_all_aliases) {
+	    fatal(alias " is already an alias for " cpu_all_aliases[alias])
+	}
+	cpu_all_aliases[alias] = cpu_name
+    }
+    cpu_has_alias[cpu_name] = 1
+    parse_ok = 1
+}
+
 /^[ 	]*tune for / {
     if (NF != 3) fatal("syntax: tune for <cpu-name>")
     if (cpu_name != "") {
