diff --git a/gas/testsuite/gas/riscv/e-ext-dis-rv32e.d b/gas/testsuite/gas/riscv/e-ext-dis-rv32e.d new file mode 100644 index 00000000000..b2f27e798ed --- /dev/null +++ b/gas/testsuite/gas/riscv/e-ext-dis-rv32e.d @@ -0,0 +1,11 @@ +#as: -march=rv32e +#source: e-ext-dis.s +#objdump: -d -M numeric + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+00f78793[ ]+add[ ]+x15,x15,15 +[ ]+[0-9a-f]+:[ ]+01ff8f93[ ]+add[ ]+invalid31,invalid31,31 diff --git a/gas/testsuite/gas/riscv/e-ext-dis-rv32i.d b/gas/testsuite/gas/riscv/e-ext-dis-rv32i.d new file mode 100644 index 00000000000..ed7b26a401a --- /dev/null +++ b/gas/testsuite/gas/riscv/e-ext-dis-rv32i.d @@ -0,0 +1,11 @@ +#as: -march=rv32i +#source: e-ext-dis.s +#objdump: -d -M numeric + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+00f78793[ ]+add[ ]+x15,x15,15 +[ ]+[0-9a-f]+:[ ]+01ff8f93[ ]+add[ ]+x31,x31,31 diff --git a/gas/testsuite/gas/riscv/e-ext-dis.s b/gas/testsuite/gas/riscv/e-ext-dis.s new file mode 100644 index 00000000000..8a9b6b2a4c6 --- /dev/null +++ b/gas/testsuite/gas/riscv/e-ext-dis.s @@ -0,0 +1,4 @@ +target: + addi x15, x15, 15 + # addi x31, x31, 31 (invalid on RV32E) + .insn 0x01ff8f93 diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 808f3657303..22374f5504f 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -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]; diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 09d2cabec72..2ceffa60860 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -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") @@ -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 @@ -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': @@ -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)]); @@ -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': @@ -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': @@ -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 '>': diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 3efab9a407d..ac2cb0ea038 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -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",