[v2] MIPS: the default output fellows triple and with-arch
Checks
Commit Message
PR 25494.
1. as fellows the isa level in triple of target
and the --with-arch buildtime option:
> as -march=from-abi xx.s
> as xx.s
2. ld fellows the isa level in triple of target
> ld -r -b binary xx.dat -o xx.o
---
bfd/Makefile.in | 1 +
bfd/config.bfd | 48 ++++++++++++-
bfd/configure | 5 ++
bfd/configure.ac | 4 ++
bfd/elfxx-mips.c | 61 +++++++++++++++-
.../binutils-all/mips/mips-note-2-n32.d | 1 +
gas/config/tc-mips.c | 70 +++++++++++++++++--
gas/configure | 20 +++++-
gas/configure.ac | 18 ++++-
gold/configure.tgt | 14 ++++
ld/configure.tgt | 12 +++-
11 files changed, 241 insertions(+), 13 deletions(-)
Comments
YunQiang Su <yunqiang.su@cipunited.com> writes:
> PR 25494.
>
> 1. as fellows the isa level in triple of target
> and the --with-arch buildtime option:
> > as -march=from-abi xx.s
> > as xx.s
> 2. ld fellows the isa level in triple of target
> > ld -r -b binary xx.dat -o xx.o
> ---
> bfd/Makefile.in | 1 +
> bfd/config.bfd | 48 ++++++++++++-
> bfd/configure | 5 ++
> bfd/configure.ac | 4 ++
> bfd/elfxx-mips.c | 61 +++++++++++++++-
> .../binutils-all/mips/mips-note-2-n32.d | 1 +
> gas/config/tc-mips.c | 70 +++++++++++++++++--
> gas/configure | 20 +++++-
> gas/configure.ac | 18 ++++-
> gold/configure.tgt | 14 ++++
> ld/configure.tgt | 12 +++-
> 11 files changed, 241 insertions(+), 13 deletions(-)
>
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index 82aa96f30e5..7b7b262d64e 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -332,6 +332,7 @@ CPPFLAGS = @CPPFLAGS@
> CYGPATH_W = @CYGPATH_W@
> DATADIRNAME = @DATADIRNAME@
> DEBUGDIR = @DEBUGDIR@
> +DEFAULT_ARCH = @DEFAULT_ARCH@
> DEFS = @DEFS@
> DEPDIR = @DEPDIR@
> DSYMUTIL = @DSYMUTIL@
> diff --git a/bfd/config.bfd b/bfd/config.bfd
> index 7af481048db..f5f3b08e50b 100644
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -227,6 +227,40 @@ z8k*) targ_archs=bfd_z8k_arch ;;
> *) targ_archs=bfd_${targ_cpu}_arch ;;
> esac
>
> +case "${targ}" in
> + mipsisa64r6*)
> + DEFAULT_ARCH=mips64r6
> + ;;
> + mipsisa64r5*)
> + DEFAULT_ARCH=mips64r5
> + ;;
> + mipsisa64r3*)
> + DEFAULT_ARCH=mips64r3
> + ;;
> + mipsisa64r2*)
> + DEFAULT_ARCH=mips64r2
> + ;;
> + mipsisa64*)
> + DEFAULT_ARCH=mips64
> + ;;
> + mipsisa32r6*)
> + DEFAULT_ARCH=mips32r6
> + ;;
> + mipsisa32r5*)
> + DEFAULT_ARCH=mips32r5
> + ;;
> + mipsisa32r3*)
> + DEFAULT_ARCH=mips32r3
> + ;;
> + mipsisa32r2*)
> + DEFAULT_ARCH=mips32r2
> + ;;
> + mipsisa32*)
> + DEFAULT_ARCH=mips32
> + ;;
> + *)
> + ;;
> +esac
>
> # WHEN ADDING ENTRIES TO THIS MATRIX:
> # Make sure that the left side always has two dashes. Otherwise you
> @@ -941,11 +975,21 @@ case "${targ}" in
> targ_defvec=mips_elf32_be_vec
> targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
> ;;
> - mips64*el-*-linux*)
> + mips*64*el-*-linux*-gnuabi64)
> + targ_defvec=mips_elf64_trad_le_vec
> + targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec"
> + want64=true
> + ;;
> + mips*64*-*-linux*-gnuabi64)
> + targ_defvec=mips_elf64_trad_be_vec
> + targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
> + want64=true
> + ;;
> + mips*64*el-*-linux*)
> targ_defvec=mips_elf32_ntrad_le_vec
> targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
> ;;
> - mips64*-*-linux*)
> + mips*64*-*-linux*)
> targ_defvec=mips_elf32_ntrad_be_vec
> targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
> ;;
> diff --git a/bfd/configure b/bfd/configure
> index 41d280ef461..3fc9aa6fdc2 100755
> --- a/bfd/configure
> +++ b/bfd/configure
> @@ -695,6 +695,7 @@ WARN_CFLAGS
> REPORT_BUGS_TEXI
> REPORT_BUGS_TO
> PKGVERSION
> +DEFAULT_ARCH
> DEBUGDIR
> ENABLE_BFD_64_BIT_FALSE
> ENABLE_BFD_64_BIT_TRUE
> @@ -13775,6 +13776,10 @@ do
> fi
> done
>
> +if test -n "$DEFAULT_ARCH"; then
> + TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
> +fi
> +
>
> # This processing still needs to be done if we're to decide properly whether
> # 64-bit support needs to be compiled in. Currently, it will be included if
> diff --git a/bfd/configure.ac b/bfd/configure.ac
> index f044616f4d9..b432d7cf10f 100644
> --- a/bfd/configure.ac
> +++ b/bfd/configure.ac
> @@ -341,6 +341,10 @@ do
> TDEFINES="$TDEFINES $targ_cflags"
> fi
> done
> +
> +if test -n "$DEFAULT_ARCH"; then
> + TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
> +fi
> AC_SUBST(TDEFINES)
>
> # This processing still needs to be done if we're to decide properly whether
> diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> index d34a755807b..61f00981bfc 100644
> --- a/bfd/elfxx-mips.c
> +++ b/bfd/elfxx-mips.c
> @@ -47,6 +47,15 @@
>
> #include "hashtab.h"
>
> +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> +struct mips_eflags_32_64
> +{
> + const char *name;
> + flagword e_mips_arch;
> + flagword e_mips_arch32;
> + flagword e_mips_arch64;
> +};
> +
> /* Types of TLS GOT entry. */
> enum mips_got_tls_type {
> GOT_TLS_NONE,
> @@ -1306,6 +1315,28 @@ bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
> #define TP_OFFSET 0x7000
> #define DTP_OFFSET 0x8000
>
> +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> +__attribute__ ((unused))
> +static const struct mips_eflags_32_64 mips_eflags_32_64_table[] =
> +{
> + { "mips1", E_MIPS_ARCH_1, E_MIPS_ARCH_1, E_MIPS_ARCH_3},
> + { "mips2", E_MIPS_ARCH_2, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
> + { "mips3", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
> + { "mips4", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_4},
> + { "mips5", E_MIPS_ARCH_5, E_MIPS_ARCH_2, E_MIPS_ARCH_5},
> + { "mips32", E_MIPS_ARCH_32, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
> + { "mips32r2", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips32r3", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips32r5", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips32r6", E_MIPS_ARCH_32R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
> + { "mips64", E_MIPS_ARCH_64, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
> + { "mips64r2", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips64r3", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips64r5", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> + { "mips64r6", E_MIPS_ARCH_64R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
> + { NULL, 0, 0, 0 }
> +};
> +
> static bfd_vma
> dtprel_base (struct bfd_link_info *info)
> {
> @@ -12316,6 +12347,30 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
> }
>
>
> +/* Get the E_MIPA_ARCH_?? value for the DEFAULT_ARCH
> + The value of bits can be 32/64 or 0 (guess from DEFAULT_ARCH)
> + */
> +static flagword mips_get_default_arch_eflags(int bits)
> +{
> +#ifdef DEFAULT_ARCH
> + int i;
> +
> + for (i = 0; mips_eflags_32_64_table[i].name; i++)
> + if (strcasecmp (mips_eflags_32_64_table[i].name, DEFAULT_ARCH) != 0)
> + continue;
> + else if (bits == 32)
> + return mips_eflags_32_64_table[i].e_mips_arch32;
> + else if (bits == 64)
> + return mips_eflags_32_64_table[i].e_mips_arch64;
> + else if (bits == 0)
> + return mips_eflags_32_64_table[i].e_mips_arch;
> +#endif
> +
> + if (bits == 64)
> + return E_MIPS_ARCH_3;
> + return E_MIPS_ARCH_1;
> +}
> +
> /* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags. */
>
> static void
One of my points in the previous review was that I don't think we should
change the behaviour for mipsisa32/64r2 and earlier (unless there's
a specific reason that I'm missing). Starting out at the minimum
MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs seems like the
correct behaviour, with the architecture being bumped once code is
linked in.
E.g. I don't see any reason in principle why mipsisa64-elf-ld should
behave differently from mips64-elf-ld for the same set of input objects.
If all the input objects are MIPS III then the output should be too.
Similarly, I think -march=from-abi should select MIPS I/III even
for mipsisa64-elf. That matches the GCC documentation:
The special value @samp{from-abi} selects the
most compatible architecture for the selected ABI (that is,
@samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@.
AIUI, the motivation for the change is that mipsisa32/64r6 is not
compatible with r2 and earlier, and so defaulting to MIPS I or MIPS III
isn't correct. I think that makes r6 architectures a new base architecture
for MIPS 32/64 r6 and above. E.g. if there was an r7 that was backwards-
compatible with r6, r7 should IMO use r6 as the default here, just like
MIPS IV toolchains use MIPS III as the default for 64-bit ABIs.
E.g. maybe we could have a MIPSR6_TOOLCHAIN_P that is true for
toolchains that are for r6+. Then select:
MIPSR6_TOOLCHAIN_P ? E_MIPS_ARCH_64R6 : E_MIPS_ARCH_3
and
MIPSR6_TOOLCHAIN_P ? E_MIPS_ARCH_32R6 : E_MIPS_ARCH_1
I can see the argument for changing -march=from-abi for r6+ too,
but we should try to keep the GCC and GAS handling compatible.
Thanks,
Richard
> @@ -12327,9 +12382,11 @@ mips_set_isa_flags (bfd *abfd)
> {
> default:
> if (ABI_N32_P (abfd) || ABI_64_P (abfd))
> - val = E_MIPS_ARCH_3;
> + val = mips_get_default_arch_eflags(64);
> + else if (ABI_O32_P (abfd))
> + val = mips_get_default_arch_eflags(32);
> else
> - val = E_MIPS_ARCH_1;
> + val = mips_get_default_arch_eflags(0);
> break;
>
> case bfd_mach_mips3000:
> diff --git a/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d b/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> index c2a581858ed..5e24e7a115e 100644
> --- a/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> +++ b/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> @@ -1,4 +1,5 @@
> #PROG: objcopy
> +#as: -n32
> #readelf: --notes --wide
> #objcopy: --merge-notes
> #name: MIPS merge notes section (n32)
> diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
> index e911aaa904a..c906471eb92 100644
> --- a/gas/config/tc-mips.c
> +++ b/gas/config/tc-mips.c
> @@ -1422,6 +1422,15 @@ static int relaxed_micromips_16bit_branch_length (fragS *, asection *, int);
> static int relaxed_micromips_32bit_branch_length (fragS *, asection *, int);
> static void file_mips_check_options (void);
>
> +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> +
> +struct mips_isa_32_64
> +{
> + int isa;
> + int isa_32;
> + int isa_64;
> +};
> +
> /* Table and functions used to map between CPU/ISA names, and
> ISA levels, and CPU numbers. */
>
> @@ -1439,6 +1448,7 @@ struct mips_cpu_info
> static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
> static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
> static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
> +static int mips_cpu_isa_32_64(int isa, int bits);
>
> /* Command-line options. */
> const char *md_shortopts = "O::g::G:";
> @@ -19979,6 +19989,28 @@ s_mips_mask (int reg_type)
> }
> }
>
> +
> +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> +static const struct mips_isa_32_64 mips_isa_32_64_table[] =
> +{
> + { ISA_MIPS1, ISA_MIPS1, ISA_MIPS3 },
> + { ISA_MIPS2, ISA_MIPS2, ISA_MIPS3 },
> + { ISA_MIPS3, ISA_MIPS2, ISA_MIPS3 },
> + { ISA_MIPS4, ISA_MIPS2, ISA_MIPS4 },
> + { ISA_MIPS5, ISA_MIPS2, ISA_MIPS5 },
> + { ISA_MIPS32, ISA_MIPS32, ISA_MIPS64 },
> + { ISA_MIPS32R2, ISA_MIPS32R2, ISA_MIPS64R2 },
> + { ISA_MIPS32R3, ISA_MIPS32R3, ISA_MIPS64R3 },
> + { ISA_MIPS32R5, ISA_MIPS32R5, ISA_MIPS64R5 },
> + { ISA_MIPS32R6, ISA_MIPS32R6, ISA_MIPS64R6 },
> + { ISA_MIPS64, ISA_MIPS32, ISA_MIPS64 },
> + { ISA_MIPS64R2, ISA_MIPS32R2, ISA_MIPS64R2 },
> + { ISA_MIPS64R3, ISA_MIPS32R3, ISA_MIPS64R3 },
> + { ISA_MIPS64R5, ISA_MIPS32R5, ISA_MIPS64R5 },
> + { ISA_MIPS64R6, ISA_MIPS32R6, ISA_MIPS64R6 },
> + { 0, 0, 0 }
> +};
> +
> /* A table describing all the processors gas knows about. Names are
> matched in the order listed.
>
> @@ -20223,6 +20255,9 @@ static const struct mips_cpu_info *
> mips_parse_cpu (const char *option, const char *cpu_string)
> {
> const struct mips_cpu_info *p;
> + const struct mips_cpu_info *default_cpu;
> + int default_isa32 = ISA_MIPS1;
> + int default_isa64 = ISA_MIPS3;
>
> /* 'from-abi' selects the most compatible architecture for the given
> ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
> @@ -20236,19 +20271,26 @@ mips_parse_cpu (const char *option, const char *cpu_string)
> 'mips64', just as we did in the days before 'from-abi'. */
> if (strcasecmp (cpu_string, "from-abi") == 0)
> {
> + for (default_cpu = mips_cpu_info_table; default_cpu->name != 0; default_cpu++)
> + if (mips_matching_cpu_name_p (default_cpu->name, MIPS_CPU_STRING_DEFAULT))
> + {
> + default_isa32 = mips_cpu_isa_32_64 (default_cpu->isa, 32);
> + default_isa64 = mips_cpu_isa_32_64 (default_cpu->isa, 64);
> + break;
> + }
> if (ABI_NEEDS_32BIT_REGS (mips_abi))
> - return mips_cpu_info_from_isa (ISA_MIPS1);
> + return mips_cpu_info_from_isa (default_isa32);
>
> if (ABI_NEEDS_64BIT_REGS (mips_abi))
> - return mips_cpu_info_from_isa (ISA_MIPS3);
> + return mips_cpu_info_from_isa (default_isa64);
>
> if (file_mips_opts.gp >= 0)
> return mips_cpu_info_from_isa (file_mips_opts.gp == 32
> - ? ISA_MIPS1 : ISA_MIPS3);
> + ? default_isa32 : default_isa64);
>
> return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
> - ? ISA_MIPS3
> - : ISA_MIPS1);
> + ? default_isa64
> + : default_isa32);
> }
>
> /* 'default' has traditionally been a no-op. Probably not very useful. */
> @@ -20263,6 +20305,24 @@ mips_parse_cpu (const char *option, const char *cpu_string)
> return 0;
> }
>
> +/* Return the best matching 32bit/64bit ISA of a ISA, according the table
> + mips_isa_32_64_table */
> +static int
> +mips_cpu_isa_32_64(int isa, int bits)
> +{
> + int i;
> +
> + for (i = 0; mips_isa_32_64_table[i].isa != 0; i++)
> + if (isa != mips_isa_32_64_table[i].isa)
> + continue;
> + else if (bits == 32)
> + return mips_isa_32_64_table[i].isa_32;
> + else if (bits == 64)
> + return mips_isa_32_64_table[i].isa_64;
> +
> + return 0;
> +}
> +
> /* Return the canonical processor information for ISA (a member of the
> ISA_MIPS* enumeration). */
>
> diff --git a/gas/configure b/gas/configure
> index b56836998ef..11b0a56bbd4 100755
> --- a/gas/configure
> +++ b/gas/configure
> @@ -12201,6 +12201,21 @@ _ACEOF
> as_fn_error $? "$target_cpu isn't a supported MIPS CPU name" "$LINENO" 5
> ;;
> esac
> + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5
> +$as_echo_n "checking for default configuration of --with-arch... " >&6; }
> + if test "x${with_arch}" != x; then
> + case ${with_arch} in
> + mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
> + mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
> + mips_cpu=${with_arch}
> + ;;
> + *)
> + as_fn_error $? "This kind of arch name does *NOT* exist!" "$LINENO" 5
> + ;;
> + esac
> + fi
> + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_arch" >&5
> +$as_echo "$with_arch" >&6; }
> # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
> # binaries. It's a GNU extension that some OSes don't understand.
> case ${target} in
> @@ -12223,7 +12238,10 @@ _ACEOF
> esac
> # Decide which ABI to target by default.
> case ${target} in
> - mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> + mips*64*-linux-gnuabi64)
> + mips_default_abi=N64_ABI
> + ;;
> + mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> | mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
> mips_default_abi=N32_ABI
> ;;
> diff --git a/gas/configure.ac b/gas/configure.ac
> index 6a68fd7c4e6..a126a3fda5d 100644
> --- a/gas/configure.ac
> +++ b/gas/configure.ac
> @@ -370,6 +370,19 @@ changequote([,])dnl
> AC_MSG_ERROR($target_cpu isn't a supported MIPS CPU name)
> ;;
> esac
> + AC_MSG_CHECKING(for default configuration of --with-arch)
> + if test "x${with_arch}" != x; then
> + case ${with_arch} in
> + mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
> + mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
> + mips_cpu=${with_arch}
> + ;;
> + *)
> + AC_MSG_ERROR(This kind of arch name does *NOT* exist!)
> + ;;
> + esac
> + fi
> + AC_MSG_RESULT($with_arch)
> # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
> # binaries. It's a GNU extension that some OSes don't understand.
> case ${target} in
> @@ -392,7 +405,10 @@ changequote([,])dnl
> esac
> # Decide which ABI to target by default.
> case ${target} in
> - mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> + mips*64*-linux-gnuabi64)
> + mips_default_abi=N64_ABI
> + ;;
> + mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> | mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
> mips_default_abi=N32_ABI
> ;;
> diff --git a/gold/configure.tgt b/gold/configure.tgt
> index 4b54e08d27f..ef47ce079f1 100644
> --- a/gold/configure.tgt
> +++ b/gold/configure.tgt
> @@ -153,6 +153,13 @@ aarch64*-*)
> targ_big_endian=false
> targ_extra_big_endian=true
> ;;
> +mips*64*el*-*-*|mips*64*le*-*-*)
> + targ_obj=mips
> + targ_machine=EM_MIPS_RS3_LE
> + targ_size=64
> + targ_big_endian=false
> + targ_extra_big_endian=true
> + ;;
> mips*el*-*-*|mips*le*-*-*)
> targ_obj=mips
> targ_machine=EM_MIPS_RS3_LE
> @@ -160,6 +167,13 @@ mips*el*-*-*|mips*le*-*-*)
> targ_big_endian=false
> targ_extra_big_endian=true
> ;;
> +mips*64*-*-*)
> + targ_obj=mips
> + targ_machine=EM_MIPS
> + targ_size=64
> + targ_big_endian=true
> + targ_extra_big_endian=false
> + ;;
> mips*-*-*)
> targ_obj=mips
> targ_machine=EM_MIPS
> diff --git a/ld/configure.tgt b/ld/configure.tgt
> index 34c9d67c365..4a71f679e29 100644
> --- a/ld/configure.tgt
> +++ b/ld/configure.tgt
> @@ -580,11 +580,19 @@ mips*-*-vxworks*) targ_emul=elf32ebmipvxworks
> ;;
> mips*-*-windiss) targ_emul=elf32mipswindiss
> ;;
> -mips64*el-*-linux-*) targ_emul=elf32ltsmipn32
> +mips*64*el-*-linux-gnuabi64) targ_emul=elf64ltsmip
> + targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32ltsmip elf32btsmip elf64btsmip"
> + targ_extra_libpath=$targ_extra_emuls
> + ;;
> +mips*64*el-*-linux-*) targ_emul=elf32ltsmipn32
> targ_extra_emuls="elf32btsmipn32 elf32ltsmip elf32btsmip elf64ltsmip elf64btsmip"
> targ_extra_libpath=$targ_extra_emuls
> ;;
> -mips64*-*-linux-*) targ_emul=elf32btsmipn32
> +mips*64*-*-linux-gnuabi64) targ_emul=elf64btsmip
> + targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32btsmip elf32ltsmip elf64ltsmip"
> + targ_extra_libpath=$targ_extra_emuls
> + ;;
> +mips*64*-*-linux-*) targ_emul=elf32btsmipn32
> targ_extra_emuls="elf32ltsmipn32 elf32btsmip elf32ltsmip elf64btsmip elf64ltsmip"
> targ_extra_libpath=$targ_extra_emuls
> ;;
https://sourceware.org/bugzilla/attachment.cgi?id=12247
It sounds like my earliest patch...
Richard Sandiford via Binutils <binutils@sourceware.org> 于2023年4月3日周一 20:40写道:
>
> YunQiang Su <yunqiang.su@cipunited.com> writes:
> > PR 25494.
> >
> > 1. as fellows the isa level in triple of target
> > and the --with-arch buildtime option:
> > > as -march=from-abi xx.s
> > > as xx.s
> > 2. ld fellows the isa level in triple of target
> > > ld -r -b binary xx.dat -o xx.o
> > ---
> > bfd/Makefile.in | 1 +
> > bfd/config.bfd | 48 ++++++++++++-
> > bfd/configure | 5 ++
> > bfd/configure.ac | 4 ++
> > bfd/elfxx-mips.c | 61 +++++++++++++++-
> > .../binutils-all/mips/mips-note-2-n32.d | 1 +
> > gas/config/tc-mips.c | 70 +++++++++++++++++--
> > gas/configure | 20 +++++-
> > gas/configure.ac | 18 ++++-
> > gold/configure.tgt | 14 ++++
> > ld/configure.tgt | 12 +++-
> > 11 files changed, 241 insertions(+), 13 deletions(-)
> >
> > diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> > index 82aa96f30e5..7b7b262d64e 100644
> > --- a/bfd/Makefile.in
> > +++ b/bfd/Makefile.in
> > @@ -332,6 +332,7 @@ CPPFLAGS = @CPPFLAGS@
> > CYGPATH_W = @CYGPATH_W@
> > DATADIRNAME = @DATADIRNAME@
> > DEBUGDIR = @DEBUGDIR@
> > +DEFAULT_ARCH = @DEFAULT_ARCH@
> > DEFS = @DEFS@
> > DEPDIR = @DEPDIR@
> > DSYMUTIL = @DSYMUTIL@
> > diff --git a/bfd/config.bfd b/bfd/config.bfd
> > index 7af481048db..f5f3b08e50b 100644
> > --- a/bfd/config.bfd
> > +++ b/bfd/config.bfd
> > @@ -227,6 +227,40 @@ z8k*) targ_archs=bfd_z8k_arch ;;
> > *) targ_archs=bfd_${targ_cpu}_arch ;;
> > esac
> >
> > +case "${targ}" in
> > + mipsisa64r6*)
> > + DEFAULT_ARCH=mips64r6
> > + ;;
> > + mipsisa64r5*)
> > + DEFAULT_ARCH=mips64r5
> > + ;;
> > + mipsisa64r3*)
> > + DEFAULT_ARCH=mips64r3
> > + ;;
> > + mipsisa64r2*)
> > + DEFAULT_ARCH=mips64r2
> > + ;;
> > + mipsisa64*)
> > + DEFAULT_ARCH=mips64
> > + ;;
> > + mipsisa32r6*)
> > + DEFAULT_ARCH=mips32r6
> > + ;;
> > + mipsisa32r5*)
> > + DEFAULT_ARCH=mips32r5
> > + ;;
> > + mipsisa32r3*)
> > + DEFAULT_ARCH=mips32r3
> > + ;;
> > + mipsisa32r2*)
> > + DEFAULT_ARCH=mips32r2
> > + ;;
> > + mipsisa32*)
> > + DEFAULT_ARCH=mips32
> > + ;;
> > + *)
> > + ;;
> > +esac
> >
> > # WHEN ADDING ENTRIES TO THIS MATRIX:
> > # Make sure that the left side always has two dashes. Otherwise you
> > @@ -941,11 +975,21 @@ case "${targ}" in
> > targ_defvec=mips_elf32_be_vec
> > targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
> > ;;
> > - mips64*el-*-linux*)
> > + mips*64*el-*-linux*-gnuabi64)
> > + targ_defvec=mips_elf64_trad_le_vec
> > + targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec"
> > + want64=true
> > + ;;
> > + mips*64*-*-linux*-gnuabi64)
> > + targ_defvec=mips_elf64_trad_be_vec
> > + targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
> > + want64=true
> > + ;;
> > + mips*64*el-*-linux*)
> > targ_defvec=mips_elf32_ntrad_le_vec
> > targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
> > ;;
> > - mips64*-*-linux*)
> > + mips*64*-*-linux*)
> > targ_defvec=mips_elf32_ntrad_be_vec
> > targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
> > ;;
> > diff --git a/bfd/configure b/bfd/configure
> > index 41d280ef461..3fc9aa6fdc2 100755
> > --- a/bfd/configure
> > +++ b/bfd/configure
> > @@ -695,6 +695,7 @@ WARN_CFLAGS
> > REPORT_BUGS_TEXI
> > REPORT_BUGS_TO
> > PKGVERSION
> > +DEFAULT_ARCH
> > DEBUGDIR
> > ENABLE_BFD_64_BIT_FALSE
> > ENABLE_BFD_64_BIT_TRUE
> > @@ -13775,6 +13776,10 @@ do
> > fi
> > done
> >
> > +if test -n "$DEFAULT_ARCH"; then
> > + TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
> > +fi
> > +
> >
> > # This processing still needs to be done if we're to decide properly whether
> > # 64-bit support needs to be compiled in. Currently, it will be included if
> > diff --git a/bfd/configure.ac b/bfd/configure.ac
> > index f044616f4d9..b432d7cf10f 100644
> > --- a/bfd/configure.ac
> > +++ b/bfd/configure.ac
> > @@ -341,6 +341,10 @@ do
> > TDEFINES="$TDEFINES $targ_cflags"
> > fi
> > done
> > +
> > +if test -n "$DEFAULT_ARCH"; then
> > + TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
> > +fi
> > AC_SUBST(TDEFINES)
> >
> > # This processing still needs to be done if we're to decide properly whether
> > diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> > index d34a755807b..61f00981bfc 100644
> > --- a/bfd/elfxx-mips.c
> > +++ b/bfd/elfxx-mips.c
> > @@ -47,6 +47,15 @@
> >
> > #include "hashtab.h"
> >
> > +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> > +struct mips_eflags_32_64
> > +{
> > + const char *name;
> > + flagword e_mips_arch;
> > + flagword e_mips_arch32;
> > + flagword e_mips_arch64;
> > +};
> > +
> > /* Types of TLS GOT entry. */
> > enum mips_got_tls_type {
> > GOT_TLS_NONE,
> > @@ -1306,6 +1315,28 @@ bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
> > #define TP_OFFSET 0x7000
> > #define DTP_OFFSET 0x8000
> >
> > +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> > +__attribute__ ((unused))
> > +static const struct mips_eflags_32_64 mips_eflags_32_64_table[] =
> > +{
> > + { "mips1", E_MIPS_ARCH_1, E_MIPS_ARCH_1, E_MIPS_ARCH_3},
> > + { "mips2", E_MIPS_ARCH_2, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
> > + { "mips3", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
> > + { "mips4", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_4},
> > + { "mips5", E_MIPS_ARCH_5, E_MIPS_ARCH_2, E_MIPS_ARCH_5},
> > + { "mips32", E_MIPS_ARCH_32, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
> > + { "mips32r2", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips32r3", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips32r5", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips32r6", E_MIPS_ARCH_32R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
> > + { "mips64", E_MIPS_ARCH_64, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
> > + { "mips64r2", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips64r3", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips64r5", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
> > + { "mips64r6", E_MIPS_ARCH_64R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
> > + { NULL, 0, 0, 0 }
> > +};
> > +
> > static bfd_vma
> > dtprel_base (struct bfd_link_info *info)
> > {
> > @@ -12316,6 +12347,30 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
> > }
> >
> >
> > +/* Get the E_MIPA_ARCH_?? value for the DEFAULT_ARCH
> > + The value of bits can be 32/64 or 0 (guess from DEFAULT_ARCH)
> > + */
> > +static flagword mips_get_default_arch_eflags(int bits)
> > +{
> > +#ifdef DEFAULT_ARCH
> > + int i;
> > +
> > + for (i = 0; mips_eflags_32_64_table[i].name; i++)
> > + if (strcasecmp (mips_eflags_32_64_table[i].name, DEFAULT_ARCH) != 0)
> > + continue;
> > + else if (bits == 32)
> > + return mips_eflags_32_64_table[i].e_mips_arch32;
> > + else if (bits == 64)
> > + return mips_eflags_32_64_table[i].e_mips_arch64;
> > + else if (bits == 0)
> > + return mips_eflags_32_64_table[i].e_mips_arch;
> > +#endif
> > +
> > + if (bits == 64)
> > + return E_MIPS_ARCH_3;
> > + return E_MIPS_ARCH_1;
> > +}
> > +
> > /* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags. */
> >
> > static void
>
> One of my points in the previous review was that I don't think we should
> change the behaviour for mipsisa32/64r2 and earlier (unless there's
> a specific reason that I'm missing). Starting out at the minimum
> MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs seems like the
> correct behaviour, with the architecture being bumped once code is
> linked in.
>
> E.g. I don't see any reason in principle why mipsisa64-elf-ld should
> behave differently from mips64-elf-ld for the same set of input objects.
> If all the input objects are MIPS III then the output should be too.
> Similarly, I think -march=from-abi should select MIPS I/III even
> for mipsisa64-elf. That matches the GCC documentation:
>
> The special value @samp{from-abi} selects the
> most compatible architecture for the selected ABI (that is,
> @samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@.
>
> AIUI, the motivation for the change is that mipsisa32/64r6 is not
> compatible with r2 and earlier, and so defaulting to MIPS I or MIPS III
> isn't correct. I think that makes r6 architectures a new base architecture
> for MIPS 32/64 r6 and above. E.g. if there was an r7 that was backwards-
> compatible with r6, r7 should IMO use r6 as the default here, just like
> MIPS IV toolchains use MIPS III as the default for 64-bit ABIs.
>
> E.g. maybe we could have a MIPSR6_TOOLCHAIN_P that is true for
> toolchains that are for r6+. Then select:
>
> MIPSR6_TOOLCHAIN_P ? E_MIPS_ARCH_64R6 : E_MIPS_ARCH_3
>
> and
>
> MIPSR6_TOOLCHAIN_P ? E_MIPS_ARCH_32R6 : E_MIPS_ARCH_1
>
> I can see the argument for changing -march=from-abi for r6+ too,
> but we should try to keep the GCC and GAS handling compatible.
>
> Thanks,
> Richard
>
> > @@ -12327,9 +12382,11 @@ mips_set_isa_flags (bfd *abfd)
> > {
> > default:
> > if (ABI_N32_P (abfd) || ABI_64_P (abfd))
> > - val = E_MIPS_ARCH_3;
> > + val = mips_get_default_arch_eflags(64);
> > + else if (ABI_O32_P (abfd))
> > + val = mips_get_default_arch_eflags(32);
> > else
> > - val = E_MIPS_ARCH_1;
> > + val = mips_get_default_arch_eflags(0);
> > break;
> >
> > case bfd_mach_mips3000:
> > diff --git a/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d b/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> > index c2a581858ed..5e24e7a115e 100644
> > --- a/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> > +++ b/binutils/testsuite/binutils-all/mips/mips-note-2-n32.d
> > @@ -1,4 +1,5 @@
> > #PROG: objcopy
> > +#as: -n32
> > #readelf: --notes --wide
> > #objcopy: --merge-notes
> > #name: MIPS merge notes section (n32)
> > diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
> > index e911aaa904a..c906471eb92 100644
> > --- a/gas/config/tc-mips.c
> > +++ b/gas/config/tc-mips.c
> > @@ -1422,6 +1422,15 @@ static int relaxed_micromips_16bit_branch_length (fragS *, asection *, int);
> > static int relaxed_micromips_32bit_branch_length (fragS *, asection *, int);
> > static void file_mips_check_options (void);
> >
> > +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> > +
> > +struct mips_isa_32_64
> > +{
> > + int isa;
> > + int isa_32;
> > + int isa_64;
> > +};
> > +
> > /* Table and functions used to map between CPU/ISA names, and
> > ISA levels, and CPU numbers. */
> >
> > @@ -1439,6 +1448,7 @@ struct mips_cpu_info
> > static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
> > static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
> > static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
> > +static int mips_cpu_isa_32_64(int isa, int bits);
> >
> > /* Command-line options. */
> > const char *md_shortopts = "O::g::G:";
> > @@ -19979,6 +19989,28 @@ s_mips_mask (int reg_type)
> > }
> > }
> >
> > +
> > +/* A table describing all ISA and its 32bit and 64bit version for best matching */
> > +static const struct mips_isa_32_64 mips_isa_32_64_table[] =
> > +{
> > + { ISA_MIPS1, ISA_MIPS1, ISA_MIPS3 },
> > + { ISA_MIPS2, ISA_MIPS2, ISA_MIPS3 },
> > + { ISA_MIPS3, ISA_MIPS2, ISA_MIPS3 },
> > + { ISA_MIPS4, ISA_MIPS2, ISA_MIPS4 },
> > + { ISA_MIPS5, ISA_MIPS2, ISA_MIPS5 },
> > + { ISA_MIPS32, ISA_MIPS32, ISA_MIPS64 },
> > + { ISA_MIPS32R2, ISA_MIPS32R2, ISA_MIPS64R2 },
> > + { ISA_MIPS32R3, ISA_MIPS32R3, ISA_MIPS64R3 },
> > + { ISA_MIPS32R5, ISA_MIPS32R5, ISA_MIPS64R5 },
> > + { ISA_MIPS32R6, ISA_MIPS32R6, ISA_MIPS64R6 },
> > + { ISA_MIPS64, ISA_MIPS32, ISA_MIPS64 },
> > + { ISA_MIPS64R2, ISA_MIPS32R2, ISA_MIPS64R2 },
> > + { ISA_MIPS64R3, ISA_MIPS32R3, ISA_MIPS64R3 },
> > + { ISA_MIPS64R5, ISA_MIPS32R5, ISA_MIPS64R5 },
> > + { ISA_MIPS64R6, ISA_MIPS32R6, ISA_MIPS64R6 },
> > + { 0, 0, 0 }
> > +};
> > +
> > /* A table describing all the processors gas knows about. Names are
> > matched in the order listed.
> >
> > @@ -20223,6 +20255,9 @@ static const struct mips_cpu_info *
> > mips_parse_cpu (const char *option, const char *cpu_string)
> > {
> > const struct mips_cpu_info *p;
> > + const struct mips_cpu_info *default_cpu;
> > + int default_isa32 = ISA_MIPS1;
> > + int default_isa64 = ISA_MIPS3;
> >
> > /* 'from-abi' selects the most compatible architecture for the given
> > ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
> > @@ -20236,19 +20271,26 @@ mips_parse_cpu (const char *option, const char *cpu_string)
> > 'mips64', just as we did in the days before 'from-abi'. */
> > if (strcasecmp (cpu_string, "from-abi") == 0)
> > {
> > + for (default_cpu = mips_cpu_info_table; default_cpu->name != 0; default_cpu++)
> > + if (mips_matching_cpu_name_p (default_cpu->name, MIPS_CPU_STRING_DEFAULT))
> > + {
> > + default_isa32 = mips_cpu_isa_32_64 (default_cpu->isa, 32);
> > + default_isa64 = mips_cpu_isa_32_64 (default_cpu->isa, 64);
> > + break;
> > + }
> > if (ABI_NEEDS_32BIT_REGS (mips_abi))
> > - return mips_cpu_info_from_isa (ISA_MIPS1);
> > + return mips_cpu_info_from_isa (default_isa32);
> >
> > if (ABI_NEEDS_64BIT_REGS (mips_abi))
> > - return mips_cpu_info_from_isa (ISA_MIPS3);
> > + return mips_cpu_info_from_isa (default_isa64);
> >
> > if (file_mips_opts.gp >= 0)
> > return mips_cpu_info_from_isa (file_mips_opts.gp == 32
> > - ? ISA_MIPS1 : ISA_MIPS3);
> > + ? default_isa32 : default_isa64);
> >
> > return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
> > - ? ISA_MIPS3
> > - : ISA_MIPS1);
> > + ? default_isa64
> > + : default_isa32);
> > }
> >
> > /* 'default' has traditionally been a no-op. Probably not very useful. */
> > @@ -20263,6 +20305,24 @@ mips_parse_cpu (const char *option, const char *cpu_string)
> > return 0;
> > }
> >
> > +/* Return the best matching 32bit/64bit ISA of a ISA, according the table
> > + mips_isa_32_64_table */
> > +static int
> > +mips_cpu_isa_32_64(int isa, int bits)
> > +{
> > + int i;
> > +
> > + for (i = 0; mips_isa_32_64_table[i].isa != 0; i++)
> > + if (isa != mips_isa_32_64_table[i].isa)
> > + continue;
> > + else if (bits == 32)
> > + return mips_isa_32_64_table[i].isa_32;
> > + else if (bits == 64)
> > + return mips_isa_32_64_table[i].isa_64;
> > +
> > + return 0;
> > +}
> > +
> > /* Return the canonical processor information for ISA (a member of the
> > ISA_MIPS* enumeration). */
> >
> > diff --git a/gas/configure b/gas/configure
> > index b56836998ef..11b0a56bbd4 100755
> > --- a/gas/configure
> > +++ b/gas/configure
> > @@ -12201,6 +12201,21 @@ _ACEOF
> > as_fn_error $? "$target_cpu isn't a supported MIPS CPU name" "$LINENO" 5
> > ;;
> > esac
> > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5
> > +$as_echo_n "checking for default configuration of --with-arch... " >&6; }
> > + if test "x${with_arch}" != x; then
> > + case ${with_arch} in
> > + mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
> > + mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
> > + mips_cpu=${with_arch}
> > + ;;
> > + *)
> > + as_fn_error $? "This kind of arch name does *NOT* exist!" "$LINENO" 5
> > + ;;
> > + esac
> > + fi
> > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_arch" >&5
> > +$as_echo "$with_arch" >&6; }
> > # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
> > # binaries. It's a GNU extension that some OSes don't understand.
> > case ${target} in
> > @@ -12223,7 +12238,10 @@ _ACEOF
> > esac
> > # Decide which ABI to target by default.
> > case ${target} in
> > - mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> > + mips*64*-linux-gnuabi64)
> > + mips_default_abi=N64_ABI
> > + ;;
> > + mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> > | mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
> > mips_default_abi=N32_ABI
> > ;;
> > diff --git a/gas/configure.ac b/gas/configure.ac
> > index 6a68fd7c4e6..a126a3fda5d 100644
> > --- a/gas/configure.ac
> > +++ b/gas/configure.ac
> > @@ -370,6 +370,19 @@ changequote([,])dnl
> > AC_MSG_ERROR($target_cpu isn't a supported MIPS CPU name)
> > ;;
> > esac
> > + AC_MSG_CHECKING(for default configuration of --with-arch)
> > + if test "x${with_arch}" != x; then
> > + case ${with_arch} in
> > + mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
> > + mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
> > + mips_cpu=${with_arch}
> > + ;;
> > + *)
> > + AC_MSG_ERROR(This kind of arch name does *NOT* exist!)
> > + ;;
> > + esac
> > + fi
> > + AC_MSG_RESULT($with_arch)
> > # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
> > # binaries. It's a GNU extension that some OSes don't understand.
> > case ${target} in
> > @@ -392,7 +405,10 @@ changequote([,])dnl
> > esac
> > # Decide which ABI to target by default.
> > case ${target} in
> > - mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> > + mips*64*-linux-gnuabi64)
> > + mips_default_abi=N64_ABI
> > + ;;
> > + mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
> > | mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
> > mips_default_abi=N32_ABI
> > ;;
> > diff --git a/gold/configure.tgt b/gold/configure.tgt
> > index 4b54e08d27f..ef47ce079f1 100644
> > --- a/gold/configure.tgt
> > +++ b/gold/configure.tgt
> > @@ -153,6 +153,13 @@ aarch64*-*)
> > targ_big_endian=false
> > targ_extra_big_endian=true
> > ;;
> > +mips*64*el*-*-*|mips*64*le*-*-*)
> > + targ_obj=mips
> > + targ_machine=EM_MIPS_RS3_LE
> > + targ_size=64
> > + targ_big_endian=false
> > + targ_extra_big_endian=true
> > + ;;
> > mips*el*-*-*|mips*le*-*-*)
> > targ_obj=mips
> > targ_machine=EM_MIPS_RS3_LE
> > @@ -160,6 +167,13 @@ mips*el*-*-*|mips*le*-*-*)
> > targ_big_endian=false
> > targ_extra_big_endian=true
> > ;;
> > +mips*64*-*-*)
> > + targ_obj=mips
> > + targ_machine=EM_MIPS
> > + targ_size=64
> > + targ_big_endian=true
> > + targ_extra_big_endian=false
> > + ;;
> > mips*-*-*)
> > targ_obj=mips
> > targ_machine=EM_MIPS
> > diff --git a/ld/configure.tgt b/ld/configure.tgt
> > index 34c9d67c365..4a71f679e29 100644
> > --- a/ld/configure.tgt
> > +++ b/ld/configure.tgt
> > @@ -580,11 +580,19 @@ mips*-*-vxworks*) targ_emul=elf32ebmipvxworks
> > ;;
> > mips*-*-windiss) targ_emul=elf32mipswindiss
> > ;;
> > -mips64*el-*-linux-*) targ_emul=elf32ltsmipn32
> > +mips*64*el-*-linux-gnuabi64) targ_emul=elf64ltsmip
> > + targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32ltsmip elf32btsmip elf64btsmip"
> > + targ_extra_libpath=$targ_extra_emuls
> > + ;;
> > +mips*64*el-*-linux-*) targ_emul=elf32ltsmipn32
> > targ_extra_emuls="elf32btsmipn32 elf32ltsmip elf32btsmip elf64ltsmip elf64btsmip"
> > targ_extra_libpath=$targ_extra_emuls
> > ;;
> > -mips64*-*-linux-*) targ_emul=elf32btsmipn32
> > +mips*64*-*-linux-gnuabi64) targ_emul=elf64btsmip
> > + targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32btsmip elf32ltsmip elf64ltsmip"
> > + targ_extra_libpath=$targ_extra_emuls
> > + ;;
> > +mips*64*-*-linux-*) targ_emul=elf32btsmipn32
> > targ_extra_emuls="elf32ltsmipn32 elf32btsmip elf32ltsmip elf64btsmip elf64ltsmip"
> > targ_extra_libpath=$targ_extra_emuls
> > ;;
@@ -332,6 +332,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
DEBUGDIR = @DEBUGDIR@
+DEFAULT_ARCH = @DEFAULT_ARCH@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
@@ -227,6 +227,40 @@ z8k*) targ_archs=bfd_z8k_arch ;;
*) targ_archs=bfd_${targ_cpu}_arch ;;
esac
+case "${targ}" in
+ mipsisa64r6*)
+ DEFAULT_ARCH=mips64r6
+ ;;
+ mipsisa64r5*)
+ DEFAULT_ARCH=mips64r5
+ ;;
+ mipsisa64r3*)
+ DEFAULT_ARCH=mips64r3
+ ;;
+ mipsisa64r2*)
+ DEFAULT_ARCH=mips64r2
+ ;;
+ mipsisa64*)
+ DEFAULT_ARCH=mips64
+ ;;
+ mipsisa32r6*)
+ DEFAULT_ARCH=mips32r6
+ ;;
+ mipsisa32r5*)
+ DEFAULT_ARCH=mips32r5
+ ;;
+ mipsisa32r3*)
+ DEFAULT_ARCH=mips32r3
+ ;;
+ mipsisa32r2*)
+ DEFAULT_ARCH=mips32r2
+ ;;
+ mipsisa32*)
+ DEFAULT_ARCH=mips32
+ ;;
+ *)
+ ;;
+esac
# WHEN ADDING ENTRIES TO THIS MATRIX:
# Make sure that the left side always has two dashes. Otherwise you
@@ -941,11 +975,21 @@ case "${targ}" in
targ_defvec=mips_elf32_be_vec
targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
;;
- mips64*el-*-linux*)
+ mips*64*el-*-linux*-gnuabi64)
+ targ_defvec=mips_elf64_trad_le_vec
+ targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec"
+ want64=true
+ ;;
+ mips*64*-*-linux*-gnuabi64)
+ targ_defvec=mips_elf64_trad_be_vec
+ targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
+ want64=true
+ ;;
+ mips*64*el-*-linux*)
targ_defvec=mips_elf32_ntrad_le_vec
targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
;;
- mips64*-*-linux*)
+ mips*64*-*-linux*)
targ_defvec=mips_elf32_ntrad_be_vec
targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
;;
@@ -695,6 +695,7 @@ WARN_CFLAGS
REPORT_BUGS_TEXI
REPORT_BUGS_TO
PKGVERSION
+DEFAULT_ARCH
DEBUGDIR
ENABLE_BFD_64_BIT_FALSE
ENABLE_BFD_64_BIT_TRUE
@@ -13775,6 +13776,10 @@ do
fi
done
+if test -n "$DEFAULT_ARCH"; then
+ TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
+fi
+
# This processing still needs to be done if we're to decide properly whether
# 64-bit support needs to be compiled in. Currently, it will be included if
@@ -341,6 +341,10 @@ do
TDEFINES="$TDEFINES $targ_cflags"
fi
done
+
+if test -n "$DEFAULT_ARCH"; then
+ TDEFINES="$TDEFINES -DDEFAULT_ARCH=\\\"${DEFAULT_ARCH}\\\""
+fi
AC_SUBST(TDEFINES)
# This processing still needs to be done if we're to decide properly whether
@@ -47,6 +47,15 @@
#include "hashtab.h"
+/* A table describing all ISA and its 32bit and 64bit version for best matching */
+struct mips_eflags_32_64
+{
+ const char *name;
+ flagword e_mips_arch;
+ flagword e_mips_arch32;
+ flagword e_mips_arch64;
+};
+
/* Types of TLS GOT entry. */
enum mips_got_tls_type {
GOT_TLS_NONE,
@@ -1306,6 +1315,28 @@ bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
#define TP_OFFSET 0x7000
#define DTP_OFFSET 0x8000
+/* A table describing all ISA and its 32bit and 64bit version for best matching */
+__attribute__ ((unused))
+static const struct mips_eflags_32_64 mips_eflags_32_64_table[] =
+{
+ { "mips1", E_MIPS_ARCH_1, E_MIPS_ARCH_1, E_MIPS_ARCH_3},
+ { "mips2", E_MIPS_ARCH_2, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
+ { "mips3", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_3},
+ { "mips4", E_MIPS_ARCH_3, E_MIPS_ARCH_2, E_MIPS_ARCH_4},
+ { "mips5", E_MIPS_ARCH_5, E_MIPS_ARCH_2, E_MIPS_ARCH_5},
+ { "mips32", E_MIPS_ARCH_32, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
+ { "mips32r2", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips32r3", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips32r5", E_MIPS_ARCH_32R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips32r6", E_MIPS_ARCH_32R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
+ { "mips64", E_MIPS_ARCH_64, E_MIPS_ARCH_32, E_MIPS_ARCH_64},
+ { "mips64r2", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips64r3", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips64r5", E_MIPS_ARCH_64R2, E_MIPS_ARCH_32R2, E_MIPS_ARCH_64R2},
+ { "mips64r6", E_MIPS_ARCH_64R6, E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6},
+ { NULL, 0, 0, 0 }
+};
+
static bfd_vma
dtprel_base (struct bfd_link_info *info)
{
@@ -12316,6 +12347,30 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
}
+/* Get the E_MIPA_ARCH_?? value for the DEFAULT_ARCH
+ The value of bits can be 32/64 or 0 (guess from DEFAULT_ARCH)
+ */
+static flagword mips_get_default_arch_eflags(int bits)
+{
+#ifdef DEFAULT_ARCH
+ int i;
+
+ for (i = 0; mips_eflags_32_64_table[i].name; i++)
+ if (strcasecmp (mips_eflags_32_64_table[i].name, DEFAULT_ARCH) != 0)
+ continue;
+ else if (bits == 32)
+ return mips_eflags_32_64_table[i].e_mips_arch32;
+ else if (bits == 64)
+ return mips_eflags_32_64_table[i].e_mips_arch64;
+ else if (bits == 0)
+ return mips_eflags_32_64_table[i].e_mips_arch;
+#endif
+
+ if (bits == 64)
+ return E_MIPS_ARCH_3;
+ return E_MIPS_ARCH_1;
+}
+
/* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags. */
static void
@@ -12327,9 +12382,11 @@ mips_set_isa_flags (bfd *abfd)
{
default:
if (ABI_N32_P (abfd) || ABI_64_P (abfd))
- val = E_MIPS_ARCH_3;
+ val = mips_get_default_arch_eflags(64);
+ else if (ABI_O32_P (abfd))
+ val = mips_get_default_arch_eflags(32);
else
- val = E_MIPS_ARCH_1;
+ val = mips_get_default_arch_eflags(0);
break;
case bfd_mach_mips3000:
@@ -1,4 +1,5 @@
#PROG: objcopy
+#as: -n32
#readelf: --notes --wide
#objcopy: --merge-notes
#name: MIPS merge notes section (n32)
@@ -1422,6 +1422,15 @@ static int relaxed_micromips_16bit_branch_length (fragS *, asection *, int);
static int relaxed_micromips_32bit_branch_length (fragS *, asection *, int);
static void file_mips_check_options (void);
+/* A table describing all ISA and its 32bit and 64bit version for best matching */
+
+struct mips_isa_32_64
+{
+ int isa;
+ int isa_32;
+ int isa_64;
+};
+
/* Table and functions used to map between CPU/ISA names, and
ISA levels, and CPU numbers. */
@@ -1439,6 +1448,7 @@ struct mips_cpu_info
static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
+static int mips_cpu_isa_32_64(int isa, int bits);
/* Command-line options. */
const char *md_shortopts = "O::g::G:";
@@ -19979,6 +19989,28 @@ s_mips_mask (int reg_type)
}
}
+
+/* A table describing all ISA and its 32bit and 64bit version for best matching */
+static const struct mips_isa_32_64 mips_isa_32_64_table[] =
+{
+ { ISA_MIPS1, ISA_MIPS1, ISA_MIPS3 },
+ { ISA_MIPS2, ISA_MIPS2, ISA_MIPS3 },
+ { ISA_MIPS3, ISA_MIPS2, ISA_MIPS3 },
+ { ISA_MIPS4, ISA_MIPS2, ISA_MIPS4 },
+ { ISA_MIPS5, ISA_MIPS2, ISA_MIPS5 },
+ { ISA_MIPS32, ISA_MIPS32, ISA_MIPS64 },
+ { ISA_MIPS32R2, ISA_MIPS32R2, ISA_MIPS64R2 },
+ { ISA_MIPS32R3, ISA_MIPS32R3, ISA_MIPS64R3 },
+ { ISA_MIPS32R5, ISA_MIPS32R5, ISA_MIPS64R5 },
+ { ISA_MIPS32R6, ISA_MIPS32R6, ISA_MIPS64R6 },
+ { ISA_MIPS64, ISA_MIPS32, ISA_MIPS64 },
+ { ISA_MIPS64R2, ISA_MIPS32R2, ISA_MIPS64R2 },
+ { ISA_MIPS64R3, ISA_MIPS32R3, ISA_MIPS64R3 },
+ { ISA_MIPS64R5, ISA_MIPS32R5, ISA_MIPS64R5 },
+ { ISA_MIPS64R6, ISA_MIPS32R6, ISA_MIPS64R6 },
+ { 0, 0, 0 }
+};
+
/* A table describing all the processors gas knows about. Names are
matched in the order listed.
@@ -20223,6 +20255,9 @@ static const struct mips_cpu_info *
mips_parse_cpu (const char *option, const char *cpu_string)
{
const struct mips_cpu_info *p;
+ const struct mips_cpu_info *default_cpu;
+ int default_isa32 = ISA_MIPS1;
+ int default_isa64 = ISA_MIPS3;
/* 'from-abi' selects the most compatible architecture for the given
ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
@@ -20236,19 +20271,26 @@ mips_parse_cpu (const char *option, const char *cpu_string)
'mips64', just as we did in the days before 'from-abi'. */
if (strcasecmp (cpu_string, "from-abi") == 0)
{
+ for (default_cpu = mips_cpu_info_table; default_cpu->name != 0; default_cpu++)
+ if (mips_matching_cpu_name_p (default_cpu->name, MIPS_CPU_STRING_DEFAULT))
+ {
+ default_isa32 = mips_cpu_isa_32_64 (default_cpu->isa, 32);
+ default_isa64 = mips_cpu_isa_32_64 (default_cpu->isa, 64);
+ break;
+ }
if (ABI_NEEDS_32BIT_REGS (mips_abi))
- return mips_cpu_info_from_isa (ISA_MIPS1);
+ return mips_cpu_info_from_isa (default_isa32);
if (ABI_NEEDS_64BIT_REGS (mips_abi))
- return mips_cpu_info_from_isa (ISA_MIPS3);
+ return mips_cpu_info_from_isa (default_isa64);
if (file_mips_opts.gp >= 0)
return mips_cpu_info_from_isa (file_mips_opts.gp == 32
- ? ISA_MIPS1 : ISA_MIPS3);
+ ? default_isa32 : default_isa64);
return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
- ? ISA_MIPS3
- : ISA_MIPS1);
+ ? default_isa64
+ : default_isa32);
}
/* 'default' has traditionally been a no-op. Probably not very useful. */
@@ -20263,6 +20305,24 @@ mips_parse_cpu (const char *option, const char *cpu_string)
return 0;
}
+/* Return the best matching 32bit/64bit ISA of a ISA, according the table
+ mips_isa_32_64_table */
+static int
+mips_cpu_isa_32_64(int isa, int bits)
+{
+ int i;
+
+ for (i = 0; mips_isa_32_64_table[i].isa != 0; i++)
+ if (isa != mips_isa_32_64_table[i].isa)
+ continue;
+ else if (bits == 32)
+ return mips_isa_32_64_table[i].isa_32;
+ else if (bits == 64)
+ return mips_isa_32_64_table[i].isa_64;
+
+ return 0;
+}
+
/* Return the canonical processor information for ISA (a member of the
ISA_MIPS* enumeration). */
@@ -12201,6 +12201,21 @@ _ACEOF
as_fn_error $? "$target_cpu isn't a supported MIPS CPU name" "$LINENO" 5
;;
esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5
+$as_echo_n "checking for default configuration of --with-arch... " >&6; }
+ if test "x${with_arch}" != x; then
+ case ${with_arch} in
+ mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
+ mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
+ mips_cpu=${with_arch}
+ ;;
+ *)
+ as_fn_error $? "This kind of arch name does *NOT* exist!" "$LINENO" 5
+ ;;
+ esac
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_arch" >&5
+$as_echo "$with_arch" >&6; }
# See whether it's appropriate to set E_MIPS_ABI_O32 for o32
# binaries. It's a GNU extension that some OSes don't understand.
case ${target} in
@@ -12223,7 +12238,10 @@ _ACEOF
esac
# Decide which ABI to target by default.
case ${target} in
- mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
+ mips*64*-linux-gnuabi64)
+ mips_default_abi=N64_ABI
+ ;;
+ mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
| mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
mips_default_abi=N32_ABI
;;
@@ -370,6 +370,19 @@ changequote([,])dnl
AC_MSG_ERROR($target_cpu isn't a supported MIPS CPU name)
;;
esac
+ AC_MSG_CHECKING(for default configuration of --with-arch)
+ if test "x${with_arch}" != x; then
+ case ${with_arch} in
+ mips1 | mips2 | mips32 | mips32r2 | mips32r3 | mips32r5 | mips32r6 | \
+ mips3 | mips4 | mips5 | mips64 | mips64r2 | mips64r3 | mips64r5 | mips64r6)
+ mips_cpu=${with_arch}
+ ;;
+ *)
+ AC_MSG_ERROR(This kind of arch name does *NOT* exist!)
+ ;;
+ esac
+ fi
+ AC_MSG_RESULT($with_arch)
# See whether it's appropriate to set E_MIPS_ABI_O32 for o32
# binaries. It's a GNU extension that some OSes don't understand.
case ${target} in
@@ -392,7 +405,10 @@ changequote([,])dnl
esac
# Decide which ABI to target by default.
case ${target} in
- mips64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
+ mips*64*-linux-gnuabi64)
+ mips_default_abi=N64_ABI
+ ;;
+ mips*64*-linux* | mips-sgi-irix6* | mips64*-freebsd* \
| mips64*-kfreebsd*-gnu | mips64*-ps2-elf*)
mips_default_abi=N32_ABI
;;
@@ -153,6 +153,13 @@ aarch64*-*)
targ_big_endian=false
targ_extra_big_endian=true
;;
+mips*64*el*-*-*|mips*64*le*-*-*)
+ targ_obj=mips
+ targ_machine=EM_MIPS_RS3_LE
+ targ_size=64
+ targ_big_endian=false
+ targ_extra_big_endian=true
+ ;;
mips*el*-*-*|mips*le*-*-*)
targ_obj=mips
targ_machine=EM_MIPS_RS3_LE
@@ -160,6 +167,13 @@ mips*el*-*-*|mips*le*-*-*)
targ_big_endian=false
targ_extra_big_endian=true
;;
+mips*64*-*-*)
+ targ_obj=mips
+ targ_machine=EM_MIPS
+ targ_size=64
+ targ_big_endian=true
+ targ_extra_big_endian=false
+ ;;
mips*-*-*)
targ_obj=mips
targ_machine=EM_MIPS
@@ -580,11 +580,19 @@ mips*-*-vxworks*) targ_emul=elf32ebmipvxworks
;;
mips*-*-windiss) targ_emul=elf32mipswindiss
;;
-mips64*el-*-linux-*) targ_emul=elf32ltsmipn32
+mips*64*el-*-linux-gnuabi64) targ_emul=elf64ltsmip
+ targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32ltsmip elf32btsmip elf64btsmip"
+ targ_extra_libpath=$targ_extra_emuls
+ ;;
+mips*64*el-*-linux-*) targ_emul=elf32ltsmipn32
targ_extra_emuls="elf32btsmipn32 elf32ltsmip elf32btsmip elf64ltsmip elf64btsmip"
targ_extra_libpath=$targ_extra_emuls
;;
-mips64*-*-linux-*) targ_emul=elf32btsmipn32
+mips*64*-*-linux-gnuabi64) targ_emul=elf64btsmip
+ targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32btsmip elf32ltsmip elf64ltsmip"
+ targ_extra_libpath=$targ_extra_emuls
+ ;;
+mips*64*-*-linux-*) targ_emul=elf32btsmipn32
targ_extra_emuls="elf32ltsmipn32 elf32btsmip elf32ltsmip elf64btsmip elf64ltsmip"
targ_extra_libpath=$targ_extra_emuls
;;