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
next prev 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).