public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Tsukasa OI <research_trasio@irq.a4lg.com>
To: Tsukasa OI <research_trasio@irq.a4lg.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Nelson Chu <nelson.chu@sifive.com>,
	Kito Cheng <kito.cheng@sifive.com>
Cc: binutils@sourceware.org
Subject: [RFC PATCH 1/3] RISC-V: Add xlen to match_func
Date: Mon, 23 May 2022 19:06:23 +0900	[thread overview]
Message-ID: <dc7d6ae40bd6c21b66a8e9b44c6d15285921407e.1653300374.git.research_trasio@irq.a4lg.com> (raw)
In-Reply-To: <cover.1653300374.git.research_trasio@irq.a4lg.com>

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


  reply	other threads:[~2022-05-23 10:06 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-23 10:06 [RFC PATCH 0/3] RISC-V: Check shift amount against XLEN (disassembler) Tsukasa OI
2022-05-23 10:06 ` Tsukasa OI [this message]
2022-05-23 10:06 ` [RFC PATCH 2/3] RISC-V: Check shift amount against XLEN Tsukasa OI
2022-05-23 10:06 ` [RFC PATCH 3/3] RISC-V: Add disassembler tests for shift amount Tsukasa OI
2022-07-30  3:47 ` [RFC PATCH 0/3] RISC-V: Check shift amount against XLEN (disassembler) Tsukasa OI
2022-07-30  3:51 ` [PATCH 0/1] " Tsukasa OI
2022-07-30  3:51   ` [PATCH 1/1] RISC-V: Check shift amount against XLEN (disasm) Tsukasa OI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dc7d6ae40bd6c21b66a8e9b44c6d15285921407e.1653300374.git.research_trasio@irq.a4lg.com \
    --to=research_trasio@irq.a4lg.com \
    --cc=binutils@sourceware.org \
    --cc=kito.cheng@sifive.com \
    --cc=nelson.chu@sifive.com \
    --cc=palmer@dabbelt.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).