[RFC PATCH 1/3] RISC-V: Add xlen to match_func
Tsukasa OI
research_trasio@irq.a4lg.com
Mon May 23 10:06:23 GMT 2022
For shift amount checking against current XLEN, we need to add third
argument `xlen' to opcode-matching function.
gas/ChangeLog:
* config/tc-riscv.c (riscv_ip): Call match_func with XLEN.
include/ChangeLog:
* opcode/riscv.h (struct riscv_opcode): Modify match_func so
that XLEN can be matched.
opcodes/ChangeLog:
* riscv-dis.c (riscv_disassemble_insn): Call match_func
with XLEN.
* riscv-opc.c (match_opcode, match_never, match_rs1_eq_rs2,
match_rd_nonzero, match_c_add, match_c_add_with_hint,
match_c_nop, match_c_addi16sp, match_c_lui,
match_c_lui_with_hint, match_c_addi4spn, match_c_slli,
match_slli_as_c_slli, match_c_slli64, match_srxi_as_c_srxi,
match_vs1_eq_vs2, match_vd_eq_vs1_eq_vs2): Add argument `xlen'.
ChangeLog:
* sim/riscv/sim-main.c (step_once): Call match_func with XLEN.
---
gas/config/tc-riscv.c | 2 +-
include/opcode/riscv.h | 3 +-
opcodes/riscv-dis.c | 2 +-
opcodes/riscv-opc.c | 76 ++++++++++++++++++++++++------------------
sim/riscv/sim-main.c | 2 +-
5 files changed, 49 insertions(+), 36 deletions(-)
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 1b730b4be36..b207b2d30c8 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2309,7 +2309,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
case '\0': /* End of args. */
if (insn->pinfo != INSN_MACRO)
{
- if (!insn->match_func (insn, ip->insn_opcode))
+ if (!insn->match_func (insn, ip->insn_opcode, xlen))
break;
/* For .insn, insn->match and insn->mask are 0. */
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 0d1fbcf8fc5..6ee2640cac1 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -426,7 +426,8 @@ struct riscv_opcode
/* A function to determine if a word corresponds to this instruction.
Usually, this computes ((word & mask) == match). */
- int (*match_func) (const struct riscv_opcode *op, insn_t word);
+ int (*match_func) (const struct riscv_opcode *op, insn_t word,
+ unsigned xlen);
/* For a macro, this is INSN_MACRO. Otherwise, it is a collection
of bits describing the instruction, notably any relevant hazard
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 9ff31167775..4738c6a98c7 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -644,7 +644,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
for (; op->name; op++)
{
/* Does the opcode match? */
- if (! (op->match_func) (op, word))
+ if (! (op->match_func) (op, word, xlen))
continue;
/* Is this a pseudo-instruction and may we print it as such? */
if (no_aliases && (op->pinfo & INSN_ALIAS))
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index bbd4a3718f6..636e67a3eb0 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -132,65 +132,71 @@ const char * const riscv_vma[2] =
#define MASK_VMASK (OP_MASK_VMASK << OP_SH_VMASK)
static int
-match_opcode (const struct riscv_opcode *op, insn_t insn)
+match_opcode (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen ATTRIBUTE_UNUSED)
{
return ((insn ^ op->match) & op->mask) == 0;
}
static int
match_never (const struct riscv_opcode *op ATTRIBUTE_UNUSED,
- insn_t insn ATTRIBUTE_UNUSED)
+ insn_t insn ATTRIBUTE_UNUSED,
+ unsigned xlen ATTRIBUTE_UNUSED)
{
return 0;
}
static int
-match_rs1_eq_rs2 (const struct riscv_opcode *op, insn_t insn)
+match_rs1_eq_rs2 (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
int rs2 = (insn & MASK_RS2) >> OP_SH_RS2;
- return match_opcode (op, insn) && rs1 == rs2;
+ return match_opcode (op, insn, xlen) && rs1 == rs2;
}
static int
-match_rd_nonzero (const struct riscv_opcode *op, insn_t insn)
+match_rd_nonzero (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return match_opcode (op, insn) && ((insn & MASK_RD) != 0);
+ return match_opcode (op, insn, xlen) && ((insn & MASK_RD) != 0);
}
static int
-match_c_add (const struct riscv_opcode *op, insn_t insn)
+match_c_add (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
{
- return match_rd_nonzero (op, insn) && ((insn & MASK_CRS2) != 0);
+ return match_rd_nonzero (op, insn, xlen) && ((insn & MASK_CRS2) != 0);
}
/* We don't allow mv zero,X to become a c.mv hint, so we need a separate
matching function for this. */
static int
-match_c_add_with_hint (const struct riscv_opcode *op, insn_t insn)
+match_c_add_with_hint (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return match_opcode (op, insn) && ((insn & MASK_CRS2) != 0);
+ return match_opcode (op, insn, xlen) && ((insn & MASK_CRS2) != 0);
}
static int
-match_c_nop (const struct riscv_opcode *op, insn_t insn)
+match_c_nop (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
{
- return (match_opcode (op, insn)
+ return (match_opcode (op, insn, xlen)
&& (((insn & MASK_RD) >> OP_SH_RD) == 0));
}
static int
-match_c_addi16sp (const struct riscv_opcode *op, insn_t insn)
+match_c_addi16sp (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return (match_opcode (op, insn)
+ return (match_opcode (op, insn, xlen)
&& (((insn & MASK_RD) >> OP_SH_RD) == 2));
}
static int
-match_c_lui (const struct riscv_opcode *op, insn_t insn)
+match_c_lui (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
{
- return (match_rd_nonzero (op, insn)
+ return (match_rd_nonzero (op, insn, xlen)
&& (((insn & MASK_RD) >> OP_SH_RD) != 2)
&& EXTRACT_CITYPE_LUI_IMM (insn) != 0);
}
@@ -199,71 +205,77 @@ match_c_lui (const struct riscv_opcode *op, insn_t insn)
matching function for this. */
static int
-match_c_lui_with_hint (const struct riscv_opcode *op, insn_t insn)
+match_c_lui_with_hint (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return (match_opcode (op, insn)
+ return (match_opcode (op, insn, xlen)
&& (((insn & MASK_RD) >> OP_SH_RD) != 2)
&& EXTRACT_CITYPE_LUI_IMM (insn) != 0);
}
static int
-match_c_addi4spn (const struct riscv_opcode *op, insn_t insn)
+match_c_addi4spn (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return match_opcode (op, insn) && EXTRACT_CIWTYPE_ADDI4SPN_IMM (insn) != 0;
+ return match_opcode (op, insn, xlen)
+ && EXTRACT_CIWTYPE_ADDI4SPN_IMM (insn) != 0;
}
/* This requires a non-zero shift. A zero rd is a hint, so is allowed. */
static int
-match_c_slli (const struct riscv_opcode *op, insn_t insn)
+match_c_slli (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
{
- return match_opcode (op, insn) && EXTRACT_CITYPE_IMM (insn) != 0;
+ return match_opcode (op, insn, xlen) && EXTRACT_CITYPE_IMM (insn) != 0;
}
/* This requires a non-zero rd, and a non-zero shift. */
static int
-match_slli_as_c_slli (const struct riscv_opcode *op, insn_t insn)
+match_slli_as_c_slli (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return match_rd_nonzero (op, insn) && EXTRACT_CITYPE_IMM (insn) != 0;
+ return match_rd_nonzero (op, insn, xlen)
+ && EXTRACT_CITYPE_IMM (insn) != 0;
}
/* This requires a zero shift. A zero rd is a hint, so is allowed. */
static int
-match_c_slli64 (const struct riscv_opcode *op, insn_t insn)
+match_c_slli64 (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
{
- return match_opcode (op, insn) && EXTRACT_CITYPE_IMM (insn) == 0;
+ return match_opcode (op, insn, xlen) && EXTRACT_CITYPE_IMM (insn) == 0;
}
/* This is used for both srli and srai. This requires a non-zero shift.
A zero rd is not possible. */
static int
-match_srxi_as_c_srxi (const struct riscv_opcode *op, insn_t insn)
+match_srxi_as_c_srxi (const struct riscv_opcode *op, insn_t insn,
+ unsigned xlen)
{
- return match_opcode (op, insn) && EXTRACT_CITYPE_IMM (insn) != 0;
+ return match_opcode (op, insn, xlen) && EXTRACT_CITYPE_IMM (insn) != 0;
}
static int
match_vs1_eq_vs2 (const struct riscv_opcode *op,
- insn_t insn)
+ insn_t insn, unsigned xlen)
{
int vs1 = (insn & MASK_VS1) >> OP_SH_VS1;
int vs2 = (insn & MASK_VS2) >> OP_SH_VS2;
- return match_opcode (op, insn) && vs1 == vs2;
+ return match_opcode (op, insn, xlen) && vs1 == vs2;
}
static int
match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
- insn_t insn)
+ insn_t insn, unsigned xlen)
{
int vd = (insn & MASK_VD) >> OP_SH_VD;
int vs1 = (insn & MASK_VS1) >> OP_SH_VS1;
int vs2 = (insn & MASK_VS2) >> OP_SH_VS2;
- return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
+ return match_opcode (op, insn, xlen) && vd == vs1 && vs1 == vs2;
}
const struct riscv_opcode riscv_opcodes[] =
diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c
index 62f475671c9..0b0a021a1c6 100644
--- a/sim/riscv/sim-main.c
+++ b/sim/riscv/sim-main.c
@@ -983,7 +983,7 @@ void step_once (SIM_CPU *cpu)
for (; op->name; op++)
{
/* Does the opcode match? */
- if (! op->match_func (op, iw))
+ if (! op->match_func (op, iw, xlen))
continue;
/* Is this a pseudo-instruction and may we print it as such? */
if (op->pinfo & INSN_ALIAS)
--
2.34.1
More information about the Binutils
mailing list