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 2/3] RISC-V: Check shift amount against XLEN
Date: Mon, 23 May 2022 19:06:24 +0900	[thread overview]
Message-ID: <cdd521641d6d0d7e141d72c7955c585053a05d9e.1653300374.git.research_trasio@irq.a4lg.com> (raw)
In-Reply-To: <cover.1653300374.git.research_trasio@irq.a4lg.com>

Although assembler does the equivalent, disassembler did not have shift
amount checking.  This commit makes such invalid RV32 instruction
invalid by checking shift amount against current XLEN.

gas/ChangeLog:

	* config/tc-riscv.c (riscv_ip): Mask shift amount to suppress
	extra assembler error messages.

opcodes/ChangeLog:

	* riscv-opc.c (match_shamt): New.
	(match_c_slli, match_slli_as_c_slli, match_srxi_as_c_srxi):
	Check shift amount against current xlen.
---
 gas/config/tc-riscv.c |  6 +++--
 opcodes/riscv-opc.c   | 52 ++++++++++++++++++++++++++-----------------
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b207b2d30c8..66907bdf0f2 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2403,7 +2403,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      || imm_expr->X_op != O_constant
 		      || (unsigned long) imm_expr->X_add_number >= xlen)
 		    break;
-		  ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
+		  ip->insn_opcode |=
+		    ENCODE_CITYPE_IMM (imm_expr->X_add_number & (xlen - 1));
 		rvc_imm_done:
 		  asarg = expr_end;
 		  imm_expr->X_op = O_absent;
@@ -2843,7 +2844,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      if ((unsigned long) imm_expr->X_add_number >= xlen)
 		as_bad (_("improper shift amount (%lu)"),
 			(unsigned long) imm_expr->X_add_number);
-	      INSERT_OPERAND (SHAMT, *ip, imm_expr->X_add_number);
+	      INSERT_OPERAND (SHAMT, *ip,
+			      imm_expr->X_add_number & (xlen - 1));
 	      imm_expr->X_op = O_absent;
 	      asarg = expr_end;
 	      continue;
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 636e67a3eb0..b71a9f4711a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -162,6 +162,13 @@ match_rd_nonzero (const struct riscv_opcode *op, insn_t insn,
   return match_opcode (op, insn, xlen) && ((insn & MASK_RD) != 0);
 }
 
+static int
+match_shamt (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
+{
+  unsigned shamt = (insn & MASK_SHAMT) >> OP_SH_SHAMT;
+  return match_opcode (op, insn, xlen) && shamt < xlen;
+}
+
 static int
 match_c_add (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
 {
@@ -226,7 +233,9 @@ match_c_addi4spn (const struct riscv_opcode *op, insn_t insn,
 static int
 match_c_slli (const struct riscv_opcode *op, insn_t insn, unsigned xlen)
 {
-  return match_opcode (op, insn, xlen) && EXTRACT_CITYPE_IMM (insn) != 0;
+  return match_opcode (op, insn, xlen)
+	 && EXTRACT_CITYPE_IMM (insn) != 0
+	 && (EXTRACT_CITYPE_IMM (insn) & (RISCV_RVC_IMM_REACH - 1)) < xlen;
 }
 
 /* This requires a non-zero rd, and a non-zero shift.  */
@@ -236,7 +245,8 @@ match_slli_as_c_slli (const struct riscv_opcode *op, insn_t insn,
 		      unsigned xlen)
 {
   return match_rd_nonzero (op, insn, xlen)
-	 && EXTRACT_CITYPE_IMM (insn) != 0;
+	 && EXTRACT_CITYPE_IMM (insn) != 0
+	 && (EXTRACT_CITYPE_IMM (insn) & (RISCV_RVC_IMM_REACH - 1)) < xlen;
 }
 
 /* This requires a zero shift.  A zero rd is a hint, so is allowed.  */
@@ -254,7 +264,9 @@ static int
 match_srxi_as_c_srxi (const struct riscv_opcode *op, insn_t insn,
 		      unsigned xlen)
 {
-  return match_opcode (op, insn, xlen) && EXTRACT_CITYPE_IMM (insn) != 0;
+  return match_opcode (op, insn, xlen)
+	 && EXTRACT_CITYPE_IMM (insn) != 0
+	 && (EXTRACT_CITYPE_IMM (insn) & (RISCV_RVC_IMM_REACH - 1)) < xlen;
 }
 
 static int
@@ -371,20 +383,20 @@ const struct riscv_opcode riscv_opcodes[] =
 {"la.tls.ie",   0, INSN_CLASS_I, "d,A",       0, (int) M_LA_TLS_IE, match_never, INSN_MACRO },
 {"neg",         0, INSN_CLASS_I, "d,t",       MATCH_SUB, MASK_SUB|MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0  */
 {"slli",        0, INSN_CLASS_C, "d,CU,C>",   MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
-{"slli",        0, INSN_CLASS_I, "d,s,>",     MATCH_SLLI, MASK_SLLI, match_opcode, 0 },
+{"slli",        0, INSN_CLASS_I, "d,s,>",     MATCH_SLLI, MASK_SLLI, match_shamt, 0 },
 {"sll",         0, INSN_CLASS_C, "d,CU,C>",   MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
 {"sll",         0, INSN_CLASS_I, "d,s,t",     MATCH_SLL, MASK_SLL, match_opcode, 0 },
-{"sll",         0, INSN_CLASS_I, "d,s,>",     MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS },
+{"sll",         0, INSN_CLASS_I, "d,s,>",     MATCH_SLLI, MASK_SLLI, match_shamt, INSN_ALIAS },
 {"srli",        0, INSN_CLASS_C, "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
-{"srli",        0, INSN_CLASS_I, "d,s,>",     MATCH_SRLI, MASK_SRLI, match_opcode, 0 },
+{"srli",        0, INSN_CLASS_I, "d,s,>",     MATCH_SRLI, MASK_SRLI, match_shamt, 0 },
 {"srl",         0, INSN_CLASS_C, "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"srl",         0, INSN_CLASS_I, "d,s,t",     MATCH_SRL, MASK_SRL, match_opcode, 0 },
-{"srl",         0, INSN_CLASS_I, "d,s,>",     MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS },
+{"srl",         0, INSN_CLASS_I, "d,s,>",     MATCH_SRLI, MASK_SRLI, match_shamt, INSN_ALIAS },
 {"srai",        0, INSN_CLASS_C, "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
-{"srai",        0, INSN_CLASS_I, "d,s,>",     MATCH_SRAI, MASK_SRAI, match_opcode, 0 },
+{"srai",        0, INSN_CLASS_I, "d,s,>",     MATCH_SRAI, MASK_SRAI, match_shamt, 0 },
 {"sra",         0, INSN_CLASS_C, "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"sra",         0, INSN_CLASS_I, "d,s,t",     MATCH_SRA, MASK_SRA, match_opcode, 0 },
-{"sra",         0, INSN_CLASS_I, "d,s,>",     MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS },
+{"sra",         0, INSN_CLASS_I, "d,s,>",     MATCH_SRAI, MASK_SRAI, match_shamt, INSN_ALIAS },
 {"sub",         0, INSN_CLASS_C, "Cs,Cw,Ct",  MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
 {"sub",         0, INSN_CLASS_I, "d,s,t",     MATCH_SUB, MASK_SUB, match_opcode, 0 },
 {"lb",          0, INSN_CLASS_I, "d,o(s)",    MATCH_LB, MASK_LB, match_opcode, INSN_DREF|INSN_1_BYTE },
@@ -963,9 +975,9 @@ const struct riscv_opcode riscv_opcodes[] =
 {"orn",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ORN, MASK_ORN, match_opcode, 0 },
 {"xnor",       0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_XNOR, MASK_XNOR, match_opcode, 0 },
 {"rol",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ROL, MASK_ROL, match_opcode, 0 },
-{"rori",       0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,>", MATCH_RORI, MASK_RORI, match_opcode, 0 },
+{"rori",       0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,>", MATCH_RORI, MASK_RORI, match_shamt, 0 },
 {"ror",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ROR, MASK_ROR, match_opcode, 0 },
-{"ror",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,>", MATCH_RORI, MASK_RORI, match_opcode, INSN_ALIAS },
+{"ror",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,>", MATCH_RORI, MASK_RORI, match_shamt, INSN_ALIAS },
 {"rev8",      32, INSN_CLASS_ZBB_OR_ZBKB,  "d,s",   MATCH_GREVI | MATCH_SHAMT_REV8_32, MASK_GREVI | MASK_SHAMT, match_opcode, 0 },
 {"rev8",      64, INSN_CLASS_ZBB_OR_ZBKB,  "d,s",   MATCH_GREVI | MATCH_SHAMT_REV8_64, MASK_GREVI | MASK_SHAMT, match_opcode, 0 },
 {"rolw",      64, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ROLW, MASK_ROLW, match_opcode, 0 },
@@ -983,7 +995,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"zext.w",    64, INSN_CLASS_ZBA,  "d,s",   MATCH_ADD_UW, MASK_ADD_UW | MASK_RS2, match_opcode, INSN_ALIAS },
 {"zext.w",    64, INSN_CLASS_I, "d,s",       0, (int) M_ZEXTW, match_never, INSN_MACRO },
 {"add.uw",    64, INSN_CLASS_ZBA,  "d,s,t", MATCH_ADD_UW, MASK_ADD_UW, match_opcode, 0 },
-{"slli.uw",   64, INSN_CLASS_ZBA,  "d,s,>", MATCH_SLLI_UW, MASK_SLLI_UW, match_opcode, 0 },
+{"slli.uw",   64, INSN_CLASS_ZBA,  "d,s,>", MATCH_SLLI_UW, MASK_SLLI_UW, match_shamt, 0 },
 
 /* Zbc or zbkc instructions.  */
 {"clmul",      0, INSN_CLASS_ZBC_OR_ZBKC,  "d,s,t", MATCH_CLMUL, MASK_CLMUL, match_opcode, 0 },
@@ -991,18 +1003,18 @@ const struct riscv_opcode riscv_opcodes[] =
 {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },
 
 /* Zbs instructions.  */
-{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, 0 },
-{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, 0 },
-{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, 0 },
-{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, 0 },
+{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_shamt, 0 },
+{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_shamt, 0 },
+{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_shamt, 0 },
+{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_shamt, 0 },
 {"bclr",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BCLR, MASK_BCLR, match_opcode, 0 },
-{"bclr",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, INSN_ALIAS },
+{"bclr",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_shamt, INSN_ALIAS },
 {"bset",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BSET, MASK_BSET, match_opcode, 0 },
-{"bset",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, INSN_ALIAS },
+{"bset",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_shamt, INSN_ALIAS },
 {"binv",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BINV, MASK_BINV, match_opcode, 0 },
-{"binv",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, INSN_ALIAS },
+{"binv",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_shamt, INSN_ALIAS },
 {"bext",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },
-{"bext",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, INSN_ALIAS },
+{"bext",      0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_shamt, INSN_ALIAS },
 
 /* Zbkx instructions.  */
 {"xperm4",     0, INSN_CLASS_ZBKX,  "d,s,t",  MATCH_XPERM4, MASK_XPERM4, match_opcode, 0 },
-- 
2.34.1


  parent 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 ` [RFC PATCH 1/3] RISC-V: Add xlen to match_func Tsukasa OI
2022-05-23 10:06 ` Tsukasa OI [this message]
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=cdd521641d6d0d7e141d72c7955c585053a05d9e.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).