Re: [m68k] cleanup arch/cpu selection

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

Re: [m68k] cleanup arch/cpu selection

Ben Elliston-39
> 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.

This seems like a sensible proposal to me, however please ensure that
for the time being, the old-style command line options continue to be
supported.  If you like, you could emit a warning and advise the user
of the new options.  I really dislike seeing users left to work out
why their Makefiles have stopped working when they upgrade binutils.

Cheers, Ben

attachment0 (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [m68k] cleanup arch/cpu selection

Nathan Sidwell
Ben Elliston wrote:

>>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.
>
>
> This seems like a sensible proposal to me, however please ensure that
> for the time being, the old-style command line options continue to be
> supported.  If you like, you could emit a warning and advise the user
> of the new options.  I really dislike seeing users left to work out
> why their Makefiles have stopped working when they upgrade binutils.

This is the patch I've committed.  It addresses Andreas's concern about the EF_
flags. In doing so I discovered I'd missed a piece of readelf, which needed
adjusting.

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

Nathan Sidwell
Nathan Sidwell wrote:

>
> This is the patch I've committed.  It addresses Andreas's concern about
> the EF_ flags. In doing so I discovered I'd missed a piece of readelf,
> which needed adjusting.

*this* is the patch

--
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_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.
       
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 7 Feb 2006 18:55:36 -0000
***************
*** 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
     Free Software Foundation, Inc.
     Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
--- 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, 2006
     Free Software Foundation, Inc.
     Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
*************** 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 7 Feb 2006 18:55:37 -0000
***************
*** 1,7 ****
  /* 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.
 
--- 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, 2006
!    Free Software Foundation, Inc.
 
     Contributed by Cygnus Support.
 
*************** extern struct bfd_section *_bfd_elf_tls_
*** 706,711 ****
--- 707,716 ----
  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 7 Feb 2006 18:55:47 -0000
*************** extern struct bfd_section *_bfd_elf_tls_
*** 714,719 ****
--- 714,723 ----
  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.
--- 1674,1695 ----
  #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 7 Feb 2006 18:55:47 -0000
***************
*** 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.
     Hacked by Steve Chamberlain of Cygnus Support.
 
     This file is part of BFD, the Binary File Descriptor library.
--- 1,6 ----
  /* BFD library support routines for architectures.
     Copyright 1990, 1991, 1992, 1993, 1994, 1997, 1998, 2000, 2001, 2002,
!    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,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 7 Feb 2006 18:55:50 -0000
***************
*** 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.
 
     This file is part of BFD, the Binary File Descriptor library.
 
--- 1,6 ----
  /* Motorola 68k series support for 32-bit ELF
     Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
!    2004, 2005, 2006 Free Software Foundation, Inc.
 
     This file is part of BFD, the Binary File Descriptor library.
 
***************
*** 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));
*************** static const bfd_byte elf_m68k_plt_entry
*** 220,226 ****
 
  #define CFV4E_PLT_ENTRY_SIZE 24
 
! #define CFV4E_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CFV4E)
 
  static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] =
  {
--- 221,227 ----
 
  #define CFV4E_PLT_ENTRY_SIZE 24
 
! #define CFV4E_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_M68K_CFV4E)
 
  static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] =
  {
*************** static const bfd_byte elf_cfv4e_plt_entr
*** 248,254 ****
    0, 0, 0, 0              /* Replaced with offset to start of .plt.  */
  };
 
! #define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CPU32)
 
  #define PLT_CPU32_ENTRY_SIZE 24
  /* Procedure linkage table entries for the cpu32 */
--- 249,255 ----
    0, 0, 0, 0              /* Replaced with offset to start of .plt.  */
  };
 
! #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 */
*************** 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_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)
*************** 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,528 ----
  {
    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_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;
  }
*************** elf32_m68k_print_private_bfd_data (abfd,
*** 416,421 ****
--- 534,540 ----
       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;
--- 546,600 ----
    /* xgettext:c-format */
    fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
 
!   if (eflags & EF_M68K_CPU32)
!     fprintf (file, " [cpu32]");
!
!   if (eflags & EF_M68K_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;
*************** elf_m68k_plt_sym_val (bfd_vma i, const a
*** 2313,2318 ****
--- 2475,2481 ----
                                          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 7 Feb 2006 18:55:54 -0000
***************
*** 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
     Free Software Foundation, Inc.
 
     Written by Steve Chamberlain of Cygnus Support.
--- 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, 2006
     Free Software Foundation, Inc.
 
     Written by Steve Chamberlain of Cygnus Support.
*************** 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 7 Feb 2006 18:55:56 -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: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.333
diff -c -3 -p -r1.333 readelf.c
*** binutils/readelf.c 2 Feb 2006 22:53:46 -0000 1.333
--- binutils/readelf.c 7 Feb 2006 18:56:07 -0000
*************** get_machine_flags (unsigned e_flags, uns
*** 1940,1949 ****
   break;
 
  case EM_68K:
!  if (e_flags & EF_CPU32)
     strcat (buf, ", cpu32");
!  if (e_flags & EF_M68000)
     strcat (buf, ", m68000");
   break;
 
  case EM_PPC:
--- 1940,1992 ----
   break;
 
  case EM_68K:
!  if (e_flags & EF_M68K_CPU32)
     strcat (buf, ", cpu32");
!  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: 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 7 Feb 2006 18:56:16 -0000
***************
*** 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.
 
     This file is part of GAS, the GNU Assembler.
 
--- 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, 2006 Free Software Foundation, Inc.
 
     This file is part of GAS, the GNU Assembler.
 
*************** 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
Reply | Threaded
Open this post in threaded view
|

Re: [m68k] cleanup arch/cpu selection

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

> * gas/testsuite/gas/m68k/arch-cpu-1.[sd]: New.

These files are missing.

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:
> Nathan Sidwell <[hidden email]> writes:
>
>
>> * gas/testsuite/gas/m68k/arch-cpu-1.[sd]: New.
>
>
> These files are missing.
oops.  Fixed.

nathan

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