[PATCH 1/9] RISC-V: Support assembly and disassembly in big endian mode
Marcus Comstedt
marcus@mc.pp.se
Sat Dec 19 13:17:20 GMT 2020
---
bfd/config.bfd | 4 ++--
bfd/configure | 2 ++
bfd/configure.ac | 2 ++
bfd/elfnn-riscv.c | 5 ++++-
bfd/targets.c | 4 ++++
gas/config/tc-riscv.c | 24 +++++++++++++++++++++---
6 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/bfd/config.bfd b/bfd/config.bfd
index fdc6dbe3dd..2ae8b1a4cc 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1160,12 +1160,12 @@ case "${targ}" in
#ifdef BFD64
riscv-*-* | riscv32*-*-*)
targ_defvec=riscv_elf32_vec
- targ_selvecs="riscv_elf32_vec riscv_elf64_vec"
+ targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
want64=true
;;
riscv64*-*-*)
targ_defvec=riscv_elf64_vec
- targ_selvecs="riscv_elf32_vec riscv_elf64_vec"
+ targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
want64=true
;;
#endif
diff --git a/bfd/configure b/bfd/configure
index 5d84aed069..1460bbdfba 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -14919,6 +14919,8 @@ do
pru_elf32_vec) tb="$tb elf32-pru.lo elf32.lo $elf" ;;
riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
+ riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 5ec4d4f0b4..4813e661aa 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -625,6 +625,8 @@ do
pru_elf32_vec) tb="$tb elf32-pru.lo elf32.lo $elf" ;;
riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
+ riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 20944c8109..618fe9319f 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4943,7 +4943,8 @@ static bfd_boolean
riscv_elf_object_p (bfd *abfd)
{
/* There are only two mach types in RISCV currently. */
- if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0)
+ if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0 ||
+ strcmp (abfd->xvec->name, "elf32-bigriscv") == 0)
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32);
else
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64);
@@ -4962,6 +4963,8 @@ riscv_elf_obj_attrs_arg_type (int tag)
#define TARGET_LITTLE_SYM riscv_elfNN_vec
#define TARGET_LITTLE_NAME "elfNN-littleriscv"
+#define TARGET_BIG_SYM riscv_elfNN_be_vec
+#define TARGET_BIG_NAME "elfNN-bigriscv"
#define elf_backend_reloc_type_class riscv_reloc_type_class
diff --git a/bfd/targets.c b/bfd/targets.c
index 8ae5c489fc..8fa8f693fb 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -843,6 +843,8 @@ extern const bfd_target powerpc_xcoff_vec;
extern const bfd_target pru_elf32_vec;
extern const bfd_target riscv_elf32_vec;
extern const bfd_target riscv_elf64_vec;
+extern const bfd_target riscv_elf32_be_vec;
+extern const bfd_target riscv_elf64_be_vec;
extern const bfd_target rl78_elf32_vec;
extern const bfd_target rs6000_xcoff64_vec;
extern const bfd_target rs6000_xcoff64_aix_vec;
@@ -1237,6 +1239,8 @@ static const bfd_target * const _bfd_target_vector[] =
#ifdef BFD64
&riscv_elf32_vec,
&riscv_elf64_vec,
+ &riscv_elf32_be_vec,
+ &riscv_elf64_be_vec,
#endif
&rl78_elf32_vec,
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index ca7e52a169..622eb48448 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -445,7 +445,10 @@ static char *expr_end;
const char *
riscv_target_format (void)
{
- return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
+ if (target_big_endian)
+ return xlen == 64 ? "elf64-bigriscv" : "elf32-bigriscv";
+ else
+ return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
}
/* Return the length of instruction INSN. */
@@ -474,7 +477,7 @@ static void
install_insn (const struct riscv_cl_insn *insn)
{
char *f = insn->frag->fr_literal + insn->where;
- md_number_to_chars (f, insn->insn_opcode, insn_length (insn));
+ number_to_chars_littleendian (f, insn->insn_opcode, insn_length (insn));
}
/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
@@ -2662,7 +2665,10 @@ md_atof (int type, char *litP, int *sizeP)
void
md_number_to_chars (char *buf, valueT val, int n)
{
- number_to_chars_littleendian (buf, val, n);
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
}
const char *md_shortopts = "O::g::G:";
@@ -2681,6 +2687,8 @@ enum options
OPTION_NO_CSR_CHECK,
OPTION_MISA_SPEC,
OPTION_MPRIV_SPEC,
+ OPTION_BIG_ENDIAN,
+ OPTION_LITTLE_ENDIAN,
OPTION_END_OF_ENUM
};
@@ -2699,6 +2707,8 @@ struct option md_longopts[] =
{"mno-csr-check", no_argument, NULL, OPTION_NO_CSR_CHECK},
{"misa-spec", required_argument, NULL, OPTION_MISA_SPEC},
{"mpriv-spec", required_argument, NULL, OPTION_MPRIV_SPEC},
+ {"mbig-endian", no_argument, NULL, OPTION_BIG_ENDIAN},
+ {"mlittle-endian", no_argument, NULL, OPTION_LITTLE_ENDIAN},
{NULL, no_argument, NULL, 0}
};
@@ -2777,6 +2787,14 @@ md_parse_option (int c, const char *arg)
case OPTION_MPRIV_SPEC:
return riscv_set_default_priv_spec (arg);
+ case OPTION_BIG_ENDIAN:
+ target_big_endian = 1;
+ break;
+
+ case OPTION_LITTLE_ENDIAN:
+ target_big_endian = 0;
+ break;
+
default:
return 0;
}
--
2.26.2
More information about the Binutils
mailing list