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