new file mode 100644
@@ -0,0 +1,13 @@
+#as: -march=rv64imfd_zbb
+#source: dis-arch-override.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd\.s[ ]+ft0,fa1,fa2
+[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+fadd\.d[ ]+ft0,fa1,fa2
+[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+a0,misa
+[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+zext\.h[ ]+a0,a1
new file mode 100644
@@ -0,0 +1,13 @@
+#as: -march=rv64imfd_zbb
+#source: dis-arch-override.s
+#objdump: -d -M arch=rv32im_zfinx_zbkb
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd\.s[ ]+zero,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+\.4byte[ ]+0x2c5f053
+[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+a0,misa
+[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+packw[ ]+a0,a1,zero
new file mode 100644
@@ -0,0 +1,13 @@
+#as: -march=rv64imfd_zbb
+#source: dis-arch-override.s
+#objdump: -d -m riscv -M arch=rv32im_zfinx_zbkb,numeric
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd\.s[ ]+x0,x11,x12
+[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+\.4byte[ ]+0x2c5f053
+[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+x10,misa
+[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+\.4byte[ ]+0x805c53b
new file mode 100644
@@ -0,0 +1,45 @@
+# Assembler configuration:
+# -march=rv64imfd_zbb
+# Disassembler configurations:
+# Test 1: -d
+# Test 2: -d -M arch=rv32im_zfinx_zbkb
+# Test 3: -d -m riscv -M arch=rv32im_zfinx_zbkb,numeric
+
+target:
+ # Assembler : fadd.s (F)
+ # Disassembler (test 2/3) : fadd.s (Zfinx)
+ # Test that all three operands point to GPRs.
+ fadd.s ft0, fa1, fa2
+
+ # Assembler : fadd.d (D)
+ # Disassembler (test 2/3) : (invalid)
+ # On disassembler option on test 2, Zdinx is not present. So,
+ # it should be disassembled as an invalid instruction.
+ fadd.d ft0, fa1, fa2
+
+ # Assembler : csrr (Zicsr)
+ # Disassembler (test 2/3) : csrr (Zicsr)
+ # When assembling, Zicsr is implied by F. When disassembling,
+ # Zicsr is implied by Zfinx. On both cases, csrr should be
+ # disassembled as csrr.
+ csrr a0, misa
+
+ # Assembler : zext.h (Zbb)
+ # Disassembler (test 2) : packw (Zbkb)
+ # Disassembler (test 3) : (invalid)
+ # Since zext.h specialized instruction does not exist in Zbkb
+ # and we disassemble the output with Zbkb, this instruction
+ # should be disassembled as a packw instruction (on RV64).
+ #
+ # We specify arch=rv32im_zfinx_zbkb on disassembling on test
+ # 2 and 3. But, XLEN part of the ISA string is effective
+ # only if XLEN-neutral machine is specified by `-m riscv' option
+ # (because we are disassembling 64-bit RISC-V ELF file, BFD
+ # architecture is set to `riscv:rv64' unless `-m' option
+ # is specified).
+ #
+ # As a result, test 3 (with `-m riscv' option) disassembles with
+ # RV32 but test 2 (without it) does with RV64.
+ # It changes the result of disassembling since packw instruction
+ # is invalid on RV32.
+ zext.h a0, a1
@@ -35,6 +35,9 @@
/* Default architecture string (if not available). */
static const char *const initial_default_arch = "rv64gc";
+/* If set, a custom architecture string is specified. */
+static bool is_custom_arch = false;
+
/* Current XLEN for the disassembler. */
static unsigned xlen = 0;
@@ -183,8 +186,10 @@ update_riscv_dis_xlen (struct disassemble_info *info)
This is only effective if XLEN-specific BFD machine architecture is
chosen. If XLEN-neutral (like riscv), BFD machine architecture is
ignored on XLEN selection.
- 2. Non-default RISC-V architecture string set by either an ELF
- attribute or a mapping symbol with ISA string.
+ 2. Non-default RISC-V architecture string set by either:
+ a. -M arch=... option (GDB: set disassembler-options arch=...),
+ b. A mapping symbol with ISA string or
+ c. An ELF attribute
3. ELF class in dummy ELF header. */
if (xlen_by_mach != 0)
xlen = xlen_by_mach;
@@ -294,6 +299,7 @@ set_default_riscv_dis_options (void)
no_aliases = false;
is_numeric = false;
is_custom_priv_spec = false;
+ is_custom_arch = false;
}
/* Parse RISC-V disassembler option (without arguments). */
@@ -355,6 +361,11 @@ parse_riscv_dis_option (const char *option)
priv_spec = priv_spec_new;
}
}
+ else if (strcmp (option, "arch") == 0)
+ {
+ is_custom_arch = true;
+ update_riscv_dis_arch (&dis_arch_context_override, value);
+ }
else
{
/* xgettext:c-format */
@@ -1024,6 +1035,9 @@ riscv_get_map_state (int n,
*state = newstate;
if (newstate == MAP_INSN && update)
{
+ /* Skip if a custom architecture is specified. */
+ if (is_custom_arch)
+ return true;
if (arch)
{
/* Override the architecture. */
@@ -1308,7 +1322,10 @@ riscv_get_disassembler (bfd *abfd)
}
}
- update_riscv_dis_arch (&dis_arch_context_default, default_arch);
+ if (is_custom_arch)
+ set_riscv_dis_arch_context (&dis_arch_context_default, default_arch);
+ else
+ update_riscv_dis_arch (&dis_arch_context_default, default_arch);
return print_insn_riscv;
}
@@ -1359,6 +1376,7 @@ riscv_symbol_is_valid (asymbol * sym,
typedef enum
{
RISCV_OPTION_ARG_NONE = -1,
+ RISCV_OPTION_ARG_ARCH,
RISCV_OPTION_ARG_PRIV_SPEC,
RISCV_OPTION_ARG_COUNT
@@ -1376,6 +1394,9 @@ static struct
{ "numeric",
N_("Print numeric register names, rather than ABI names."),
RISCV_OPTION_ARG_NONE },
+ { "arch=",
+ N_("Disassemble using specified ISA and extensions."),
+ RISCV_OPTION_ARG_ARCH },
{ "no-aliases",
N_("Disassemble only into canonical instructions."),
RISCV_OPTION_ARG_NONE },
@@ -1403,6 +1424,9 @@ disassembler_options_riscv (void)
args = XNEWVEC (disasm_option_arg_t, num_args + 1);
+ args[RISCV_OPTION_ARG_ARCH].name = "ARCH";
+ args[RISCV_OPTION_ARG_ARCH].values = NULL;
+
args[RISCV_OPTION_ARG_PRIV_SPEC].name = "SPEC";
priv_spec_count = PRIV_SPEC_CLASS_DRAFT - PRIV_SPEC_CLASS_NONE - 1;
args[RISCV_OPTION_ARG_PRIV_SPEC].values