From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sender-0.a4lg.com (mail-sender.a4lg.com [153.120.152.154]) by sourceware.org (Postfix) with ESMTPS id 8E3A4382E911 for ; Mon, 23 May 2022 10:06:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8E3A4382E911 Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id DD9BC300089; Mon, 23 May 2022 10:06:42 +0000 (UTC) From: Tsukasa OI To: Tsukasa OI , Palmer Dabbelt , Nelson Chu , Kito Cheng 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 Message-Id: In-Reply-To: References: Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 May 2022 10:06:46 -0000 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