[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