* bfd/archures.c (bfd_mach_mcf5200, bfd_mach_mcf5206e,
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 7 Feb 2006 19:01:10 +0000 (19:01 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Tue, 7 Feb 2006 19:01:10 +0000 (19:01 +0000)
bfd_mach_mcf5307, bfd_mach_mcf5407, bfd_mach_mcf528x,
bfd_mach_mcfv4e, bfd_mach_mcf521x, bfd_mach_mcf5249,
bfd_mach_mcf547x, bfd_mach_mcf548x): Remove.
(bfd_mach_mcf_isa_a, bfd_mach_mcf_isa_a_div,
bfd_mach_mcf_isa_a_div_mac, bfd_mach_mcf_isa_a_div_emac,
bfd_mach_mcf_isa_aplus, bfd_mach_mcf_isa_aplus_mac,
bfd_mach_mcf_isa_aplus_emac, bfd_mach_mcf_isa_aplus_usp,
bfd_mach_mcf_isa_aplus_usp_mac, bfd_mach_mcf_isa_aplus_usp_emac,
bfd_mach_mcf_isa_b, bfd_mach_mcf_isa_b_mac, bfd_mach_mcf_isa_b_emac,
bfd_mach_mcf_isa_b_usp_float, bfd_mach_mcf_isa_b_usp_float_mac,
bfd_mach_mcf_isa_b_usp_float_emac): New.
(bfd_default_scan): Update coldfire mapping.
* bfd/bfd-in.h (bfd_m68k_mach_to_features,
bfd_m68k_features_to_mach): Declare.
* bfd/bfd-in2.h: Rebuilt.
* bfd/cpu-m68k.c (arch_info_struct): Add new coldfire machines,
adjust legacy names.
(m68k_arch_features): New.
(bfd_m68k_mach_to_features,
bfd_m68k_features_to_mach): Define.
* bfd/elf32-m68k.c (elf32_m68k_object_p): New.
(elf32_m68k_merge_private_bfd_data): Merge the CF EF flags.
(elf32_m68k_print_private_bfd_data): Print the CF EF flags.
(elf_backend_object_p): Define.
* bfd/ieee.c (ieee_write_processor): Update coldfire machines.
* bfd/libbfd.h: Rebuilt.

* gas/config/tc-m68k.c (mcf5208_control_regs, mcf5213_control_regs,
mcf5329_control_regs): New.
(not_current_architecture, selected_arch, selected_cpu): New.
(m68k_archs, m68k_extensions): New.
(archs): Renamed to ...
(m68k_cpus): ... here.  Adjust.
(n_arches): Remove.
(md_pseudo_table): Add arch and cpu directives.
(find_cf_chip, m68k_ip): Adjust table scanning.
(no_68851, no_68881): Remove.
(md_assemble): Lazily initialize.
(select_control_regs): Adjust cpu names. Add 5208, 5213, 5329.
(md_init_after_args): Move functionality to m68k_init_arch.
(mri_chip): Adjust table scanning.
(md_parse_option): Reimplement 'm' processing to add -march & -mcpu
options with saner parsing.
(m68k_lookup_cpu, m68k_set_arch, m68k_set_cpu, m68k_set_extension,
m68k_init_arch): New.
(s_m68k_cpu, s_m68k_arch): New.
(md_show_usage): Adjust.
(m68k_elf_final_processing): Set CF EF flags.
* gas/config/tc-m68k.h (m68k_init_after_args): Remove.
(tc_init_after_args): Remove.
* gas/doc/c-m68k.texi (M68K-Opts): Document -march, -mcpu options.
(M68k-Directives): Document .arch and .cpu directives.

* gas/testsuite/gas/m68k/all.exp: Add arch-cpu-1 test.
* gas/testsuite/gas/m68k/arch-cpu-1.[sd]: New.

* include/elf/m68k.h (EF_CPU32, EF_M68000, EF_CFV4E): Rename to ...
(EF_M68K_CPU32, EF_M68K_M68000, EF_M68K_CFV4E): ... here.
(EF_M68K_ISA_MASK, EF_M68K_ISA_A, EF_M68K_M68K_ISA_A_PLUS,
EF_M68K_ISA_B, EF_M68K_HW_DIV, EF_M68K_MAC_MASK, EF_M68K_MAC,
EF_M68K_EMAC, EF_M68K_USP, EF_M68K_FLOAT): New.

* include/opcode/m68k.h (m68008, m68ec030, m68882): Remove.
(m68k_mask): New.
(cpu_m68k, cpu_cf): New.
(mcf5200, mcf5206e, mcf521x, mcf5249, mcf528x, mcf5307, mcf5407,
mcf5470, mcf5480): Rename to cpu_<foo>. Add m680x0 variants.

* opcodes/m68k-dis.c (print_insn_m68k): Use
bfd_m68k_mach_to_features.

* binutils/readelf.c (get_machine_flags): Add logic for EF_M68K flags.

21 files changed:
bfd/ChangeLog
bfd/archures.c
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/cpu-m68k.c
bfd/elf32-m68k.c
bfd/ieee.c
bfd/libbfd.h
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/config/tc-m68k.c
gas/config/tc-m68k.h
gas/doc/c-m68k.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/m68k/all.exp
include/elf/ChangeLog
include/elf/m68k.h
include/opcode/m68k.h
opcodes/ChangeLog
opcodes/m68k-dis.c

index 5820f98..c943726 100644 (file)
@@ -1,3 +1,33 @@
+2006-01-26  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * archures.c (bfd_mach_mcf5200, bfd_mach_mcf5206e,
+       bfd_mach_mcf5307, bfd_mach_mcf5407, bfd_mach_mcf528x,
+       bfd_mach_mcfv4e, bfd_mach_mcf521x, bfd_mach_mcf5249,
+       bfd_mach_mcf547x, bfd_mach_mcf548x): Remove.
+       (bfd_mach_mcf_isa_a, bfd_mach_mcf_isa_a_div,
+       bfd_mach_mcf_isa_a_div_mac, bfd_mach_mcf_isa_a_div_emac,
+       bfd_mach_mcf_isa_aplus, bfd_mach_mcf_isa_aplus_mac,
+       bfd_mach_mcf_isa_aplus_emac, bfd_mach_mcf_isa_aplus_usp,
+       bfd_mach_mcf_isa_aplus_usp_mac, bfd_mach_mcf_isa_aplus_usp_emac,
+       bfd_mach_mcf_isa_b, bfd_mach_mcf_isa_b_mac, bfd_mach_mcf_isa_b_emac,
+       bfd_mach_mcf_isa_b_usp_float, bfd_mach_mcf_isa_b_usp_float_mac,
+       bfd_mach_mcf_isa_b_usp_float_emac): New.
+       (bfd_default_scan): Update coldfire mapping.
+       * bfd-in.h (bfd_m68k_mach_to_features,
+       bfd_m68k_features_to_mach): Declare.
+       * bfd-in2.h: Rebuilt.
+       * cpu-m68k.c (arch_info_struct): Add new coldfire machines,
+       adjust legacy names.
+       (m68k_arch_features): New.
+       (bfd_m68k_mach_to_features,
+       bfd_m68k_features_to_mach): Define.
+       * elf32-m68k.c (elf32_m68k_object_p): New.
+       (elf32_m68k_merge_private_bfd_data): Merge the CF EF flags.
+       (elf32_m68k_print_private_bfd_data): Print the CF EF flags.
+       (elf_backend_object_p): Define.
+       * ieee.c (ieee_write_processor): Update coldfire machines.
+       * libbfd.h: Rebuilt.
+
 2006-02-06  Steve Ellcey  <sje@cup.hp.com>
 
        * elfxx-ia64.c (elfNN_ia64_fake_sections): Set SHF_IA_64_HP_TLS
index 069393a..e9a90e7 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD library support routines for architectures.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005
+   2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
@@ -80,16 +80,22 @@ DESCRIPTION
 .#define bfd_mach_m68040 6
 .#define bfd_mach_m68060 7
 .#define bfd_mach_cpu32  8
-.#define bfd_mach_mcf5200  9
-.#define bfd_mach_mcf5206e 10
-.#define bfd_mach_mcf5307  11
-.#define bfd_mach_mcf5407  12
-.#define bfd_mach_mcf528x  13
-.#define bfd_mach_mcfv4e   14
-.#define bfd_mach_mcf521x   15
-.#define bfd_mach_mcf5249   16
-.#define bfd_mach_mcf547x   17
-.#define bfd_mach_mcf548x   18
+.#define bfd_mach_mcf_isa_a 9
+.#define bfd_mach_mcf_isa_a_div 10
+.#define bfd_mach_mcf_isa_a_div_mac 11
+.#define bfd_mach_mcf_isa_a_div_emac 12
+.#define bfd_mach_mcf_isa_aplus 13
+.#define bfd_mach_mcf_isa_aplus_mac 14
+.#define bfd_mach_mcf_isa_aplus_emac 15
+.#define bfd_mach_mcf_isa_aplus_usp 16
+.#define bfd_mach_mcf_isa_aplus_usp_mac 17
+.#define bfd_mach_mcf_isa_aplus_usp_emac 18
+.#define bfd_mach_mcf_isa_b 19
+.#define bfd_mach_mcf_isa_b_mac 20
+.#define bfd_mach_mcf_isa_b_emac 21
+.#define bfd_mach_mcf_isa_b_usp_float 22
+.#define bfd_mach_mcf_isa_b_usp_float_mac 23
+.#define bfd_mach_mcf_isa_b_usp_float_emac 24
 .  bfd_arch_vax,       {* DEC Vax *}
 .  bfd_arch_i960,      {* Intel 960 *}
 .    {* The order of the following is important.
@@ -1004,23 +1010,23 @@ bfd_default_scan (const bfd_arch_info_type *info, const char *string)
       break;
     case 5200:
       arch = bfd_arch_m68k;
-      number = bfd_mach_mcf5200;
+      number = bfd_mach_mcf_isa_a;
       break;
     case 5206:
       arch = bfd_arch_m68k;
-      number = bfd_mach_mcf5206e;
+      number = bfd_mach_mcf_isa_a_div_mac;
       break;
     case 5307:
       arch = bfd_arch_m68k;
-      number = bfd_mach_mcf5307;
+      number = bfd_mach_mcf_isa_a_div_mac;
       break;
     case 5407:
       arch = bfd_arch_m68k;
-      number = bfd_mach_mcf5407;
+      number = bfd_mach_mcf_isa_b_mac;
       break;
     case 5282:
       arch = bfd_arch_m68k;
-      number = bfd_mach_mcf528x;
+      number = bfd_mach_mcf_isa_b_usp_float_emac;
       break;
 
     case 32000:
index 74aded8..25ae6a4 100644 (file)
@@ -1,7 +1,8 @@
 /* Main header file for the bfd library -- portable access to object files.
 
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
@@ -706,6 +707,10 @@ extern struct bfd_section *_bfd_elf_tls_setup
 extern void _bfd_fix_excluded_sec_syms
   (bfd *, struct bfd_link_info *);
 
+extern unsigned bfd_m68k_mach_to_features (int);
+
+extern int bfd_m68k_features_to_mach (unsigned);
+
 extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
    char **);
index cae4ede..1578cbc 100644 (file)
@@ -714,6 +714,10 @@ extern struct bfd_section *_bfd_elf_tls_setup
 extern void _bfd_fix_excluded_sec_syms
   (bfd *, struct bfd_link_info *);
 
+extern unsigned bfd_m68k_mach_to_features (int);
+
+extern int bfd_m68k_features_to_mach (unsigned);
+
 extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
    char **);
@@ -1670,16 +1674,22 @@ enum bfd_architecture
 #define bfd_mach_m68040 6
 #define bfd_mach_m68060 7
 #define bfd_mach_cpu32  8
-#define bfd_mach_mcf5200  9
-#define bfd_mach_mcf5206e 10
-#define bfd_mach_mcf5307  11
-#define bfd_mach_mcf5407  12
-#define bfd_mach_mcf528x  13
-#define bfd_mach_mcfv4e   14
-#define bfd_mach_mcf521x   15
-#define bfd_mach_mcf5249   16
-#define bfd_mach_mcf547x   17
-#define bfd_mach_mcf548x   18
+#define bfd_mach_mcf_isa_a 9
+#define bfd_mach_mcf_isa_a_div 10
+#define bfd_mach_mcf_isa_a_div_mac 11
+#define bfd_mach_mcf_isa_a_div_emac 12
+#define bfd_mach_mcf_isa_aplus 13
+#define bfd_mach_mcf_isa_aplus_mac 14
+#define bfd_mach_mcf_isa_aplus_emac 15
+#define bfd_mach_mcf_isa_aplus_usp 16
+#define bfd_mach_mcf_isa_aplus_usp_mac 17
+#define bfd_mach_mcf_isa_aplus_usp_emac 18
+#define bfd_mach_mcf_isa_b 19
+#define bfd_mach_mcf_isa_b_mac 20
+#define bfd_mach_mcf_isa_b_emac 21
+#define bfd_mach_mcf_isa_b_usp_float 22
+#define bfd_mach_mcf_isa_b_usp_float_mac 23
+#define bfd_mach_mcf_isa_b_usp_float_emac 24
   bfd_arch_vax,       /* DEC Vax */
   bfd_arch_i960,      /* Intel 960 */
     /* The order of the following is important.
index e2ac095..93b60f9 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD library support routines for architectures.
    Copyright 1990, 1991, 1992, 1993, 1994, 1997, 1998, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2006 Free Software Foundation, Inc.
    Hacked by Steve Chamberlain of Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -22,6 +22,7 @@
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
+#include "opcode/m68k.h"
 
 #define N(name, print,d,next)  \
 {  32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, next, }
@@ -34,19 +35,149 @@ static const bfd_arch_info_type arch_info_struct[] =
     N(bfd_mach_m68020,  "m68k:68020", FALSE, &arch_info_struct[4]),
     N(bfd_mach_m68030,  "m68k:68030", FALSE, &arch_info_struct[5]),
     N(bfd_mach_m68040,  "m68k:68040", FALSE, &arch_info_struct[6]),
-    N(bfd_mach_cpu32,   "m68k:cpu32", FALSE, &arch_info_struct[7]),
-    N(bfd_mach_mcf5200, "m68k:5200",  FALSE, &arch_info_struct[8]),
-    N(bfd_mach_mcf5206e,"m68k:5206e", FALSE, &arch_info_struct[9]),
-    N(bfd_mach_mcf5307, "m68k:5307",  FALSE, &arch_info_struct[10]),
-    N(bfd_mach_mcf5407, "m68k:5407",  FALSE, &arch_info_struct[11]),
-    N(bfd_mach_m68060,  "m68k:68060", FALSE, &arch_info_struct[12]),
-    N(bfd_mach_mcf528x, "m68k:528x",  FALSE, &arch_info_struct[13]),
-    N(bfd_mach_mcf521x, "m68k:521x",  FALSE, &arch_info_struct[14]),
-    N(bfd_mach_mcf5249, "m68k:5249",  FALSE, &arch_info_struct[15]),
-    N(bfd_mach_mcf547x, "m68k:547x",  FALSE, &arch_info_struct[16]),
-    N(bfd_mach_mcf548x, "m68k:548x",  FALSE, &arch_info_struct[17]),
-    N(bfd_mach_mcfv4e,  "m68k:cfv4e", FALSE, 0),
+    N(bfd_mach_m68060,  "m68k:68060", FALSE, &arch_info_struct[7]),
+    N(bfd_mach_cpu32,   "m68k:cpu32", FALSE, &arch_info_struct[8]),
+
+    /* Various combinations of CF architecture features */
+    N(bfd_mach_mcf_isa_a, "m68k:isa-a",
+      FALSE, &arch_info_struct[9]),
+    N(bfd_mach_mcf_isa_a_div, "m68k:isa-a:div",
+      FALSE, &arch_info_struct[10]),
+    N(bfd_mach_mcf_isa_a_div_mac, "m68k:isa-a:div:mac",
+      FALSE, &arch_info_struct[11]),
+    N(bfd_mach_mcf_isa_a_div_emac, "m68k:isa-a:div:emac",
+      FALSE, &arch_info_struct[12]),
+    N(bfd_mach_mcf_isa_aplus, "m68k:isa-a+",
+      FALSE, &arch_info_struct[13]),
+    N(bfd_mach_mcf_isa_aplus_mac, "m68k:isa-a+:mac",
+      FALSE, &arch_info_struct[14]),
+    N(bfd_mach_mcf_isa_aplus_emac, "m68k:isa-a+:emac",
+      FALSE, &arch_info_struct[15]),
+    N(bfd_mach_mcf_isa_aplus_usp, "m68k:isa-a+:usp",
+      FALSE, &arch_info_struct[16]),
+    N(bfd_mach_mcf_isa_aplus_usp_mac, "m68k:isa-a+:usp:mac",
+      FALSE, &arch_info_struct[17]),
+    N(bfd_mach_mcf_isa_aplus_usp_emac, "m68k:isa-a+:usp:emac",
+      FALSE, &arch_info_struct[18]),
+    N(bfd_mach_mcf_isa_b, "m68k:isa-b",
+      FALSE, &arch_info_struct[19]),
+    N(bfd_mach_mcf_isa_b_mac, "m68k:isa-b:mac",
+      FALSE, &arch_info_struct[20]),
+    N(bfd_mach_mcf_isa_b_emac, "m68k:isa-b:emac",
+      FALSE, &arch_info_struct[21]),
+    N(bfd_mach_mcf_isa_b_usp_float, "m68k:isa-b:usp:float",
+      FALSE, &arch_info_struct[22]),
+    N(bfd_mach_mcf_isa_b_usp_float_mac, "m68k:isa-b:usp:float:mac",
+      FALSE, &arch_info_struct[23]),
+    N(bfd_mach_mcf_isa_b_usp_float_emac, "m68k:isa-b:usp:float:emac",
+      FALSE, &arch_info_struct[24]),
+
+    /* Legacy names for CF architectures */
+    N(bfd_mach_mcf_isa_a, "m68k:5200",  FALSE, &arch_info_struct[25]),
+    N(bfd_mach_mcf_isa_a_div_mac,"m68k:5206e", FALSE, &arch_info_struct[26]),
+    N(bfd_mach_mcf_isa_a_div_mac, "m68k:5307",  FALSE, &arch_info_struct[27]),
+    N(bfd_mach_mcf_isa_b_mac, "m68k:5407",  FALSE, &arch_info_struct[28]),
+    N(bfd_mach_mcf_isa_aplus_usp_emac, "m68k:528x",
+      FALSE, &arch_info_struct[29]),
+    N(bfd_mach_mcf_isa_aplus_usp_emac, "m68k:521x",
+      FALSE, &arch_info_struct[30]),
+    N(bfd_mach_mcf_isa_a_div_emac, "m68k:5249",  FALSE, &arch_info_struct[31]),
+    N(bfd_mach_mcf_isa_b_usp_float_emac, "m68k:547x",
+      FALSE, &arch_info_struct[32]),
+    N(bfd_mach_mcf_isa_b_usp_float_emac, "m68k:548x",
+      FALSE, &arch_info_struct[33]),
+    N(bfd_mach_mcf_isa_b_usp_float_emac,  "m68k:cfv4e", FALSE, 0),
   };
 
 const bfd_arch_info_type bfd_m68k_arch =
   N(0, "m68k", TRUE, &arch_info_struct[0]);
+
+/* Table indexed by bfd_mach_arch number indicating which
+   architectural features are supported.  */
+static const unsigned m68k_arch_features[] = 
+{
+  0,
+  m68000|m68881|m68851,
+  m68000|m68881|m68851,
+  m68010|m68881|m68851,
+  m68020|m68881|m68851,
+  m68030|m68881|m68851,
+  m68040|m68881|m68851,
+  m68060|m68881|m68851,
+  cpu32|m68881,
+  mcfisa_a,
+  mcfisa_a|mcfhwdiv,
+  mcfisa_a|mcfhwdiv|mcfmac,
+  mcfisa_a|mcfhwdiv|mcfemac,
+  mcfisa_a|mcfisa_aa|mcfhwdiv,
+  mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,
+  mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,
+  mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp,
+  mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfmac,
+  mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfemac,
+  mcfisa_a|mcfhwdiv|mcfisa_b,
+  mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,
+  mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac,
+  mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat,
+  mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfmac,
+  mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac,
+};
+
+/* Return the count of bits set in MASK  */
+static unsigned
+bit_count (unsigned mask)
+{
+  unsigned ix;
+
+  for (ix = 0; mask; ix++)
+    /* Clear the LSB set */
+    mask ^= mask & -mask;
+  return ix;
+}
+
+/* Return the architectural features supported by MACH */
+
+unsigned
+bfd_m68k_mach_to_features (int mach)
+{
+  if ((unsigned)mach
+      >= sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]))
+    mach = 0;
+  return m68k_arch_features[mach];
+}
+
+/* Return the bfd machine that most closely represents the
+   architectural features.  We find the machine with the smallest
+   number of additional features.  If there is no such machine, we
+   find the one with the smallest number of missing features.  */
+
+int bfd_m68k_features_to_mach (unsigned features)
+{
+  int superset = 0, subset = 0;
+  unsigned extra = 99, missing = 99;
+  unsigned ix;
+
+  for (ix = 0;
+       ix != sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]);
+       ix++)
+    {
+      unsigned this_extra, this_missing;
+      
+      if (m68k_arch_features[ix] == features)
+       return ix;
+      this_extra = bit_count (m68k_arch_features[ix] & ~features);
+      if (this_extra < extra)
+       {
+         extra = this_extra;
+         superset = ix;
+       }
+      
+      this_missing = bit_count (features & ~m68k_arch_features[ix]);
+      if (this_missing < missing)
+       {
+         missing = this_missing;
+         superset = ix;
+       }
+    }
+  return superset ? superset : subset;
+}
index fec2bbb..7b3a1e9 100644 (file)
@@ -1,6 +1,6 @@
 /* Motorola 68k series support for 32-bit ELF
    Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005 Free Software Foundation, Inc.
+   2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -24,6 +24,7 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/m68k.h"
+#include "opcode/m68k.h"
 
 static reloc_howto_type *reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
@@ -220,7 +221,7 @@ static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
 
 #define CFV4E_PLT_ENTRY_SIZE 24 
 
-#define CFV4E_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CFV4E)
+#define CFV4E_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_M68K_CFV4E)
 
 static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] =
 {
@@ -248,7 +249,7 @@ static const bfd_byte elf_cfv4e_plt_entry[CFV4E_PLT_ENTRY_SIZE] =
   0, 0, 0, 0              /* Replaced with offset to start of .plt.  */
 };
 
-#define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CPU32)
+#define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_M68K_CPU32)
 
 #define PLT_CPU32_ENTRY_SIZE 24
 /* Procedure linkage table entries for the cpu32 */
@@ -372,6 +373,56 @@ elf_m68k_link_hash_table_create (abfd)
   return &ret->root.root;
 }
 
+/* Set the right machine number.  */
+
+static bfd_boolean
+elf32_m68k_object_p (bfd *abfd)
+{
+  unsigned int mach = 0;
+  unsigned features = 0;
+  flagword eflags = elf_elfheader (abfd)->e_flags;
+
+  if (eflags & EF_M68K_M68000)
+    features |= m68000;
+  else if (eflags & EF_M68K_CPU32)
+    features |= cpu32;
+  else if (eflags & EF_M68K_ISA_MASK)
+    {
+      switch (eflags & EF_M68K_ISA_MASK)
+       {
+       case EF_M68K_ISA_B:
+         features |= mcfisa_b;
+         /* FALLTHROUGH */
+       case EF_M68K_ISA_A_PLUS:
+         features |= mcfisa_aa;
+         /* FALLTHROUGH */
+       case EF_M68K_ISA_A:
+         features |= mcfisa_a;
+         break;
+       }
+      if (eflags & EF_M68K_HW_DIV)
+       features |= mcfhwdiv;
+      switch (eflags & EF_M68K_MAC_MASK)
+       {
+       case EF_M68K_MAC:
+         features |= mcfmac;
+         break;
+       case EF_M68K_EMAC:
+         features |= mcfemac;
+         break;
+       }
+      if (eflags & EF_M68K_USP)
+       features |= mcfusp;
+      if (eflags & EF_M68K_FLOAT)
+       features |= cfloat;
+    }
+
+  mach = bfd_m68k_features_to_mach (features);
+  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, mach);
+
+  return TRUE;
+}
+
 /* Keep m68k-specific flags in the ELF header.  */
 static bfd_boolean
 elf32_m68k_set_private_flags (abfd, flags)
@@ -392,19 +443,86 @@ elf32_m68k_merge_private_bfd_data (ibfd, obfd)
 {
   flagword out_flags;
   flagword in_flags;
-
+  unsigned in_mach, out_mach;
+  
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return TRUE;
-
+    return FALSE;
+
+  in_mach = bfd_get_mach (ibfd);
+  out_mach = bfd_get_mach (obfd);
+  if (!out_mach || !in_mach)
+    /* One is unknown, copy the input machine.  */
+    out_mach = in_mach;
+  else if (in_mach != out_mach)
+    {
+      if (in_mach <= bfd_mach_m68060 && out_mach <= bfd_mach_m68060)
+       {
+         /* Merge m68k machine. */
+         if (in_mach > out_mach)
+           out_mach = in_mach;
+       }
+      else if (in_mach >= bfd_mach_mcf_isa_a && out_mach >= bfd_mach_mcf_isa_a)
+       /* Merge cf machine.  */
+       out_mach = bfd_m68k_features_to_mach
+         (bfd_m68k_mach_to_features (in_mach)
+          | bfd_m68k_mach_to_features (out_mach));
+      else
+       /* They are incompatible.  */
+       return FALSE;
+    }
+  bfd_set_arch_mach (obfd, bfd_arch_m68k, out_mach);
+  
   in_flags  = elf_elfheader (ibfd)->e_flags;
   out_flags = elf_elfheader (obfd)->e_flags;
 
   if (!elf_flags_init (obfd))
     {
       elf_flags_init (obfd) = TRUE;
-      elf_elfheader (obfd)->e_flags = in_flags;
+      out_flags = in_flags;
+    }
+  else
+    {
+      /* Copy legacy flags.  */
+      out_flags |= in_flags & (EF_M68K_CPU32 | EF_M68K_M68000 | EF_M68K_CFV4E);
+
+      if (((in_flags | out_flags) & EF_M68K_ISA_MASK)
+         && ((in_flags | out_flags) & (EF_M68K_CPU32 | EF_M68K_M68000)))
+       /* Mixing m68k and cf is not allowed */
+       return FALSE;
+      
+      if (in_flags & EF_M68K_ISA_MASK)
+       {
+         if (out_flags & EF_M68K_ISA_MASK)
+           {
+             /* Merge cf specific flags */
+             if ((in_flags & EF_M68K_ISA_MASK)
+                 > (out_flags & EF_M68K_ISA_MASK))
+               {
+                 out_flags ^= out_flags & EF_M68K_ISA_MASK;
+                 out_flags |= in_flags & EF_M68K_ISA_MASK;
+               }
+             out_flags |= in_flags
+               & (EF_M68K_HW_DIV | EF_M68K_USP | EF_M68K_FLOAT);
+             if (in_flags & EF_M68K_MAC_MASK)
+               {
+                 if (!(out_flags & EF_M68K_MAC_MASK))
+                   out_flags |= in_flags & EF_M68K_MAC_MASK;
+                 else if ((out_flags & EF_M68K_MAC_MASK)
+                          != (in_flags & EF_M68K_MAC_MASK))
+                   /* Cannot mix MACs */
+                   return FALSE;
+               }
+           }
+         else
+           {
+             /* Copy the coldfire bits.  */
+             out_flags &= ~EF_M68K_CF_MASK;
+             out_flags |= in_flags & EF_M68K_CF_MASK;
+           }
+       }
     }
+  elf_elfheader (obfd)->e_flags = out_flags;
 
   return TRUE;
 }
@@ -416,6 +534,7 @@ elf32_m68k_print_private_bfd_data (abfd, ptr)
      PTR ptr;
 {
   FILE *file = (FILE *) ptr;
+  flagword eflags = elf_elfheader (abfd)->e_flags;
 
   BFD_ASSERT (abfd != NULL && ptr != NULL);
 
@@ -427,12 +546,55 @@ elf32_m68k_print_private_bfd_data (abfd, ptr)
   /* xgettext:c-format */
   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
 
-  if (elf_elfheader (abfd)->e_flags & EF_CPU32)
-    fprintf (file, _(" [cpu32]"));
+  if (eflags & EF_M68K_CPU32)
+    fprintf (file, " [cpu32]");
+
+  if (eflags & EF_M68K_M68000)
+    fprintf (file, " [m68000]");
 
-  if (elf_elfheader (abfd)->e_flags & EF_M68000)
-    fprintf (file, _(" [m68000]"));
+  if (eflags & EF_M68K_CFV4E)
+    fprintf (file, " [cfv4e]");
 
+  if (eflags & EF_M68K_ISA_MASK)
+    {
+      char const *isa = _("unknown");
+      char const *mac = _("unknown");
+      
+      switch (eflags & EF_M68K_ISA_MASK)
+       {
+       case EF_M68K_ISA_A:
+         isa = "A";
+         break;
+       case EF_M68K_ISA_A_PLUS:
+         isa = "A+";
+         break;
+       case EF_M68K_ISA_B:
+         isa = "B";
+         break;
+       }
+      fprintf (file, " [isa %s]", isa);
+      if (eflags & EF_M68K_HW_DIV)
+       fprintf (file, " [hwdiv]");
+      switch (eflags & EF_M68K_MAC_MASK)
+       {
+       case 0:
+         mac = NULL;
+         break;
+       case EF_M68K_MAC:
+         mac = "mac";
+         break;
+       case EF_M68K_EMAC:
+         mac = "emac";
+         break;
+       }
+      if (mac)
+       fprintf (file, " [%s]", mac);
+      if (eflags & EF_M68K_USP)
+       fprintf (file, " [usp");
+      if (eflags & EF_M68K_FLOAT)
+       fprintf (file, " [float]");
+    }
+  
   fputc ('\n', file);
 
   return TRUE;
@@ -2313,6 +2475,7 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
                                         elf32_m68k_print_private_bfd_data
 #define elf_backend_reloc_type_class   elf32_m68k_reloc_type_class
 #define elf_backend_plt_sym_val                elf_m68k_plt_sym_val
+#define elf_backend_object_p           elf32_m68k_object_p
 
 #define elf_backend_can_gc_sections 1
 #define elf_backend_can_refcount 1
index 53e16e1..248551f 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for ieee-695 objects.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005
+   2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    Written by Steve Chamberlain of Cygnus Support.
@@ -3466,11 +3466,22 @@ ieee_write_processor (bfd *abfd)
          case bfd_mach_m68040: id = "68040"; break;
          case bfd_mach_m68060: id = "68060"; break;
          case bfd_mach_cpu32:  id = "cpu32"; break;
-         case bfd_mach_mcf5200:id = "5200";  break;
-         case bfd_mach_mcf5206e:id = "5206e"; break;
-         case bfd_mach_mcf5307:id = "5307";  break;
-         case bfd_mach_mcf5407:id = "5407";  break;
-         case bfd_mach_mcf528x:id = "5282";  break;
+         case bfd_mach_mcf_isa_a: id = "isa-a"; break;
+         case bfd_mach_mcf_isa_a_div: id = "isa-a:div"; break;
+         case bfd_mach_mcf_isa_a_div_mac: id = "isa-a:div:mac"; break;
+         case bfd_mach_mcf_isa_a_div_emac: id = "isa-a:div:emac"; break;
+         case bfd_mach_mcf_isa_aplus: id = "isa-a+"; break;
+         case bfd_mach_mcf_isa_aplus_mac: id = "isa-a+:mac"; break;
+         case bfd_mach_mcf_isa_aplus_emac: id = "isa-a+:mac"; break;
+         case bfd_mach_mcf_isa_aplus_usp: id = "isa-a+:usp"; break;
+         case bfd_mach_mcf_isa_aplus_usp_mac: id = "isa-a+:usp:mac"; break;
+         case bfd_mach_mcf_isa_aplus_usp_emac: id = "isa-a+:usp:emac"; break;
+         case bfd_mach_mcf_isa_b: id = "isa-b"; break;
+         case bfd_mach_mcf_isa_b_mac: id = "isa-b:mac"; break;
+         case bfd_mach_mcf_isa_b_emac: id = "isa-b:emac"; break;
+         case bfd_mach_mcf_isa_b_usp_float: id = "isa-b:usp:float"; break;
+         case bfd_mach_mcf_isa_b_usp_float_mac: id = "isa-b:usp:float:mac"; break;
+         case bfd_mach_mcf_isa_b_usp_float_emac: id = "isa-b:usp:float:emac"; break;
          }
 
        if (! ieee_write_id (abfd, id))
index 984ade3..2150cee 100644 (file)
@@ -7,7 +7,7 @@
    (This include file is not for users of the library.)
 
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    Written by Cygnus Support.
index 0d027b0..80dd58e 100644 (file)
@@ -1,3 +1,7 @@
+2006-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * readelf.c (get_machine_flags): Add logic for EF_M68K flags.
+
 2006-02-02  H.J. Lu  <hongjiu.lu@intel.com>
 
        * readelf.c (process_program_headers): Undo the last change.
index f0385d0..0bb2fdb 100644 (file)
@@ -1940,10 +1940,53 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          break;
 
        case EM_68K:
-         if (e_flags & EF_CPU32)
+         if (e_flags & EF_M68K_CPU32)
            strcat (buf, ", cpu32");
-         if (e_flags & EF_M68000)
+         if (e_flags & EF_M68K_M68000)
            strcat (buf, ", m68000");
+         if (e_flags & EF_M68K_ISA_MASK)
+           {
+             char const *isa = _("unknown");
+             char const *mac = _("unknown mac");
+      
+             switch (e_flags & EF_M68K_ISA_MASK)
+               {
+               case EF_M68K_ISA_A:
+                 isa = "A";
+                 break;
+               case EF_M68K_ISA_A_PLUS:
+                 isa = "A+";
+                 break;
+               case EF_M68K_ISA_B:
+                 isa = "B";
+                 break;
+               }
+             strcat (buf, ", cf, isa ");
+             strcat (buf, isa);
+             if (e_flags & EF_M68K_HW_DIV)
+               strcat (buf, ", hwdiv");
+             switch (e_flags & EF_M68K_MAC_MASK)
+               {
+               case 0:
+                 mac = NULL;
+                 break;
+               case EF_M68K_MAC:
+                 mac = "mac";
+                 break;
+               case EF_M68K_EMAC:
+                 mac = "emac";
+                 break;
+               }
+             if (mac)
+               {
+                 strcat (buf, ", ");
+                 strcat (buf, mac);
+               }
+             if (e_flags & EF_M68K_USP)
+               strcat (buf, ", usp");
+             if (e_flags & EF_M68K_FLOAT)
+               strcat (buf, ", float");
+           }
          break;
 
        case EM_PPC:
index 0247c82..6877ccb 100644 (file)
@@ -1,3 +1,31 @@
+2006-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * config/tc-m68k.c (mcf5208_control_regs, mcf5213_control_regs,
+       mcf5329_control_regs): New.
+       (not_current_architecture, selected_arch, selected_cpu): New.
+       (m68k_archs, m68k_extensions): New.
+       (archs): Renamed to ...
+       (m68k_cpus): ... here.  Adjust.
+       (n_arches): Remove.
+       (md_pseudo_table): Add arch and cpu directives.
+       (find_cf_chip, m68k_ip): Adjust table scanning.
+       (no_68851, no_68881): Remove.
+       (md_assemble): Lazily initialize.
+       (select_control_regs): Adjust cpu names. Add 5208, 5213, 5329.
+       (md_init_after_args): Move functionality to m68k_init_arch.
+       (mri_chip): Adjust table scanning.
+       (md_parse_option): Reimplement 'm' processing to add -march & -mcpu
+       options with saner parsing.
+       (m68k_lookup_cpu, m68k_set_arch, m68k_set_cpu, m68k_set_extension,
+       m68k_init_arch): New.
+       (s_m68k_cpu, s_m68k_arch): New.
+       (md_show_usage): Adjust.
+       (m68k_elf_final_processing): Set CF EF flags.
+       * config/tc-m68k.h (m68k_init_after_args): Remove.
+       (tc_init_after_args): Remove.
+       * doc/c-m68k.texi (M68K-Opts): Document -march, -mcpu options.
+       (M68k-Directives): Document .arch and .cpu directives.
+
 2006-02-05  Arnold Metselaar  <arnold.metselaar@planet.nl>
 
        * config/tc-z80.c (z80_start_line_hook): allow .equ and .defl as 
index 761cdd4..b7fb25c 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-m68k.c -- Assemble for the m68k family
    Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -176,6 +176,18 @@ static const enum m68k_register mcf_control_regs[] = {
   RAMBAR0, RAMBAR1, MBAR,
   0
 };
+static const enum m68k_register mcf5208_control_regs[] = {
+  CACR, ACR0, ACR1, VBR, RAMBAR1,
+  0
+};
+static const enum m68k_register mcf5213_control_regs[] = {
+  VBR, RAMBAR, FLASHBAR,
+  0
+};
+static const enum m68k_register mcf5329_control_regs[] = {
+  CACR, ACR0, ACR1, VBR, RAMBAR,
+  0
+};
 static const enum m68k_register mcf5249_control_regs[] = {
   CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR1, MBAR, MBAR2,
   0
@@ -348,90 +360,162 @@ static void s_mri_repeat (int);
 static void s_mri_until (int);
 static void s_mri_while (int);
 static void s_mri_endw (int);
+static void s_m68k_cpu (int);
+static void s_m68k_arch (int);
+
+struct m68k_cpu
+{
+  unsigned long arch;  /* Architecture features.  */
+  unsigned long chip;  /* Specific chip */
+  const char *name;    /* Name */
+  unsigned alias;
+};
 
+/* We hold flags for features explicitly enabled and explicitly
+   disabled.  */
 static int current_architecture;
+static int not_current_architecture;
 static int current_chip;
+static const struct m68k_cpu *selected_arch;
+static const struct m68k_cpu *selected_cpu;
+static int initialized;
 
-struct m68k_cpu
-  {
-    unsigned long arch;
-    unsigned long chip;
-    const char *name;
-    int alias;
-  };
+/* Architecture models.  */
+static const struct m68k_cpu m68k_archs[] =
+{
+  {m68000,                                     cpu_m68000, "68000", 0},
+  {m68010,                                     cpu_m68010, "68010", 0},
+  {m68020|m68881|m68851,                       cpu_m68020, "68020", 0},
+  {m68030|m68881|m68851,                       cpu_m68030, "68030", 0},
+  {m68040,                                     cpu_m68040, "68040", 0},
+  {m68060,                                     cpu_m68060, "68060", 0},
+  {cpu32|m68881,                               cpu_cpu32, "cpu32", 0},
+  {mcfisa_a|mcfhwdiv,                          0, "isaa", 0},
+  {mcfisa_a|mcfhwdiv|mcfisa_aa,                        0, "isaaplus", 0},
+  {mcfisa_a|mcfhwdiv|mcfisa_b,                 0, "isab", 0},
+  {mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+   cpu_cf547x, "cfv4e", 0},
+  {0,0,NULL, 0}
+};
 
-static const struct m68k_cpu archs[] =
-  {
-    { m68000,                                          m68000, "68000", 0 },
-    { m68010,                                          m68010, "68010", 0 },
-    { m68020,                                          m68020, "68020", 0 },
-    { m68030,                                          m68030, "68030", 0 },
-    { m68040,                                          m68040, "68040", 0 },
-    { m68060,                                          m68060, "68060", 0 },
-    { cpu32,                                           cpu32, "cpu32", 0 },
-    { m68881,                                          m68881, "68881", 0 },
-    { m68851,                                          m68851, "68851", 0 },
-    { mcfisa_a,                                                mcf5200, "5200", 0 },
-    { mcfisa_a|mcfhwdiv|mcfmac,                                mcf5206e, "5206e", 0 },
-    { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,      mcf521x, "521x", 0 },
-    { mcfisa_a|mcfhwdiv|mcfemac,                       mcf5249, "5249", 0 },
-    { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,      mcf528x, "528x", 0 },
-    { mcfisa_a|mcfhwdiv|mcfmac,                                mcf5307, "5307", 0 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,               mcf5407, "5407", 0 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "547x", 0 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5480, "548x", 0 },
-    /* Aliases (effectively, so far as gas is concerned) for the above
-       cpus.  */
-    { m68020,                                          m68020, "68k", 1 },
-    { m68000,                                          m68000, "68008", 1 },
-    { m68000,                                          m68000, "68302", 1 },
-    { m68000,                                          m68000, "68306", 1 },
-    { m68000,                                          m68000, "68307", 1 },
-    { m68000,                                          m68000, "68322", 1 },
-    { m68000,                                          m68000, "68356", 1 },
-    { m68000,                                          m68000, "68ec000", 1 },
-    { m68000,                                          m68000, "68hc000", 1 },
-    { m68000,                                          m68000, "68hc001", 1 },
-    { m68020,                                          m68020, "68ec020", 1 },
-    { m68030,                                          m68030, "68ec030", 1 },
-    { m68040,                                          m68040, "68ec040", 1 },
-    { m68060,                                          m68060, "68ec060", 1 },
-    { cpu32,                                           cpu32,  "68330", 1 },
-    { cpu32,                                           cpu32,  "68331", 1 },
-    { cpu32,                                           cpu32,  "68332", 1 },
-    { cpu32,                                           cpu32,  "68333", 1 },
-    { cpu32,                                           cpu32,  "68334", 1 },
-    { cpu32,                                           cpu32,  "68336", 1 },
-    { cpu32,                                           cpu32,  "68340", 1 },
-    { cpu32,                                           cpu32,  "68341", 1 },
-    { cpu32,                                           cpu32,  "68349", 1 },
-    { cpu32,                                           cpu32,  "68360", 1 },
-    { m68881,                                          m68881, "68882", 1 },
-    { mcfisa_a,                                                mcf5200, "5202", 1 },
-    { mcfisa_a,                                                mcf5200, "5204", 1 },
-    { mcfisa_a,                                                mcf5200, "5206", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac,             mcf521x, "5214", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac,             mcf521x, "5216", 1 },
-    { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,             mcf528x, "5280", 1 },
-    { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,             mcf528x, "5281", 1 },
-    { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,             mcf528x, "5282", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,               mcf5407, "cfv4", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5470", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5471", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5472", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5473", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5474", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5475", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5480", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5481", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5482", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5483", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5484", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "5485", 1 },
-    { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,        mcf5470, "cfv4e", 1 },
+/* Architecture extensions.  */
+static const struct m68k_cpu m68k_extensions[] =
+{
+  {m68851,                                     0, "68851", 0},
+  {m68881,                                     0, "68881", 0},
+  {m68881,                                     0, "68882", 0},
+  
+  {mcfhwdiv,                                   0, "div", 1},
+  {mcfusp,                                     0, "usp", 1},
+  {cfloat,                                     0, "float", 1},
+  {mcfmac,                                     0, "mac", 1},
+  {mcfemac,                                    0, "emac", 1},
+   
+  {0,0,NULL, 0}
+};
+
+/* Processor list */
+static const struct m68k_cpu m68k_cpus[] =
+{
+  { m68000,                                    cpu_m68000, "68000", 0},
+  { m68010,                                    cpu_m68010, "68010", 0},
+  { m68020|m68881|m68851,                      cpu_m68020, "68020", 0},
+  { m68030|m68881|m68851,                      cpu_m68030, "68030", 0},
+  { m68040,                                    cpu_m68040, "68040", 0},
+  { m68060,                                    cpu_m68060, "68060", 0},
+  { cpu32|m68881,                              cpu_cpu32, "cpu32",  0},
+  { mcfisa_a,                                  cpu_cf5200, "5200", 0},
+  { mcfisa_a|mcfhwdiv|mcfmac,                  cpu_cf5206e, "5206e", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,        cpu_cf5208, "5208", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,        cpu_cf5213, "5213", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,cpu_cf521x, "521x", 0},
+  { mcfisa_a|mcfhwdiv|mcfemac,         cpu_cf5249, "5249", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,cpu_cf528x, "528x", 0},
+  { mcfisa_a|mcfhwdiv|mcfmac,                  cpu_cf5307, "5307", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf5329, "5329", 0},
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, cpu_cf5407, "5407",0},
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "547x", 0},
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+                                               cpu_cf548x, "548x", 0},
+  /* Aliases (effectively, so far as gas is concerned) for the above
+     cpus.  */
+  { m68020|m68881|m68851,                      cpu_m68020, "68k", 1},
+  { m68000,                                    cpu_m68000, "68008", 1},
+  { m68000,                                    cpu_m68000, "68302", 1},
+  { m68000,                                    cpu_m68000, "68306", 1},
+  { m68000,                                    cpu_m68000, "68307", 1},
+  { m68000,                                    cpu_m68000, "68322", 1},
+  { m68000,                                    cpu_m68000, "68356", 1},
+  { m68000,                                    cpu_m68000, "68ec000", 1},
+  { m68000,                                    cpu_m68000, "68hc000", 1},
+  { m68000,                                    cpu_m68000, "68hc001", 1},
+  { m68020|m68881|m68851,                      cpu_m68020, "68ec020", 1},
+  { m68030|m68881|m68851,                      cpu_m68030, "68ec030", 1},
+  { m68040,                                    cpu_m68040, "68ec040", 1},
+  { m68060,                                    cpu_m68060, "68ec060", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68330", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68331", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68332", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68333", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68334", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68336", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68340", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68341", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68349", 1},
+  { cpu32|m68881,                              cpu_cpu32, "68360", 1},
+  { mcfisa_a,                                  cpu_cf5200, "5202", 1},
+  { mcfisa_a,                                  cpu_cf5200, "5204", 1},
+  { mcfisa_a,                                  cpu_cf5200, "5206", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,                cpu_cf5208, "5207", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,                cpu_cf5213, "5211", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac,                cpu_cf5213, "5212", 1},
+  { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac,       cpu_cf521x, "5214", 1},
+  { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac,       cpu_cf521x, "5216", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf5329, "5327", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf5329, "5328", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf528x, "5280", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf528x, "5281", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac,       cpu_cf528x, "5282", 1},
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, cpu_cf5407,     "cfv4", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "cfv4e", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5470", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5471", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5472", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5473", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5474", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf547x, "5475", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5480", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5481", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5482", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5483", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5484", 1 },
+  { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat,
+    cpu_cf548x, "5485", 1 },
+  {0,0,NULL, 0}
   };
 
-static const int n_archs = sizeof (archs) / sizeof (archs[0]);
+#define CPU_ALLOW_MC 1
+#define CPU_ALLOW_NEGATION 4
+
+static const struct m68k_cpu *m68k_lookup_cpu
+(const char *, const struct m68k_cpu *, int, int *);
+static int m68k_set_arch (const char *, int, int);
+static int m68k_set_cpu (const char *, int, int);
+static int m68k_set_extension (const char *, int, int);
+static void m68k_init_arch (void);
 
 /* This is the assembler relaxation table for m68k. m68k is a rich CISC
    architecture and we have a lot of relaxation modes.  */
@@ -577,6 +661,9 @@ const pseudo_typeS md_pseudo_table[] =
   {"extend", float_cons, 'x'},
   {"ldouble", float_cons, 'x'},
 
+  {"arch", s_m68k_arch, 0},
+  {"cpu", s_m68k_cpu, 0},
+
   /* The following pseudo-ops are supported for MRI compatibility.  */
   {"chip", s_chip, 0},
   {"comline", s_space, 1},
@@ -684,11 +771,11 @@ find_cf_chip (int architecture)
   strcpy (buf, " (");
   cp = buf + strlen (buf);
 
-  for (i = 0, n_chips = 0, n_alias = 0; i < n_archs; ++i)
-    if (archs[i].arch & architecture)
+  for (i = 0, n_chips = 0, n_alias = 0; m68k_cpus[i].name; ++i)
+    if (m68k_cpus[i].arch & architecture)
       {
        n_chips++;
-       if (archs[i].alias)
+       if (m68k_cpus[i].alias)
          n_alias++;
       }
 
@@ -698,8 +785,8 @@ find_cf_chip (int architecture)
   if (n_alias > 1)
     n_chips -= n_alias;
       
-  for (i = 0, j = 0; i < n_archs && j < n_chips; ++i)
-    if (archs[i].arch & architecture)
+  for (i = 0, j = 0; m68k_cpus[i].name && j < n_chips; ++i)
+    if (m68k_cpus[i].arch & architecture)
       {
        if (j)
          {
@@ -722,7 +809,7 @@ find_cf_chip (int architecture)
                cp += strlen (cp);
              }
          }
-       strncpy (cp, archs[i].name, (sizeof (buf) - (cp - buf)));
+       strncpy (cp, m68k_cpus[i].name, (sizeof (buf) - (cp - buf)));
        cp += strlen (cp);
        j++;
       }
@@ -2004,10 +2091,10 @@ m68k_ip (char *instring)
                  {
                    int got_one = 0, idx;
 
-                   for (idx = 0; idx < n_archs; idx++)
+                   for (idx = 0; m68k_cpus[idx].name; idx++)
                      {
-                       if ((archs[idx].arch & ok_arch)
-                           && ! archs[idx].alias)
+                       if ((m68k_cpus[idx].arch & ok_arch)
+                           && ! m68k_cpus[idx].alias)
                          {
                            if (got_one)
                              {
@@ -2015,7 +2102,7 @@ m68k_ip (char *instring)
                                cp += strlen (cp);
                              }
                            got_one = 1;
-                           strcpy (cp, archs[idx].name);
+                           strcpy (cp, m68k_cpus[idx].name);
                            cp += strlen (cp);
                          }
                      }
@@ -3825,8 +3912,6 @@ init_regtable (void)
     insert_reg (init_table[i].name, init_table[i].number);
 }
 
-static int no_68851, no_68881;
-
 void
 md_assemble (char *str)
 {
@@ -3838,6 +3923,17 @@ md_assemble (char *str)
   int shorts_this_frag;
   fixS *fixP;
 
+  if (!selected_cpu && !selected_arch)
+    {
+      /* We've not selected an architecture yet.  Set the default
+        now.  We do this lazily so that an initial .cpu or .arch directive
+        can specify.  */
+      if (!m68k_set_cpu (TARGET_CPU, 1, 1))
+       as_bad (_("unrecognized default cpu `%s'"), TARGET_CPU);
+    }
+  if (!initialized)
+    m68k_init_arch ();
+  
   /* In MRI mode, the instruction and operands are separated by a
      space.  Anything following the operands is a comment.  The label
      has already been removed.  */
@@ -4283,102 +4379,56 @@ select_control_regs (void)
       control_regs = m68020_control_regs;
       break;
       
-    case m68000:
+    case cpu_m68000:
       control_regs = m68000_control_regs;
       break;
-    case m68010:
+    case cpu_m68010:
       control_regs = m68010_control_regs;
       break;
-    case m68020:
-    case m68030:
+    case cpu_m68020:
+    case cpu_m68030:
       control_regs = m68020_control_regs;
       break;
-    case m68040:
+    case cpu_m68040:
       control_regs = m68040_control_regs;
       break;
-    case m68060:
+    case cpu_m68060:
       control_regs = m68060_control_regs;
       break;
-    case cpu32:
+    case cpu_cpu32:
       control_regs = cpu32_control_regs;
       break;
-    case mcf5200:
-    case mcf5206e:
-    case mcf5307:
-    case mcf5407:
+    case cpu_cf5200:
+    case cpu_cf5206e:
+    case cpu_cf5307:
+    case cpu_cf5407:
       control_regs = mcf_control_regs;
       break;
-    case mcf5249:
+    case cpu_cf5249:
       control_regs = mcf5249_control_regs;
       break;
-    case mcf528x:
-    case mcf521x:
+    case cpu_cf528x:
+    case cpu_cf521x:
       control_regs = mcf528x_control_regs;
       break;
-    case mcf5470:
-    case mcf5480:
+    case cpu_cf547x:
+    case cpu_cf548x:
       control_regs = mcfv4e_control_regs;
       break;
+    case cpu_cf5208:
+      control_regs = mcf5208_control_regs;
+      break;
+    case cpu_cf5213:
+      control_regs = mcf5213_control_regs;
+      break;
+    case cpu_cf5329:
+      control_regs = mcf5329_control_regs;
+      break;
     default:
       abort ();
     }
 }
 
-void
-m68k_init_after_args (void)
-{
-  if (cpu_of_arch (current_architecture) == 0)
-    {
-      int i;
-      const char *default_cpu = TARGET_CPU;
-
-      if (*default_cpu == 'm')
-       default_cpu++;
-      for (i = 0; i < n_archs; i++)
-       if (strcasecmp (default_cpu, archs[i].name) == 0)
-         break;
-      if (i == n_archs)
-       {
-         as_bad (_("unrecognized default cpu `%s' ???"), TARGET_CPU);
-         current_architecture |= m68020;
-       }
-      else
-       current_architecture |= archs[i].arch;
-    }
-  /* Permit m68881 specification with all cpus; those that can't work
-     with a coprocessor could be doing emulation.  */
-  if (current_architecture & m68851)
-    {
-      if (current_architecture & m68040)
-       as_warn (_("68040 and 68851 specified; mmu instructions may assemble incorrectly"));
-    }
-  /* What other incompatibilities could we check for?  */
-
-  /* Toss in some default assumptions about coprocessors.  */
-  if (!no_68881
-      && (cpu_of_arch (current_architecture)
-         /* Can CPU32 have a 68881 coprocessor??  */
-         & (m68020 | m68030 | cpu32)))
-    current_architecture |= m68881;
-
-  if (!no_68851
-      && (cpu_of_arch (current_architecture) & m68020up) != 0
-      && (cpu_of_arch (current_architecture) & m68040up) == 0)
-    current_architecture |= m68851;
-
-  if (no_68881 && (current_architecture & m68881))
-    as_bad (_("options for 68881 and no-68881 both given"));
-
-  if (no_68851 && (current_architecture & m68851))
-    as_bad (_("options for 68851 and no-68851 both given"));
-
-  /* Note which set of "movec" control registers is available.  */
-  select_control_regs ();
-
-  if (cpu_of_arch (current_architecture) < m68020
-      || arch_coldfire_p (current_architecture))
-    md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0;
-}
 \f
 /* This is called when a label is defined.  */
 
@@ -5291,10 +5341,10 @@ mri_chip (void)
   while (is_part_of_name (c = *input_line_pointer++))
     ;
   *--input_line_pointer = 0;
-  for (i = 0; i < n_archs; i++)
-    if (strcasecmp (s, archs[i].name) == 0)
+  for (i = 0; m68k_cpus[i].name; i++)
+    if (strcasecmp (s, m68k_cpus[i].name) == 0)
       break;
-  if (i >= n_archs)
+  if (!m68k_cpus[i].name)
     {
       as_bad (_("%s: unrecognized processor name"), s);
       *input_line_pointer = c;
@@ -5307,8 +5357,8 @@ mri_chip (void)
     current_architecture = 0;
   else
     current_architecture &= m68881 | m68851;
-  current_architecture |= archs[i].arch;
-  current_chip = archs[i].chip;
+  current_architecture |= m68k_cpus[i].arch & ~(m68881 | m68851);
+  current_chip = m68k_cpus[i].chip;
 
   while (*input_line_pointer == '/')
     {
@@ -6908,28 +6958,204 @@ s_mri_endw (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 \f
+/* Parse a .cpu directive.  */
+
+static void
+s_m68k_cpu (int ignored ATTRIBUTE_UNUSED)
+{
+  char saved_char;
+  char *name;
+
+  if (initialized)
+    {
+      as_bad (_("already assembled instructions"));
+      ignore_rest_of_line ();
+      return;
+    }
+  
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE(*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  m68k_set_cpu (name, 1, 0);
+  
+  *input_line_pointer = saved_char;
+  demand_empty_rest_of_line ();
+  return;
+}
+
+/* Parse a .arch directive.  */
+
+static void
+s_m68k_arch (int ignored ATTRIBUTE_UNUSED)
+{
+  char saved_char;
+  char *name;
+
+  if (initialized)
+    {
+      as_bad (_("already assembled instructions"));
+      ignore_rest_of_line ();
+      return;
+    }
+  
+  name = input_line_pointer;
+  while (*input_line_pointer && *input_line_pointer != ','
+        && !ISSPACE (*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  if (m68k_set_arch (name, 1, 0))
+    {
+      /* Scan extensions. */
+      do
+       {
+         *input_line_pointer++ = saved_char;
+         if (!*input_line_pointer || ISSPACE (*input_line_pointer))
+           break;
+         name = input_line_pointer;
+         while (*input_line_pointer && *input_line_pointer != ','
+                && !ISSPACE (*input_line_pointer))
+           input_line_pointer++;
+         saved_char = *input_line_pointer;
+         *input_line_pointer = 0;
+       }
+      while (m68k_set_extension (name, 1, 0));
+    }
+  
+  *input_line_pointer = saved_char;
+  demand_empty_rest_of_line ();
+  return;
+}
+\f
+/* Lookup a cpu name in TABLE and return the slot found.  Return NULL
+   if none is found, the caller is responsible for emitting an error
+   message.  If ALLOW_M is non-zero, we allow an initial 'm' on the
+   cpu name, if it begins with a '6' (possibly skipping an intervening
+   'c'.  We also allow a 'c' in the same place.  if NEGATED is
+   non-zero, we accept a leading 'no-' and *NEGATED is set to true, if
+   the option is indeed negated.  */
+
+static const struct m68k_cpu *
+m68k_lookup_cpu (const char *arg, const struct m68k_cpu *table,
+                int allow_m, int *negated)
+{
+  /* allow negated value? */
+  if (negated)
+    {
+      *negated = 0;
+
+      if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-')
+       {
+         arg += 3;
+         *negated = 1;
+       }
+    }
+  
+  /* Remove 'm' or 'mc' prefix from 68k variants.  */
+  if (allow_m)
+    {
+      if (arg[0] == 'm')
+       {
+         if (arg[1] == '6')
+           arg += 1;
+         else if (arg[1] == 'c'  && arg[2] == '6')
+           arg += 2;
+       }
+    }
+  else if (arg[0] == 'c' && arg[1] == '6')
+    arg += 1;
+
+  for (; table->name; table++)
+    if (!strcmp (arg, table->name))
+      return table;
+  return 0;
+}
+
+/* Set the cpu, issuing errors if it is unrecognized, or invalid */
+
+static int
+m68k_set_cpu (char const *name, int allow_m, int silent)
+{
+  const struct m68k_cpu *cpu;
+
+  cpu = m68k_lookup_cpu (name, m68k_cpus, allow_m, NULL);
+
+  if (!cpu)
+    {
+      if (!silent)
+       as_bad (_("cpu `%s' unrecognized"), name);
+      return 0;
+    }
+      
+  if (selected_cpu && selected_cpu != cpu)
+    {
+      as_bad (_("already selected `%s' processor"),
+             selected_cpu->name);
+      return 0;
+    }
+  selected_cpu = cpu;
+  return 1;
+}
+
+/* Set the architecture, issuing errors if it is unrecognized, or invalid */
+
+static int
+m68k_set_arch (char const *name, int allow_m, int silent)
+{
+  const struct m68k_cpu *arch;
+
+  arch = m68k_lookup_cpu (name, m68k_archs, allow_m, NULL);
+
+  if (!arch)
+    {
+      if (!silent)
+       as_bad (_("architecture `%s' unrecognized"), name);
+      return 0;
+    }
+      
+  if (selected_arch && selected_arch != arch)
+    {
+      as_bad (_("already selected `%s' architecture"),
+             selected_arch->name);
+      return 0;
+    }
+  
+  selected_arch = arch;
+  return 1;
+}
+
+/* Set the architecture extension, issuing errors if it is
+   unrecognized, or invalid */
+
+static int
+m68k_set_extension (char const *name, int allow_m, int silent)
+{
+  int negated;
+  const struct m68k_cpu *ext;
+
+  ext = m68k_lookup_cpu (name, m68k_extensions, allow_m, &negated);
+
+  if (!ext)
+    {
+      if (!silent)
+       as_bad (_("extension `%s' unrecognized"), name);
+      return 0;
+    }
+
+  if (negated)
+    not_current_architecture |= ext->arch;
+  else
+    current_architecture |= ext->arch;
+  return 1;
+}
+
 /* md_parse_option
    Invocation line includes a switch not recognized by the base assembler.
-   See if it's a processor-specific option.  These are:
-
-   -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040
-   -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851
-       Select the architecture.  Instructions or features not
-       supported by the selected architecture cause fatal
-       errors.  More than one may be specified.  The default is
-       -m68020 -m68851 -m68881.  Note that -m68008 is a synonym
-       for -m68000, and -m68882 is a synonym for -m68881.
-   -[A]m[c]no-68851, -[A]m[c]no-68881
-       Don't accept 688?1 instructions.  (The "c" is kind of silly,
-       so don't use or document it, but that's the way the parsing
-       works).
-
-   -pic        Indicates PIC.
-   -k  Indicates PIC.  (Sun 3 only.)
-   --pcrel
-       Never turn PC-relative branches into absolute jumps.
-   --bitwise-or
-       Permit `|' to be used in expressions.  */
+ */
 
 #ifdef OBJ_ELF
 const char *md_shortopts = "lSA:m:kQ:V";
@@ -6979,80 +7205,6 @@ md_parse_option (int c, char *arg)
       flag_keep_pcrel = 1;
       break;
 
-    case 'A':
-      if (*arg == 'm')
-       arg++;
-      /* Intentional fall-through.  */
-    case 'm':
-
-      if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-')
-       {
-         int i;
-         unsigned long arch;
-
-         arg += 3;
-         if (*arg == 'm')
-           {
-             arg++;
-             if (arg[0] == 'c' && arg[1] == '6')
-               arg++;
-           }
-         for (i = 0; i < n_archs; i++)
-           if (!strcmp (arg, archs[i].name))
-             break;
-         if (i == n_archs)
-           return 0;
-
-         arch = archs[i].arch;
-         if (arch == m68881)
-           no_68881 = 1;
-         else if (arch == m68851)
-           no_68851 = 1;
-         else
-           return 0;
-       }
-      else
-       {
-         int i;
-
-         if (arg[0] == 'c' && arg[1] == '6')
-           arg++;
-
-         for (i = 0; i < n_archs; i++)
-           if (!strcmp (arg, archs[i].name))
-             {
-               unsigned long arch = archs[i].arch;
-
-               if (cpu_of_arch (arch))
-                 /* It's a cpu spec.  */
-                 {
-                   current_architecture &= ~m68000up;
-                   current_architecture |= arch;
-                   current_chip = archs[i].chip;
-                 }
-               else if (arch == m68881)
-                 {
-                   current_architecture |= m68881;
-                   no_68881 = 0;
-                 }
-               else if (arch == m68851)
-                 {
-                   current_architecture |= m68851;
-                   no_68851 = 0;
-                 }
-               else
-                 /* ??? */
-                 abort ();
-               break;
-             }
-         if (i == n_archs)
-           {
-             as_bad (_("unrecognized architecture specification `%s'"), arg);
-             return 0;
-           }
-       }
-      break;
-
     case OPTION_PIC:
     case 'k':
       flag_want_pic = 1;
@@ -7106,6 +7258,25 @@ md_parse_option (int c, char *arg)
       m68k_rel32_from_cmdline = 1;
       break;
 
+    case 'A':
+#if WARN_DEPRECATED
+      as_tsktsk (_ ("option `-A%s' is deprecated: use `-%s'",
+                   arg, arg));
+#endif
+      /* Intentional fall-through.  */
+    case 'm':
+      if (!strncmp (arg, "arch=", 5))
+       m68k_set_arch (arg + 5, 1, 0);
+      else if (!strncmp (arg, "cpu=", 4))
+       m68k_set_cpu (arg + 4, 1, 0);
+      else if (m68k_set_extension (arg, 0, 1))
+       ;
+      else if (m68k_set_cpu (arg, 0, 1))
+       ;
+      else
+       return 0;
+      break;
+
     default:
       return 0;
     }
@@ -7113,6 +7284,64 @@ md_parse_option (int c, char *arg)
   return 1;
 }
 
+/* Setup tables from the selected arch and/or cpu */
+
+static void
+m68k_init_arch (void)
+{
+  unsigned arch_of_chip = 0;
+  
+  if (not_current_architecture & current_architecture)
+    {
+      as_bad (_("architecture features both enabled and disabled"));
+      not_current_architecture &= ~current_architecture;
+    }
+  if (selected_arch)
+    {
+      arch_of_chip = selected_arch->arch;
+      current_chip = selected_arch->chip;
+      if (selected_cpu && (arch_of_chip & ~selected_cpu->arch))
+       {
+         as_bad (_("selected processor is not from selected architecture"));
+         arch_of_chip = selected_cpu->arch;
+       }
+    }
+  else
+    arch_of_chip = selected_cpu->arch;
+  if (selected_cpu)
+    current_chip = selected_cpu->chip;
+
+  current_architecture |= arch_of_chip;
+  current_architecture &= ~not_current_architecture;
+  if ((current_architecture & m68k_mask)
+      && (current_architecture & ~m68k_mask))
+    {
+      as_bad (_ ("m68k and cf features both selected"));
+      if (arch_of_chip & m68k_mask)
+       current_architecture &= m68k_mask;
+      else
+       current_architecture &= ~m68k_mask;
+    }
+  
+  /* Permit m68881 specification with all cpus; those that can't work
+     with a coprocessor could be doing emulation.  */
+  if (current_architecture & m68851)
+    {
+      if (current_architecture & m68040)
+       as_warn (_("68040 and 68851 specified; mmu instructions may assemble incorrectly"));
+    }
+  /* What other incompatibilities could we check for?  */
+
+  /* Note which set of "movec" control registers is available.  */
+  select_control_regs ();
+
+  if (cpu_of_arch (current_architecture) < m68020
+      || arch_coldfire_p (current_architecture))
+    md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0;
+  
+  initialized = 1;
+}
+
 void
 md_show_usage (FILE *stream)
 {
@@ -7123,17 +7352,17 @@ md_show_usage (FILE *stream)
   /* Get the canonical name for the default target CPU.  */
   if (*default_cpu == 'm')
     default_cpu++;
-  for (i = 0; i < n_archs; i++)
+  for (i = 0; m68k_cpus[i].name; i++)
     {
-      if (strcasecmp (default_cpu, archs[i].name) == 0)
+      if (strcasecmp (default_cpu, m68k_cpus[i].name) == 0)
        {
-         default_arch = archs[i].arch;
-         for (i = 0; i < n_archs; i++)
+         default_arch = m68k_cpus[i].arch;
+         for (i = 0; m68k_cpus[i].name; i++)
            {
-             if (archs[i].arch == default_arch
-                 && !archs[i].alias)
+             if (m68k_cpus[i].arch == default_arch
+                 && !m68k_cpus[i].alias)
                {
-                 default_cpu = archs[i].name;
+                 default_cpu = m68k_cpus[i].name;
                  break;
                }
            }
@@ -7141,32 +7370,45 @@ md_show_usage (FILE *stream)
     }
 
   fprintf (stream, _("\
-680X0 options:\n\
--l                     use 1 word for refs to undefined symbols [default 2]\n\
--m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060 |\n\
--m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360 | -mcpu32 |\n\
--m5200  | -m5202  | -m5204  | -m5206  | -m5206e | -m521x  | -m5249  |\n\
--m528x  | -m5307  | -m5407  | -m547x  | -m548x  | -mcfv4  | -mcfv4e\n\
-                       specify variant of 680X0 architecture [default %s]\n\
--m68881 | -m68882 | -mno-68881 | -mno-68882\n\
-                       target has/lacks floating-point coprocessor\n\
-                       [default yes for 68020, 68030, and cpu32]\n"),
-          default_cpu);
+-march=<arch>          set architecture\n\
+-mcpu=<cpu>            set cpu [default %s]\n\
+"), default_cpu);
+  for (i = 0; m68k_extensions[i].name; i++)
+    fprintf (stream, _("\
+-m[no-]%-16s enable/disable %s architecture extension\n\
+"), m68k_extensions[i].name, m68k_extensions[i].alias ? "ColdFire" : "m68k");
+  
   fprintf (stream, _("\
--m68851 | -mno-68851\n\
-                       target has/lacks memory-management unit coprocessor\n\
-                       [default yes for 68020 and up]\n\
+-l                     use 1 word for refs to undefined symbols [default 2]\n\
 -pic, -k               generate position independent code\n\
 -S                     turn jbsr into jsr\n\
 --pcrel                 never turn PC-relative branches into absolute jumps\n\
 --register-prefix-optional\n\
                        recognize register names without prefix character\n\
---bitwise-or           do not treat `|' as a comment character\n"));
-  fprintf (stream, _("\
+--bitwise-or           do not treat `|' as a comment character\n\
 --base-size-default-16 base reg without size is 16 bits\n\
 --base-size-default-32 base reg without size is 32 bits (default)\n\
 --disp-size-default-16 displacement with unknown size is 16 bits\n\
---disp-size-default-32 displacement with unknown size is 32 bits (default)\n"));
+--disp-size-default-32 displacement with unknown size is 32 bits (default)\n\
+"));
+  
+  fprintf (stream, _("Architecture variants are: "));
+  for (i = 0; m68k_archs[i].name; i++)
+    {
+      if (i)
+       fprintf (stream, " | ");
+      fprintf (stream, m68k_archs[i].name);
+    }
+  fprintf (stream, "\n");
+
+  fprintf (stream, _("Processor variants are: "));
+  for (i = 0; m68k_cpus[i].name; i++)
+    {
+      if (i)
+       fprintf (stream, " | ");
+      fprintf (stream, m68k_cpus[i].name);
+    }
+  fprintf (stream, _("\n"));
 }
 \f
 #ifdef TEST2
@@ -7313,14 +7555,42 @@ md_pcrel_from (fixS *fixP)
 void
 m68k_elf_final_processing (void)
 {
-  /* Set file-specific flags if this is a cpu32 processor.  */
+  unsigned flags = 0;
+  
   if (arch_coldfire_fpu (current_architecture))
-    elf_elfheader (stdoutput)->e_flags |= EF_CFV4E;
+    flags |= EF_M68K_CFV4E;
+  /* Set file-specific flags if this is a cpu32 processor.  */
   if (cpu_of_arch (current_architecture) & cpu32)
-    elf_elfheader (stdoutput)->e_flags |= EF_CPU32;
+    flags |= EF_M68K_CPU32;
   else if ((cpu_of_arch (current_architecture) & m68000up)
           && !(cpu_of_arch (current_architecture) & m68020up))
-    elf_elfheader (stdoutput)->e_flags |= EF_M68000;
+    flags |= EF_M68K_M68000;
+  
+  if (current_architecture & mcfisa_a)
+    {
+      /* Set coldfire specific elf flags */
+      if (current_architecture & mcfisa_b)
+       flags |= EF_M68K_ISA_B;
+      else if (current_architecture & mcfisa_aa)
+       flags |= EF_M68K_ISA_A_PLUS;
+      else
+       flags |= EF_M68K_ISA_A;
+
+      if (current_architecture & mcfhwdiv)
+       flags |= EF_M68K_HW_DIV;
+
+      if (current_architecture & mcfusp)
+       flags |= EF_M68K_USP;
+      
+      if (current_architecture & cfloat)
+       flags |= EF_M68K_FLOAT;
+
+      if (current_architecture & mcfmac)
+       flags |= EF_M68K_MAC;
+      else if (current_architecture & mcfemac)
+       flags |= EF_M68K_EMAC;
+    }
+  elf_elfheader (stdoutput)->e_flags |= flags;
 }
 #endif
 
index 523a387..fc05a92 100644 (file)
@@ -145,9 +145,6 @@ extern void m68k_elf_final_processing (void);
 
 #define DIFF_EXPR_OK
 
-extern void m68k_init_after_args (void);
-#define tc_init_after_args m68k_init_after_args
-
 extern int m68k_parse_long_option (char *);
 #define md_parse_long_option m68k_parse_long_option
 
index d3c849c..d4da2a1 100644 (file)
@@ -32,6 +32,50 @@ dependent options:
 
 @table @samp
 
+@cindex @samp{-march=} command line option, M680x0
+@item -march=@var{architecture}
+This option specifies a target architecture.  The following
+architectures are recognized:
+@code{68000},
+@code{68010},
+@code{68020},
+@code{68030},
+@code{68040},
+@code{68060},
+@code{cpu32},
+@code{isaa},
+@code{isaaplus},
+@code{isab} and
+@code{cfv4e}.
+
+
+@cindex @samp{-mcpu=} command line option, M680x0
+@item -mcpu=@var{cpu}
+This option specifies a target cpu.  When used in conjunction with the
+@option{-march} option, the cpu must be within the specified
+architecture.  Also, the generic features of the architecture are used
+for instruction generation, rather than those of the specific chip.
+
+@cindex @samp{-m[no-]68851} command line option, M680x0
+@cindex @samp{-m[no-]68881} command line option, M680x0
+@cindex @samp{-m[no-]div} command line option, M680x0
+@cindex @samp{-m[no-]usp} command line option, M680x0
+@cindex @samp{-m[no-]float} command line option, M680x0
+@cindex @samp{-m[no-]mac} command line option, M680x0
+@cindex @samp{-m[no-]emac} command line option, M680x0
+@item -m[no-]68851
+@item -m[no-]68881
+@item -m[no-]div
+@item -m[no-]usp
+@item -m[no-]float
+@item -m[no-]mac
+@item -m[no-]emac
+
+Enable or disable various architecture specific features.  If a chip
+or architecture by default supports an option (for instance
+@option{-march=isaaplus} includes the @option{-mdiv} option),
+explicitly disabling the option will override the default.
+
 @cindex @samp{-l} option, M680x0
 @item -l
 You can use the @samp{-l} option to shorten the size of references to undefined
@@ -398,6 +442,25 @@ aligns the output to an even byte boundary.
 @cindex @code{skip} directive, M680x0
 @item .skip
 This directive is identical to a @code{.space} directive.
+
+@cindex @code{arch} directive, M680x0
+@item .arch @var{name}
+Select the target architecture and extension features.  Valid valuse
+for @var{name} are the same as for the @option{-march} command line
+option.  This directive cannot be specified after
+any instructions have been assembled.  If it is given multiple times,
+or in conjuction with the @option{-march} option, all uses must be for
+the same architecture and extension set.
+
+@cindex @code{cpu} directive, M680x0
+@item .cpu @var{name}
+Select the target cpu.  Valid valuse
+for @var{name} are the same as for the @option{-mcpu} command line
+option.  This directive cannot be specified after
+any instructions have been assembled.  If it is given multiple times,
+or in conjuction with the @option{-mopt} option, all uses must be for
+the same cpu.
+
 @end table
 
 @need 2000
index 99cb994..a51a1f4 100644 (file)
@@ -1,3 +1,8 @@
+2006-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * testsuite/gas/m68k/all.exp: Add arch-cpu-1 test.
+       * testsuite/gas/m68k/arch-cpu-1.[sd]: New.
+
 2005-02-02  Paul Brook  <paul@codesourcery.com>
 
        * gas/arm/thumb2_invert.d: New test.
index 6077817..9516b1a 100644 (file)
@@ -39,6 +39,7 @@ if [istarget m68*-*-*] then {
     run_dump_test mcf-mac
     run_dump_test mcf-emac
     run_dump_test mcf-fpu
+    run_dump_test arch-cpu-1
 
     set testname "68000 operands"
     gas_run "operands.s" "-m68000" "2>err.out"
index 1bac01d..fca9b33 100644 (file)
@@ -1,3 +1,15 @@
+2006-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * m68k.h (EF_CPU32, EF_M68000, EF_CFV4E): Rename to ...
+       (EF_M68K_CPU32, EF_M68K_M68000, EF_M68K_CFV4E): ... here.
+       (EF_M68K_ISA_MASK, EF_M68K_ISA_A, EF_M68K_M68K_ISA_A_PLUS,
+       EF_M68K_ISA_B, EF_M68K_HW_DIV, EF_M68K_MAC_MASK, EF_M68K_MAC,
+       EF_M68K_EMAC, EF_M68K_USP, EF_M68K_FLOAT): New.
+
+2006-02-06  Steve Ellcey  <sje@cup.hp.com>
+
+       * ia64.h (SHF_IA_64_HP_TLS): New.
+
 2006-01-18  Alexandre Oliva  <aoliva@redhat.com>
 
        Introduce TLS descriptors for i386 and x86_64.
index 05e2eb8..929cd60 100644 (file)
@@ -1,5 +1,5 @@
 /* MC68k ELF support for BFD.
-   Copyright 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2002, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -52,8 +52,22 @@ START_RELOC_NUMBERS (elf_m68k_reloc_type)
   RELOC_NUMBER (R_68K_GNU_VTENTRY, 24)
 END_RELOC_NUMBERS (R_68K_max)
 
-#define EF_CPU32    0x00810000
-#define EF_M68000   0x01000000
-#define EF_CFV4E    0x00008000
+#define EF_M68K_CPU32    0x00810000
+#define EF_M68K_M68000   0x01000000
+#define EF_M68K_CFV4E    0x00008000
 
+/* We use the bottom 8 bits to encode information about the
+   coldfire variant.  */
+#define EF_M68K_ISA_MASK       0x07  /* Which ISA */
+#define EF_M68K_ISA_A          0x01
+#define EF_M68K_ISA_A_PLUS     0x02
+#define EF_M68K_ISA_B          0x03
+#define EF_M68K_HW_DIV         0x08  /* Has HW divide */
+#define EF_M68K_MAC_MASK       0x30 
+#define EF_M68K_MAC            0x10  /* Has MAC */
+#define EF_M68K_EMAC           0x20  /* Has EMAC */
+#define EF_M68K_USP            0x40  /* Has USP insns */
+#define EF_M68K_FLOAT          0x80  /* Has float insns */
+#define EF_M68K_CF_MASK                0xFF
+     
 #endif
index 84bef98..0d21658 100644 (file)
@@ -1,6 +1,6 @@
 /* Opcode table header for m680[01234]0/m6888[12]/m68851.
    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2001,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2006 Free Software Foundation, Inc.
 
    This file is part of GDB, GAS, and the GNU binutils.
 
    structure.  */
 #define        _m68k_undef  0
 #define        m68000   0x001
-#define        m68008   m68000 /* Synonym for -m68000.  otherwise unused.  */
 #define        m68010   0x002
 #define        m68020   0x004
 #define        m68030   0x008
-#define m68ec030 m68030 /* Similar enough to -m68030 to ignore differences;
-                          gas will deal with the few differences.  */
 #define        m68040   0x010
-/* There is no 68050.  */
 #define m68060   0x020
 #define        m68881   0x040
-#define        m68882   m68881 /* Synonym for -m68881.  otherwise unused.  */
 #define        m68851   0x080
 #define cpu32   0x100          /* e.g., 68332 */
+#define m68k_mask  0x1ff
 
 #define mcfmac   0x200         /* ColdFire MAC. */
 #define mcfemac  0x400         /* ColdFire EMAC. */
 #define mcfisa_b 0x8000                /* ColdFire ISA_B.  */
 #define mcfusp   0x10000       /* ColdFire USP instructions.  */
 
-#define mcf5200  0x20000
-#define mcf5206e 0x40000
-#define mcf521x  0x80000
-#define mcf5249  0x100000
-#define mcf528x  0x200000
-#define mcf5307  0x400000
-#define mcf5407  0x800000
-#define mcf5470  0x1000000
-#define mcf5480  0x2000000
-
- /* Handy aliases.  */
+/* Handy aliases.  */
 #define        m68040up   (m68040 | m68060)
 #define        m68030up   (m68030 | m68040up)
 #define        m68020up   (m68020 | m68030up)
 #define        m68010up   (m68010 | cpu32 | m68020up)
 #define        m68000up   (m68000 | m68010up)
 
-#define        mfloat  (m68881 | m68882 | m68040 | m68060)
+#define        mfloat  (m68881 | m68040 | m68060)
 #define        mmmu    (m68851 | m68030 | m68040 | m68060)
 
+/* CPU numbering.  There are too many of these to use a bit vector.
+   These are a one-of-many selection.  Choose a numbering scheme that
+   simply maps onto manufacturer's part numbers. */
+
+/* All m68k cpus */
+#define cpu_m68k 0
+/* All coldfire cpus */
+#define cpu_cf  1000000
+
+#define cpu_m68000  (cpu_m68k + 68000)
+#define        cpu_m68008  cpu_m68000 /* Synonym for -m68000.  otherwise unused.  */
+#define        cpu_m68010  (cpu_m68k + 68010)
+#define        cpu_m68020  (cpu_m68k + 68020)
+#define        cpu_m68030  (cpu_m68k + 68030)
+#define cpu_m68ec030 cpu_m68030 /* Similar enough to -m68030 to ignore
+                          differences; gas will deal with the few
+                          differences.  */
+#define        cpu_m68040  (cpu_m68k + 68040)
+/* There is no 68050.  */
+#define cpu_m68060  (cpu_m68k + 68060)
+#define        cpu_m68851  (cpu_m68k + 68851)
+#define        cpu_m68881  (cpu_m68k + 68881)
+#define        cpu_m68882   cpu_m68881 /* Synonym for -m68881.  otherwise unused.  */
+#define cpu_cpu32   (cpu_m68k + 32)
+
+#define cpu_cf5200  (cpu_cf + 5200)
+#define cpu_cf5206e (cpu_cf + 5206)
+#define cpu_cf5208  (cpu_cf + 5208)
+#define cpu_cf521x  (cpu_cf + 5210)
+#define cpu_cf5213  (cpu_cf + 5213)
+#define cpu_cf5249  (cpu_cf + 5249)
+#define cpu_cf528x  (cpu_cf + 5280)
+#define cpu_cf5307  (cpu_cf + 5307)
+#define cpu_cf5329  (cpu_cf + 5329)
+#define cpu_cf5407  (cpu_cf + 5407)
+#define cpu_cf547x  (cpu_cf + 5470)
+#define cpu_cf548x  (cpu_cf + 5480)
+
 /* The structure used to hold information for an opcode.  */
 
 struct m68k_opcode
index 27ca4c4..51bbb1c 100644 (file)
@@ -1,3 +1,7 @@
+2006-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * m68k-dis.c (print_insn_m68k): Use bfd_m68k_mach_to_features.
+
 2006-01-26  David Ung  <davidu@mips.com>
 
        * mips-opc.c: Add I33 masks to these MIPS32R2 instructions: prefx,
index 5e4150d..8fc7015 100644 (file)
@@ -1,6 +1,6 @@
 /* Print Motorola 68k instructions.
    Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is free software; you can redistribute it and/or modify
@@ -1396,58 +1396,9 @@ print_insn_m68k (bfd_vma memaddr, disassemble_info *info)
     /* Error return.  */
     return -1;
 
-  switch (info->mach)
-    {
-    default:
-    case 0:
-      arch_mask = (unsigned int) -1;
-      break;
-    case bfd_mach_m68000:
-      arch_mask = m68000|m68881|m68851;
-      break;
-    case bfd_mach_m68008:
-      arch_mask = m68008|m68881|m68851;
-      break;
-    case bfd_mach_m68010:
-      arch_mask = m68010|m68881|m68851;
-      break;
-    case bfd_mach_m68020:
-      arch_mask = m68020|m68881|m68851;
-      break;
-    case bfd_mach_m68030:
-      arch_mask = m68030|m68881|m68851;
-      break;
-    case bfd_mach_m68040:
-      arch_mask = m68040|m68881|m68851;
-      break;
-    case bfd_mach_m68060:
-      arch_mask = m68060|m68881|m68851;
-      break;
-    case bfd_mach_mcf5200:
-      arch_mask = mcfisa_a;
-      break;
-    case bfd_mach_mcf521x:
-    case bfd_mach_mcf528x:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp|mcfemac;
-      break;
-    case bfd_mach_mcf5206e:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
-      break;
-    case bfd_mach_mcf5249:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfemac;
-      break;
-    case bfd_mach_mcf5307:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
-      break;
-    case bfd_mach_mcf5407:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac;
-      break;
-    case bfd_mach_mcf547x:
-    case bfd_mach_mcf548x:
-    case bfd_mach_mcfv4e:
-      arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac;
-      break;
-    }
+  arch_mask = bfd_m68k_mach_to_features (info->mach);
+  if (!arch_mask)
+    arch_mask = ~(unsigned int)0;
 
   FETCH_DATA (info, buffer + 2);
   major_opcode = (buffer[0] >> 4) & 15;