[m68k] cleanup arch/cpu selection

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[m68k] cleanup arch/cpu selection

Nathan Sidwell
This patch implements -march= and -mcpu= options to m68k's assembler.  It also
adds a set of -m[no-]foo extension switches.  In addition I've rationalized the
coldfire bfd_mach enumeration to work along the lines of architectural features,
rather than chip numbering -- there's an ever increasing number of chips.  I've
kept the old machine names and old assembler switches for compatibility.

The architectures supported are, 68000, 68010, 68020, 68030, 68040, 68060,
cpu32, isaa, isaaplus, isab & cfv4e.  (Although coldfire defines architecture
'families' the chips in a single family can have differening isas and
extensions.)  The extensions are 68851, 68881, div, usp, float, mac & emac.

I've added .arch and .cpu assembler directives to specify in the assembly file
itself what chip to target.  CodeSourcery intends to make use of this in
upcoming gcc patches.  This behaviour is unashamedly copied from the arm
implementation.

I've defined a set of ef_flag bits to encode the coldfire information such that
the linker can correctly check object file compatibility.  For compatibility, we
allow mixing an object file with no ISA specified with an updated one.

I separated out the chip numbering scheme from the architecture feature bit mask
-- we'd soon run out of bits if we kept going the way we were.  Although I have
defined a numbering scheme in include/opcode.h, it's only used by the assembler
to set the control registers.  That use could be simplified by a suitable change
to the m68k_cpus and m68k_archs array.  I didn't want to do that with this
patch, as it's already large enough.

I've tested this by building a complete m68k toolchain, but I have no m68k
hardware to test it.  However, I don't expect a problem there as the changes I
made would have been excercised by the build process.

ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
[hidden email]    ::     http://www.planetfall.pwp.blueyonder.co.uk


2006-01-26  Nathan Sidwell  <[hidden email]>

        * bfd/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/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_ISA_MASK, EF_ISA_A, EF_ISA_A_PLUS,
        EF_ISA_B, EF_HW_DIV, EF_MAC_MASK, EF_MAC, EF_EMAC, EF_USP,
        EF_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.
       
Index: bfd/archures.c
===================================================================
RCS file: /cvs/src/src/bfd/archures.c,v
retrieving revision 1.113
diff -c -3 -p -r1.113 archures.c
*** bfd/archures.c 16 Dec 2005 10:23:06 -0000 1.113
--- bfd/archures.c 27 Jan 2006 12:07:23 -0000
*************** DESCRIPTION
*** 80,95 ****
  .#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
  .  bfd_arch_vax,       {* DEC Vax *}
  .  bfd_arch_i960,      {* Intel 960 *}
  .    {* The order of the following is important.
--- 80,101 ----
  .#define bfd_mach_m68040 6
  .#define bfd_mach_m68060 7
  .#define bfd_mach_cpu32  8
! .#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.
*************** bfd_default_scan (const bfd_arch_info_ty
*** 1004,1026 ****
        break;
      case 5200:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf5200;
        break;
      case 5206:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf5206e;
        break;
      case 5307:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf5307;
        break;
      case 5407:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf5407;
        break;
      case 5282:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf528x;
        break;
 
      case 32000:
--- 1010,1032 ----
        break;
      case 5200:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf_isa_a;
        break;
      case 5206:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf_isa_a_div_mac;
        break;
      case 5307:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf_isa_a_div_mac;
        break;
      case 5407:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf_isa_b_mac;
        break;
      case 5282:
        arch = bfd_arch_m68k;
!       number = bfd_mach_mcf_isa_b_usp_float_emac;
        break;
 
      case 32000:
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.111
diff -c -3 -p -r1.111 bfd-in.h
*** bfd/bfd-in.h 7 Dec 2005 14:43:53 -0000 1.111
--- bfd/bfd-in.h 27 Jan 2006 12:07:24 -0000
*************** extern struct bfd_section *_bfd_elf_tls_
*** 706,711 ****
--- 706,715 ----
  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: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.378
diff -c -3 -p -r1.378 bfd-in2.h
*** bfd/bfd-in2.h 18 Jan 2006 21:07:48 -0000 1.378
--- bfd/bfd-in2.h 27 Jan 2006 12:07:30 -0000
***************
*** 8,15 ****
  /* 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, 2006
!    Free Software Foundation, Inc.
 
     Contributed by Cygnus Support.
 
--- 8,14 ----
  /* 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.
 
     Contributed by Cygnus Support.
 
*************** extern struct bfd_section *_bfd_elf_tls_
*** 714,719 ****
--- 713,722 ----
  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 **);
*************** enum bfd_architecture
*** 1670,1685 ****
  #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
    bfd_arch_vax,       /* DEC Vax */
    bfd_arch_i960,      /* Intel 960 */
      /* The order of the following is important.
--- 1673,1694 ----
  #define bfd_mach_m68040 6
  #define bfd_mach_m68060 7
  #define bfd_mach_cpu32  8
! #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: bfd/cpu-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/cpu-m68k.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 cpu-m68k.c
*** bfd/cpu-m68k.c 4 May 2005 15:53:06 -0000 1.10
--- bfd/cpu-m68k.c 27 Jan 2006 12:07:31 -0000
***************
*** 22,27 ****
--- 22,28 ----
  #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, }
*************** static const bfd_arch_info_type arch_inf
*** 34,52 ****
      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),
    };
 
  const bfd_arch_info_type bfd_m68k_arch =
    N(0, "m68k", TRUE, &arch_info_struct[0]);
--- 35,183 ----
      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_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: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.84
diff -c -3 -p -r1.84 elf32-m68k.c
*** bfd/elf32-m68k.c 1 Nov 2005 22:57:23 -0000 1.84
--- bfd/elf32-m68k.c 27 Jan 2006 12:07:32 -0000
***************
*** 24,29 ****
--- 24,30 ----
  #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));
*************** elf_m68k_link_hash_table_create (abfd)
*** 372,377 ****
--- 373,428 ----
    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_M68000)
+     features |= m68000;
+   else if (eflags & EF_CPU32)
+     features |= cpu32;
+   else if (eflags & EF_ISA_MASK)
+     {
+       switch (eflags & EF_ISA_MASK)
+ {
+ case EF_ISA_B:
+  features |= mcfisa_b;
+  /* FALLTHROUGH */
+ case EF_ISA_A_PLUS:
+  features |= mcfisa_aa;
+  /* FALLTHROUGH */
+ case EF_ISA_A:
+  features |= mcfisa_a;
+  break;
+ }
+       if (eflags & EF_HW_DIV)
+ features |= mcfhwdiv;
+       switch (eflags & EF_MAC_MASK)
+ {
+ case EF_MAC:
+  features |= mcfmac;
+  break;
+ case EF_EMAC:
+  features |= mcfemac;
+  break;
+ }
+       if (eflags & EF_USP)
+ features |= mcfusp;
+       if (eflags & EF_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)
*************** elf32_m68k_merge_private_bfd_data (ibfd,
*** 392,410 ****
  {
    flagword out_flags;
    flagword in_flags;
!
    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
!     return TRUE;
 
    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;
      }
 
    return TRUE;
  }
--- 443,526 ----
  {
    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 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;
!       out_flags = in_flags;
!     }
!   else
!     {
!       /* Copy legacy flags.  */
!       out_flags |= in_flags & (EF_CPU32 | EF_M68000 | EF_CFV4E);
!
!       if (((in_flags | out_flags) & EF_ISA_MASK)
!  && ((in_flags | out_flags) & (EF_CPU32 | EF_M68000)))
! /* Mixing m68k and cf is not allowed */
! return FALSE;
!      
!       if (in_flags & EF_ISA_MASK)
! {
!  if (out_flags & EF_ISA_MASK)
!    {
!      /* Merge cf specific flags */
!      if ((in_flags & EF_ISA_MASK) > (out_flags & EF_ISA_MASK))
! {
!  out_flags ^= out_flags & EF_ISA_MASK;
!  out_flags |= in_flags & EF_ISA_MASK;
! }
!      out_flags |= in_flags & (EF_HW_DIV | EF_USP | EF_FLOAT);
!      if (in_flags & EF_MAC_MASK)
! {
!  if (!(out_flags & EF_MAC_MASK))
!    out_flags |= in_flags & EF_MAC_MASK;
!  else if ((out_flags & EF_MAC_MASK)
!   != (in_flags & EF_MAC_MASK))
!    /* Cannot mix MACs */
!    return FALSE;
! }
!    }
!  else
!    {
!      /* Copy the coldfire bits.  */
!      out_flags &= ~EF_CF_MASK;
!      out_flags |= in_flags & EF_CF_MASK;
!    }
! }
      }
+   elf_elfheader (obfd)->e_flags = out_flags;
 
    return TRUE;
  }
*************** elf32_m68k_print_private_bfd_data (abfd,
*** 416,421 ****
--- 532,538 ----
       PTR ptr;
  {
    FILE *file = (FILE *) ptr;
+   flagword eflags = elf_elfheader (abfd)->e_flags;
 
    BFD_ASSERT (abfd != NULL && ptr != NULL);
 
*************** elf32_m68k_print_private_bfd_data (abfd,
*** 427,438 ****
    /* 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 (elf_elfheader (abfd)->e_flags & EF_M68000)
!     fprintf (file, _(" [m68000]"));
 
    fputc ('\n', file);
 
    return TRUE;
--- 544,598 ----
    /* xgettext:c-format */
    fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
 
!   if (eflags & EF_CPU32)
!     fprintf (file, " [cpu32]");
!
!   if (eflags & EF_M68000)
!     fprintf (file, " [m68000]");
 
!   if (eflags & EF_CFV4E)
!     fprintf (file, " [cfv4e]");
 
+   if (eflags & EF_ISA_MASK)
+     {
+       char const *isa = _("unknown");
+       char const *mac = _("unknown");
+      
+       switch (eflags & EF_ISA_MASK)
+ {
+ case EF_ISA_A:
+  isa = "A";
+  break;
+ case EF_ISA_A_PLUS:
+  isa = "A+";
+  break;
+ case EF_ISA_B:
+  isa = "B";
+  break;
+ }
+       fprintf (file, " [isa %s]", isa);
+       if (eflags & EF_HW_DIV)
+ fprintf (file, " [hwdiv]");
+       switch (eflags & EF_MAC_MASK)
+ {
+ case 0:
+  mac = NULL;
+  break;
+ case EF_MAC:
+  mac = "mac";
+  break;
+ case EF_EMAC:
+  mac = "emac";
+  break;
+ }
+       if (mac)
+ fprintf (file, " [%s]", mac);
+       if (eflags & EF_USP)
+ fprintf (file, " [usp");
+       if (eflags & EF_FLOAT)
+ fprintf (file, " [float]");
+     }
+  
    fputc ('\n', file);
 
    return TRUE;
*************** elf_m68k_plt_sym_val (bfd_vma i, const a
*** 2313,2318 ****
--- 2473,2479 ----
                                          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: bfd/ieee.c
===================================================================
RCS file: /cvs/src/src/bfd/ieee.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 ieee.c
*** bfd/ieee.c 6 Oct 2005 19:21:14 -0000 1.51
--- bfd/ieee.c 27 Jan 2006 12:07:35 -0000
*************** ieee_write_processor (bfd *abfd)
*** 3466,3476 ****
   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;
   }
 
  if (! ieee_write_id (abfd, id))
--- 3466,3487 ----
   case bfd_mach_m68040: id = "68040"; break;
   case bfd_mach_m68060: id = "68060"; break;
   case bfd_mach_cpu32:  id = "cpu32"; 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: bfd/libbfd.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.h,v
retrieving revision 1.170
diff -c -3 -p -r1.170 libbfd.h
*** bfd/libbfd.h 18 Jan 2006 21:07:48 -0000 1.170
--- bfd/libbfd.h 27 Jan 2006 12:07:37 -0000
***************
*** 7,13 ****
     (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
     Free Software Foundation, Inc.
 
     Written by Cygnus Support.
--- 7,13 ----
     (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
     Free Software Foundation, Inc.
 
     Written by Cygnus Support.
Index: gas/config/tc-m68k.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68k.c,v
retrieving revision 1.70
diff -c -3 -p -r1.70 tc-m68k.c
*** gas/config/tc-m68k.c 20 Sep 2005 18:24:47 -0000 1.70
--- gas/config/tc-m68k.c 27 Jan 2006 12:07:45 -0000
*************** static const enum m68k_register mcf_cont
*** 176,181 ****
--- 176,193 ----
    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
*************** static void s_mri_repeat (int);
*** 348,437 ****
  static void s_mri_until (int);
  static void s_mri_while (int);
  static void s_mri_endw (int);
 
  static int current_architecture;
  static int current_chip;
 
! struct m68k_cpu
!   {
!     unsigned long arch;
!     unsigned long chip;
!     const char *name;
!     int alias;
!   };
 
! 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 },
    };
 
! static const int n_archs = sizeof (archs) / sizeof (archs[0]);
 
  /* This is the assembler relaxation table for m68k. m68k is a rich CISC
     architecture and we have a lot of relaxation modes.  */
--- 360,521 ----
  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;
+
+ /* 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}
+ };
 
! /* 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}
    };
 
! #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.  */
*************** const pseudo_typeS md_pseudo_table[] =
*** 577,582 ****
--- 661,669 ----
    {"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},
*************** find_cf_chip (int architecture)
*** 684,694 ****
    strcpy (buf, " (");
    cp = buf + strlen (buf);
 
!   for (i = 0, n_chips = 0, n_alias = 0; i < n_archs; ++i)
!     if (archs[i].arch & architecture)
        {
  n_chips++;
! if (archs[i].alias)
   n_alias++;
        }
 
--- 771,781 ----
    strcpy (buf, " (");
    cp = buf + strlen (buf);
 
!   for (i = 0, n_chips = 0, n_alias = 0; m68k_cpus[i].name; ++i)
!     if (m68k_cpus[i].arch & architecture)
        {
  n_chips++;
! if (m68k_cpus[i].alias)
   n_alias++;
        }
 
*************** find_cf_chip (int architecture)
*** 698,705 ****
    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)
        {
  if (j)
   {
--- 785,792 ----
    if (n_alias > 1)
      n_chips -= n_alias;
       
!   for (i = 0, j = 0; m68k_cpus[i].name && j < n_chips; ++i)
!     if (m68k_cpus[i].arch & architecture)
        {
  if (j)
   {
*************** find_cf_chip (int architecture)
*** 722,728 ****
  cp += strlen (cp);
       }
   }
! strncpy (cp, archs[i].name, (sizeof (buf) - (cp - buf)));
  cp += strlen (cp);
  j++;
        }
--- 809,815 ----
  cp += strlen (cp);
       }
   }
! strncpy (cp, m68k_cpus[i].name, (sizeof (buf) - (cp - buf)));
  cp += strlen (cp);
  j++;
        }
*************** m68k_ip (char *instring)
*** 2004,2013 ****
   {
     int got_one = 0, idx;
 
!    for (idx = 0; idx < n_archs; idx++)
       {
! if ((archs[idx].arch & ok_arch)
!    && ! archs[idx].alias)
   {
     if (got_one)
       {
--- 2091,2100 ----
   {
     int got_one = 0, idx;
 
!    for (idx = 0; m68k_cpus[idx].name; idx++)
       {
! if ((m68k_cpus[idx].arch & ok_arch)
!    && ! m68k_cpus[idx].alias)
   {
     if (got_one)
       {
*************** m68k_ip (char *instring)
*** 2015,2021 ****
  cp += strlen (cp);
       }
     got_one = 1;
!    strcpy (cp, archs[idx].name);
     cp += strlen (cp);
   }
       }
--- 2102,2108 ----
  cp += strlen (cp);
       }
     got_one = 1;
!    strcpy (cp, m68k_cpus[idx].name);
     cp += strlen (cp);
   }
       }
*************** init_regtable (void)
*** 3825,3832 ****
      insert_reg (init_table[i].name, init_table[i].number);
  }
 
- static int no_68851, no_68881;
-
  void
  md_assemble (char *str)
  {
--- 3912,3917 ----
*************** md_assemble (char *str)
*** 3838,3843 ****
--- 3923,3939 ----
    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.  */
*************** select_control_regs (void)
*** 4283,4384 ****
        control_regs = m68020_control_regs;
        break;
       
!     case m68000:
        control_regs = m68000_control_regs;
        break;
!     case m68010:
        control_regs = m68010_control_regs;
        break;
!     case m68020:
!     case m68030:
        control_regs = m68020_control_regs;
        break;
!     case m68040:
        control_regs = m68040_control_regs;
        break;
!     case m68060:
        control_regs = m68060_control_regs;
        break;
!     case cpu32:
        control_regs = cpu32_control_regs;
        break;
!     case mcf5200:
!     case mcf5206e:
!     case mcf5307:
!     case mcf5407:
        control_regs = mcf_control_regs;
        break;
!     case mcf5249:
        control_regs = mcf5249_control_regs;
        break;
!     case mcf528x:
!     case mcf521x:
        control_regs = mcf528x_control_regs;
        break;
!     case mcf5470:
!     case mcf5480:
        control_regs = mcfv4e_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;
- }
 
  /* This is called when a label is defined.  */
 
--- 4379,4434 ----
        control_regs = m68020_control_regs;
        break;
       
!     case cpu_m68000:
        control_regs = m68000_control_regs;
        break;
!     case cpu_m68010:
        control_regs = m68010_control_regs;
        break;
!     case cpu_m68020:
!     case cpu_m68030:
        control_regs = m68020_control_regs;
        break;
!     case cpu_m68040:
        control_regs = m68040_control_regs;
        break;
!     case cpu_m68060:
        control_regs = m68060_control_regs;
        break;
!     case cpu_cpu32:
        control_regs = cpu32_control_regs;
        break;
!     case cpu_cf5200:
!     case cpu_cf5206e:
!     case cpu_cf5307:
!     case cpu_cf5407:
        control_regs = mcf_control_regs;
        break;
!     case cpu_cf5249:
        control_regs = mcf5249_control_regs;
        break;
!     case cpu_cf528x:
!     case cpu_cf521x:
        control_regs = mcf528x_control_regs;
        break;
!     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 ();
      }
  }
 
 
  /* This is called when a label is defined.  */
 
*************** mri_chip (void)
*** 5291,5300 ****
    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)
        break;
!   if (i >= n_archs)
      {
        as_bad (_("%s: unrecognized processor name"), s);
        *input_line_pointer = c;
--- 5341,5350 ----
    while (is_part_of_name (c = *input_line_pointer++))
      ;
    *--input_line_pointer = 0;
!   for (i = 0; m68k_cpus[i].name; i++)
!     if (strcasecmp (s, m68k_cpus[i].name) == 0)
        break;
!   if (!m68k_cpus[i].name)
      {
        as_bad (_("%s: unrecognized processor name"), s);
        *input_line_pointer = c;
*************** mri_chip (void)
*** 5307,5314 ****
      current_architecture = 0;
    else
      current_architecture &= m68881 | m68851;
!   current_architecture |= archs[i].arch;
!   current_chip = archs[i].chip;
 
    while (*input_line_pointer == '/')
      {
--- 5357,5364 ----
      current_architecture = 0;
    else
      current_architecture &= m68881 | m68851;
!   current_architecture |= m68k_cpus[i].arch & ~(m68881 | m68851);
!   current_chip = m68k_cpus[i].chip;
 
    while (*input_line_pointer == '/')
      {
*************** s_mri_endw (int ignore ATTRIBUTE_UNUSED)
*** 6908,6935 ****
    demand_empty_rest_of_line ();
  }
 
  /* 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";
--- 6958,7161 ----
    demand_empty_rest_of_line ();
  }
 
+ /* 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;
+ }
+
+ /* 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.
!  */
 
  #ifdef OBJ_ELF
  const char *md_shortopts = "lSA:m:kQ:V";
*************** md_parse_option (int c, char *arg)
*** 6979,7058 ****
        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;
--- 7205,7210 ----
*************** md_parse_option (int c, char *arg)
*** 7106,7111 ****
--- 7258,7282 ----
        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;
      }
*************** md_parse_option (int c, char *arg)
*** 7113,7118 ****
--- 7284,7347 ----
    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)
  {
*************** md_show_usage (FILE *stream)
*** 7123,7139 ****
    /* Get the canonical name for the default target CPU.  */
    if (*default_cpu == 'm')
      default_cpu++;
!   for (i = 0; i < n_archs; i++)
      {
!       if (strcasecmp (default_cpu, archs[i].name) == 0)
  {
!  default_arch = archs[i].arch;
!  for (i = 0; i < n_archs; i++)
     {
!      if (archs[i].arch == default_arch
!  && !archs[i].alias)
  {
!  default_cpu = archs[i].name;
   break;
  }
     }
--- 7352,7368 ----
    /* Get the canonical name for the default target CPU.  */
    if (*default_cpu == 'm')
      default_cpu++;
!   for (i = 0; m68k_cpus[i].name; i++)
      {
!       if (strcasecmp (default_cpu, m68k_cpus[i].name) == 0)
  {
!  default_arch = m68k_cpus[i].arch;
!  for (i = 0; m68k_cpus[i].name; i++)
     {
!      if (m68k_cpus[i].arch == default_arch
!  && !m68k_cpus[i].alias)
  {
!  default_cpu = m68k_cpus[i].name;
   break;
  }
     }
*************** md_show_usage (FILE *stream)
*** 7141,7172 ****
      }
 
    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 | -
Reply | Threaded
Open this post in threaded view
|

Re: [m68k] cleanup arch/cpu selection

Andreas Schwab
Nathan Sidwell <[hidden email]> writes:

> *** include/elf/m68k.h 10 May 2005 10:21:10 -0000 1.10
> --- include/elf/m68k.h 27 Jan 2006 12:07:51 -0000
> *************** END_RELOC_NUMBERS (R_68K_max)
> *** 56,59 ****
> --- 56,73 ----
>   #define EF_M68000   0x01000000
>   #define EF_CFV4E    0x00008000
>  
> + /* We use the bottom 8 bits to encode information about the
> +    coldfire variant.  */
> + #define EF_ISA_MASK     0x07  /* Which ISA */
> + #define EF_ISA_A 0x01
> + #define EF_ISA_A_PLUS   0x02
> + #define EF_ISA_B 0x03
> + #define EF_HW_DIV 0x08  /* Has HW divide */
> + #define EF_MAC_MASK 0x30
> + #define EF_MAC 0x10  /* Has MAC */
> + #define EF_EMAC 0x20  /* Has EMAC */
> + #define EF_USP 0x40  /* Has USP insns */
> + #define EF_FLOAT 0x80  /* Has float insns */
> + #define EF_CF_MASK 0xFF
> +      
>   #endif

IMHO these should be named EF_68K_ISA_MASK, etc., since they are m68k
specific.

Andreas.

--
Andreas Schwab, SuSE Labs, [hidden email]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: [m68k] cleanup arch/cpu selection

Nathan Sidwell
Andreas Schwab wrote:

>
> IMHO these should be named EF_68K_ISA_MASK, etc., since they are m68k
> specific.

I'm fine with that (I looked at some other elf header files and they didn't
always put a prefix in).  Should the EF_M68000, EF_CFV4E & EF_CPU32 be similarly
renamed?

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
[hidden email]    ::     http://www.planetfall.pwp.blueyonder.co.uk

Reply | Threaded
Open this post in threaded view
|

Re: [m68k] cleanup arch/cpu selection

Andreas Schwab
Nathan Sidwell <[hidden email]> writes:

> Andreas Schwab wrote:
>
>> IMHO these should be named EF_68K_ISA_MASK, etc., since they are m68k
>> specific.
>
> I'm fine with that (I looked at some other elf header files and they didn't
> always put a prefix in).

There are a few exceptions, but most of them do (and the exceptions should
perhaps be fixed eventually).

> Should the EF_M68000, EF_CFV4E & EF_CPU32 be similarly renamed?

I'd say yes.

Andreas.

--
Andreas Schwab, SuSE Labs, [hidden email]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."