[PATCH v2] MIPS: the default output fellows triple and with-arch
YunQiang Su
yunqiang.su@cipunited.com
Mon Apr 3 11:06:35 GMT 2023
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
@@ -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
;;
--
2.30.2
More information about the Binutils
mailing list