Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RISC-V: Workaround for CSR implications to the Privileged Architecture #49

Merged
merged 9 commits into from
Oct 14, 2022
5 changes: 5 additions & 0 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"g", "zicsr", check_implicit_always},
{"g", "zifencei", check_implicit_always},
{"m", "zmmul", check_implicit_always},
{"h", "zicsr", check_implicit_always},
{"q", "d", check_implicit_always},
{"v", "d", check_implicit_always},
{"v", "zve64d", check_implicit_always},
Expand Down Expand Up @@ -1096,6 +1097,10 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zks", "zbkx", check_implicit_always},
{"zks", "zksed", check_implicit_always},
{"zks", "zksh", check_implicit_always},
{"smepmp", "zicsr", check_implicit_always},
{"smstateen", "zicsr", check_implicit_always},
{"sscofpmf", "zicsr", check_implicit_always},
{"sstc", "zicsr", check_implicit_always},
{NULL, NULL, NULL}
};

Expand Down
1 change: 1 addition & 0 deletions gas/testsuite/gas/riscv/dw-regnums.d
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Contents of the .* section:
DW_CFA_offset_extended_sf: r29 \(t4\) at cfa\+120
DW_CFA_offset_extended_sf: r30 \(t5\) at cfa\+124
DW_CFA_offset_extended_sf: r31 \(t6\) at cfa\+128
DW_CFA_offset_extended_sf: r8 \(s0\) at cfa\+36
DW_CFA_offset_extended_sf: r0 \(zero\) at cfa\+4
DW_CFA_offset_extended_sf: r1 \(ra\) at cfa\+8
DW_CFA_offset_extended_sf: r2 \(sp\) at cfa\+12
Expand Down
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/dw-regnums.s
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ _start:
.cfi_offset t5, 124
.cfi_offset t6, 128

# GPR (ABI alias)
.cfi_offset fp, 36

# GPRs (Numeric)
.cfi_offset x0, 4
.cfi_offset x1, 8
Expand Down
6 changes: 6 additions & 0 deletions gas/testsuite/gas/riscv/march-imply-h.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#as: -march=rv32ih -march-attr -misa-spec=20191213 -mpriv-spec=1.12
#readelf: -A
#source: empty.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p1_h1p0_zicsr2p0"
13 changes: 2 additions & 11 deletions include/opcode/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,6 @@ static inline unsigned int riscv_insn_length (insn_t insn)
return 2;
}

static const char * const riscv_rm[8] =
{
"rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn"
};

static const char * const riscv_pred_succ[16] =
{
0, "w", "r", "rw", "o", "ow", "or", "orw",
"i", "iw", "ir", "irw", "io", "iow", "ior", "iorw"
};

#define RVC_JUMP_BITS 11
#define RVC_JUMP_REACH ((1ULL << RVC_JUMP_BITS) * RISCV_JUMP_ALIGN)

Expand Down Expand Up @@ -555,6 +544,8 @@ extern const char * const riscv_gpr_names_numeric[NGPR];
extern const char * const riscv_gpr_names_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];
extern const char * const riscv_pred_succ[16];
extern const char * const riscv_vecr_names_numeric[NVECR];
extern const char * const riscv_vecm_names_numeric[NVECM];
extern const char * const riscv_vsew[8];
Expand Down
40 changes: 27 additions & 13 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@
#include <stdint.h>
#include <ctype.h>

/* Current XLEN for the disassembler. */
static unsigned xlen = 0;

/* Default ISA specification version (constant as of now). */
static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;

unsigned xlen = 0;
/* Default privileged specification
(as specified by the ELF attributes or the `priv-spec' option). */
static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;

static riscv_subset_list_t riscv_subsets;
static riscv_parse_subset_t riscv_rps_dis =
Expand All @@ -59,27 +64,32 @@ struct riscv_private_data
/* Used for mapping symbols. */
static int last_map_symbol = -1;
static bfd_vma last_stop_offset = 0;
enum riscv_seg_mstate last_map_state;

/* Register names as used by the disassembler. */
static const char * const *riscv_gpr_names;
static const char * const *riscv_fpr_names;

/* If set, disassemble as most general instruction. */
static int no_aliases;
static bool no_aliases = false;


/* Set default RISC-V disassembler options. */

static void
set_default_riscv_dis_options (void)
{
riscv_gpr_names = riscv_gpr_names_abi;
riscv_fpr_names = riscv_fpr_names_abi;
no_aliases = 0;
no_aliases = false;
}

/* Parse RISC-V disassembler option (without arguments). */

static bool
parse_riscv_dis_option_without_args (const char *option)
{
if (strcmp (option, "no-aliases") == 0)
no_aliases = 1;
no_aliases = true;
else if (strcmp (option, "numeric") == 0)
{
riscv_gpr_names = riscv_gpr_names_numeric;
Expand All @@ -90,6 +100,8 @@ parse_riscv_dis_option_without_args (const char *option)
return true;
}

/* Parse RISC-V disassembler option (possibly with arguments). */

static void
parse_riscv_dis_option (const char *option)
{
Expand Down Expand Up @@ -143,6 +155,8 @@ parse_riscv_dis_option (const char *option)
}
}

/* Parse RISC-V disassembler options. */

static void
parse_riscv_dis_options (const char *opts_in)
{
Expand Down Expand Up @@ -170,6 +184,8 @@ arg_print (struct disassemble_info *info, unsigned long val,
(*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", s);
}

/* If we need to print an address, set its value and state. */

static void
maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
int wide)
Expand Down Expand Up @@ -628,7 +644,7 @@ static int
riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
{
const struct riscv_opcode *op;
static bool init = 0;
static bool init = false;
static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
struct riscv_private_data *pd;
int insnlen;
Expand All @@ -642,7 +658,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
if (!riscv_hash[OP_HASH_IDX (op->match)])
riscv_hash[OP_HASH_IDX (op->match)] = op;

init = 1;
init = true;
}

if (info->private_data == NULL)
Expand Down Expand Up @@ -697,8 +713,8 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;
}

/* If arch has ZFINX flags, use gpr for disassemble. */
if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
/* If arch has the Zfinx extension, replace FPR with GPR. */
if (riscv_subset_supports (&riscv_rps_dis, "zfinx"))
riscv_fpr_names = riscv_gpr_names;

for (; op->name; op++)
Expand All @@ -712,7 +728,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
/* Is this instruction restricted to a certain value of XLEN? */
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
continue;

/* Is this instruction supported by the current architecture? */
if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
continue;

Expand Down Expand Up @@ -1024,8 +1040,6 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
set_default_riscv_dis_options ();

mstate = riscv_search_mapping_symbol (memaddr, info);
/* Save the last mapping state. */
last_map_state = mstate;

/* Set the size to dump. */
if (mstate == MAP_DATA
Expand Down
25 changes: 21 additions & 4 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ const char * const riscv_fpr_names_abi[NFPR] =
"fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
};

/* Rounding modes. */
const char * const riscv_rm[8] =
{
"rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn"
};

/* FENCE: predecessor/successor sets. */
const char * const riscv_pred_succ[16] =
{
0, "w", "r", "rw", "o", "ow", "or", "orw",
"i", "iw", "ir", "irw", "io", "iow", "ior", "iorw"
};

/* RVV registers. */
const char * const riscv_vecr_names_numeric[NVECR] =
{
Expand Down Expand Up @@ -298,6 +311,14 @@ match_th_load_pair(const struct riscv_opcode *op,
const struct riscv_opcode riscv_opcodes[] =
{
/* name, xlen, isa, operands, match, mask, match_func, pinfo. */

/* Standard hints. */
{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 },
{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 },
{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 },
{"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 },

/* Basic RVI instructions and aliases. */
{"unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, INSN_ALIAS },
{"unimp", 0, INSN_CLASS_I, "", MATCH_CSRRW|(CSR_CYCLE << OP_SH_CSR), 0xffffffffU, match_opcode, 0 }, /* csrw cycle, x0 */
{"ebreak", 0, INSN_CLASS_C, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
Expand Down Expand Up @@ -417,9 +438,6 @@ const struct riscv_opcode riscv_opcodes[] =
{"lw", 0, INSN_CLASS_I, "d,o(s)", MATCH_LW, MASK_LW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"lw", 0, INSN_CLASS_I, "d,A", 0, (int) M_LW, match_never, INSN_MACRO },
{"not", 0, INSN_CLASS_I, "d,s", MATCH_XORI|MASK_IMM, MASK_XORI|MASK_IMM, match_opcode, INSN_ALIAS },
{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 },
{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 },
{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 },
{"or", 0, INSN_CLASS_I, "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
{"or", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
{"or", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
Expand All @@ -446,7 +464,6 @@ const struct riscv_opcode riscv_opcodes[] =
{"sw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
{"sw", 0, INSN_CLASS_I, "t,q(s)", MATCH_SW, MASK_SW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"sw", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
{"pause", 0, INSN_CLASS_ZIHINTPAUSE, "",MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 },
{"fence", 0, INSN_CLASS_I, "", MATCH_FENCE|MASK_PRED|MASK_SUCC, MASK_FENCE|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS },
{"fence", 0, INSN_CLASS_I, "P,Q", MATCH_FENCE, MASK_FENCE|MASK_RD|MASK_RS1|(MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
{"fence.i", 0, INSN_CLASS_ZIFENCEI, "", MATCH_FENCE_I, MASK_FENCE|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, 0 },
Expand Down