Skip to content

Commit

Permalink
RISC-V: Support disassembling RV32E
Browse files Browse the repository at this point in the history
This commit adds support for RV32E disassembling which turns x16-x31
into invalid16-invalid31 while disassembling.

It also changes the style so that style-aware disassembler can distinguish
regular GPRs and invalid RVE registers.

gas/ChangeLog:

	* testsuite/gas/riscv/e-ext-dis.s: New RV32E disassembler test.
	* testsuite/gas/riscv/e-ext-dis-rv32e.d: Likewise.
	* testsuite/gas/riscv/e-ext-dis-rv32i.d: Likewise.

include/ChangeLog:

	* opcode/riscv.h: Add RVE register name definitions.

opcodes/ChangeLog:

	* riscv-dis.c (init_riscv_dis_state_for_arch_and_options): Apply
	RVE register names when the E extension is enabled.
	(print_gpr): New function to print a GPR.
	(print_insn_args): Use print_gpr to print a GPR.
	* riscv-opc.c (riscv_gpr_names_rve_numeric): New.
	(riscv_gpr_names_rve_abi): New.
  • Loading branch information
a4lg committed Aug 7, 2023
1 parent 899020c commit 8063f2e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 22 deletions.
11 changes: 11 additions & 0 deletions gas/testsuite/gas/riscv/e-ext-dis-rv32e.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#as: -march=rv32e
#source: e-ext-dis.s
#objdump: -d -M numeric

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00f78793[ ]+add[ ]+x15,x15,15
[ ]+[0-9a-f]+:[ ]+01ff8f93[ ]+add[ ]+invalid31,invalid31,31
11 changes: 11 additions & 0 deletions gas/testsuite/gas/riscv/e-ext-dis-rv32i.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#as: -march=rv32i
#source: e-ext-dis.s
#objdump: -d -M numeric

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00f78793[ ]+add[ ]+x15,x15,15
[ ]+[0-9a-f]+:[ ]+01ff8f93[ ]+add[ ]+x31,x31,31
4 changes: 4 additions & 0 deletions gas/testsuite/gas/riscv/e-ext-dis.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target:
addi x15, x15, 15
# addi x31, x31, 31 (invalid on RV32E)
.insn 0x01ff8f93
2 changes: 2 additions & 0 deletions include/opcode/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,8 @@ enum riscv_seg_mstate

extern const char * const riscv_gpr_names_numeric[NGPR];
extern const char * const riscv_gpr_names_abi[NGPR];
extern const char * const riscv_gpr_names_rve_numeric[NGPR];
extern const char * const riscv_gpr_names_rve_abi[NGPR];
extern const char * const riscv_fpr_names_numeric[NFPR];
extern const char * const riscv_fpr_names_abi[NFPR];
extern const char * const riscv_rm[8];
Expand Down
47 changes: 29 additions & 18 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,12 @@ init_riscv_dis_state_for_arch_and_options (void)
if (is_arch_changed)
update_riscv_dis_xlen (NULL);
/* Set GPR register names to disassemble. */
riscv_gpr_names = is_numeric ? riscv_gpr_names_numeric : riscv_gpr_names_abi;
riscv_gpr_names
= !riscv_subset_supports (&riscv_rps_dis, "e")
? (is_numeric ? riscv_gpr_names_numeric
: riscv_gpr_names_abi)
: (is_numeric ? riscv_gpr_names_rve_numeric
: riscv_gpr_names_rve_abi);
/* Set FPR register names to disassemble. */
riscv_fpr_names
= !riscv_subset_supports (&riscv_rps_dis, "zfinx")
Expand Down Expand Up @@ -408,6 +413,19 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr;
}

/* Print a GPR (print invalid16-31 on RV32E-invalid registers). */

static void
print_gpr (struct disassemble_info *info, int val)
{
const char *str = riscv_gpr_names[val];
if (str)
(*info->fprintf_styled_func) (info->stream, dis_style_register, "%s", str);
else
(*info->fprintf_styled_func) (info->stream, dis_style_text,
"invalid%d", val);
}

/* Print insn arguments for 32/64-bit code. */

static void
Expand All @@ -432,25 +450,20 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
{
case 's': /* RS1 x8-x15. */
case 'w': /* RS1 x8-x15. */
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[EXTRACT_OPERAND (CRS1S, l) + 8]);
print_gpr (info, EXTRACT_OPERAND (CRS1S, l) + 8);
break;
case 't': /* RS2 x8-x15. */
case 'x': /* RS2 x8-x15. */
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
print_gpr (info, EXTRACT_OPERAND (CRS2S, l) + 8);
break;
case 'U': /* RS1, constrained to equal RD. */
print (info->stream, dis_style_register,
"%s", riscv_gpr_names[rd]);
print_gpr (info, rd);
break;
case 'c': /* RS1, constrained to equal sp. */
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[X_SP]);
print_gpr (info, X_SP);
break;
case 'V': /* RS2 */
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]);
print_gpr (info, EXTRACT_OPERAND (CRS2, l));
break;
case 'o':
case 'j':
Expand Down Expand Up @@ -535,8 +548,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
break;
case 'e':
if (!EXTRACT_OPERAND (VWD, l))
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[0]);
print_gpr (info, 0);
else
print (info->stream, dis_style_register, "%s",
riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
Expand Down Expand Up @@ -625,12 +637,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
case 's':
if ((l & MASK_JALR) == MATCH_JALR)
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
print_gpr (info, rs1);
break;

case 't':
print (info->stream, dis_style_register, "%s",
riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
print_gpr (info, EXTRACT_OPERAND (RS2, l));
break;

case 'u':
Expand Down Expand Up @@ -690,7 +701,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l);
else if ((l & MASK_C_LUI) == MATCH_C_LUI)
pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l);
print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]);
print_gpr (info, rd);
break;

case 'y':
Expand All @@ -699,7 +710,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
break;

case 'z':
print (info->stream, dis_style_register, "%s", riscv_gpr_names[0]);
print_gpr (info, 0);
break;

case '>':
Expand Down
19 changes: 15 additions & 4 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,31 @@

const char * const riscv_gpr_names_numeric[NGPR] =
{
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
#define RISCV_GPR_NAMES_NUMERIC_LOWER \
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", \
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15"
RISCV_GPR_NAMES_NUMERIC_LOWER,
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
"x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"
};

const char * const riscv_gpr_names_abi[NGPR] =
{
"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
"s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
#define RISCV_GPR_NAMES_ABI_LOWER \
"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", \
"s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5"
RISCV_GPR_NAMES_ABI_LOWER,
"a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
"s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
};

const char *const riscv_gpr_names_rve_numeric[NGPR] = {
RISCV_GPR_NAMES_NUMERIC_LOWER
};
const char *const riscv_gpr_names_rve_abi[NGPR] = {
RISCV_GPR_NAMES_ABI_LOWER
};

const char * const riscv_fpr_names_numeric[NFPR] =
{
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
Expand Down

0 comments on commit 8063f2e

Please sign in to comment.