aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNelson Chu <nelson@rivosinc.com>2025-08-20 17:47:14 +0800
committerNelson Chu <nelson@rivosinc.com>2025-08-20 18:02:49 +0800
commitcb4ed2bee7bea6dbd4384b1f7af6493eaf7af5d1 (patch)
tree6aa913f19522ae86b14ac58a08c5a39a893415e7
parentfed7c3654c8d90e1bf6f5c3f498de789632c0e23 (diff)
downloadbinutils-cb4ed2bee7bea6dbd4384b1f7af6493eaf7af5d1.zip
binutils-cb4ed2bee7bea6dbd4384b1f7af6493eaf7af5d1.tar.gz
binutils-cb4ed2bee7bea6dbd4384b1f7af6493eaf7af5d1.tar.bz2
RISC-V: PR33216, Fixed gcc testcases failed for commit 28520d7
I made a stupid mistake in the commit 28520d7, allow to assemble slli/srli/srai with 0 immediate to hint c.slli/c.srli/c.srai. These hints will be regared as illegal instruction for gdb and qemu, so at least I got following gcc testcases failed, === g++: Unexpected fails for rv64gc lp64d medlow === FAIL: c-c++-common/torture/builtin-arith-overflow-17.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-6.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-p-17.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-p-6.c -O0 execution test === gfortran: Unexpected fails for rv64gc lp64d medlow === FAIL: gfortran.dg/leadz_trailz_2.f90 -O0 execution test === gcc: Unexpected fails for rv64gc lp64d medlow === FAIL: c-c++-common/torture/builtin-arith-overflow-17.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-6.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-p-17.c -O0 execution test FAIL: c-c++-common/torture/builtin-arith-overflow-p-6.c -O0 execution test So we should just allow c.slli/c.srli/c.srai with zero immediate as hints, but don't allow slli/srli/srai with zero immediate. gas/ PR 33216 * testsuite/gas/riscv/c-zero-imm.d: Only allow c.slli/c.srli/c.srai with zero immediate as hints, but don't allow slli/srli/srai with zero immediate. * testsuite/gas/riscv/c-zero-imm.s: Likewise. opcodes/ PR 33216 * riscv-opc.c (match_slli_as_c_slli): Added back. (match_srxi_as_c_srxi): Likewise. (riscv_opcodes): Only allow c.slli/c.srli/c.srai with zero immediate as hints, but don't allow slli/srli/srai with zero immediate.
-rw-r--r--gas/testsuite/gas/riscv/c-zero-imm.d15
-rw-r--r--gas/testsuite/gas/riscv/c-zero-imm.s6
-rw-r--r--opcodes/riscv-opc.c35
3 files changed, 40 insertions, 16 deletions
diff --git a/gas/testsuite/gas/riscv/c-zero-imm.d b/gas/testsuite/gas/riscv/c-zero-imm.d
index 56274df..c3bab3a 100644
--- a/gas/testsuite/gas/riscv/c-zero-imm.d
+++ b/gas/testsuite/gas/riscv/c-zero-imm.d
@@ -14,10 +14,13 @@ Disassembly of section .text:
[ ]+8:[ ]+0001[ ]+nop
[ ]+a:[ ]+873a[ ]+mv[ ]+a4,a4
[ ]+c:[ ]+0781[ ]+addi[ ]+a5,a5,0
-[ ]+e:[ ]+0502[ ]+slli[ ]+a0,a0,0x0
-[ ]+10:[ ]+8181[ ]+srli[ ]+a1,a1,0x0
-[ ]+12:[ ]+8601[ ]+srai[ ]+a2,a2,0x0
-[ ]+14:[ ]+0682[ ]+slli[ ]+a3,a3,0x0
-[ ]+16:[ ]+8301[ ]+srli[ ]+a4,a4,0x0
-[ ]+18:[ ]+8781[ ]+srai[ ]+a5,a5,0x0
+[ ]+e:[ ]+00051513[ ]+slli[ ]+a0,a0,0x0
+[ ]+12:[ ]+0005d593[ ]+srli[ ]+a1,a1,0x0
+[ ]+16:[ ]+40065613[ ]+srai[ ]+a2,a2,0x0
+[ ]+1a:[ ]+0502[ ]+c.slli[ ]+a0,0x0
+[ ]+1c:[ ]+8181[ ]+c.srli[ ]+a1,0x0
+[ ]+1e:[ ]+8601[ ]+c.srai[ ]+a2,0x0
+[ ]+20:[ ]+0682[ ]+c.slli[ ]+a3,0x0
+[ ]+22:[ ]+8301[ ]+c.srli[ ]+a4,0x0
+[ ]+24:[ ]+8781[ ]+c.srai[ ]+a5,0x0
#...
diff --git a/gas/testsuite/gas/riscv/c-zero-imm.s b/gas/testsuite/gas/riscv/c-zero-imm.s
index be7c820..54269cf 100644
--- a/gas/testsuite/gas/riscv/c-zero-imm.s
+++ b/gas/testsuite/gas/riscv/c-zero-imm.s
@@ -9,11 +9,15 @@
addi a4,a4,0
# These are hints.
c.addi a5,0
- # Allow these compress to hints.
+ # Don't let these compress to hints
slli a0, a0, 0
srli a1, a1, 0
srai a2, a2, 0
# These are hints.
+ c.slli a0, 0
+ c.srli a1, 0
+ c.srai a2, 0
+ # These are also hints.
c.slli64 a3
c.srli64 a4
c.srai64 a5
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index b34fffe..e6fe5e9 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -313,6 +313,14 @@ match_c_addi4spn (const struct riscv_opcode *op, insn_t insn)
return match_opcode (op, insn) && EXTRACT_CIWTYPE_ADDI4SPN_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)
+{
+ return match_rd_nonzero (op, insn) && EXTRACT_CITYPE_IMM (insn) != 0;
+}
+
/* This requires a zero shift. A zero rd is a hint, so is allowed. */
static int
@@ -321,6 +329,15 @@ match_c_slli64 (const struct riscv_opcode *op, insn_t insn)
return match_opcode (op, insn) && 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)
+{
+ return match_opcode (op, insn) && EXTRACT_CITYPE_IMM (insn) != 0;
+}
+
static int
match_vs1_eq_vs2 (const struct riscv_opcode *op,
insn_t insn)
@@ -552,19 +569,19 @@ const struct riscv_opcode riscv_opcodes[] =
{"mips.ehb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_EHB, MASK_MIPS_EHB, match_opcode, 0 },
{"mips.ihb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_IHB, MASK_MIPS_IHB, match_opcode, 0 },
{"mips.pause", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_PAUSE, MASK_MIPS_PAUSE, match_opcode, 0 },
-{"slli", 0, INSN_CLASS_ZCA, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"slli", 0, INSN_CLASS_ZCA, "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 },
-{"sll", 0, INSN_CLASS_ZCA, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"sll", 0, INSN_CLASS_ZCA, "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 },
-{"srli", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_rd_nonzero, INSN_ALIAS },
+{"srli", 0, INSN_CLASS_ZCA, "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 },
-{"srl", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_rd_nonzero, INSN_ALIAS },
+{"srl", 0, INSN_CLASS_ZCA, "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 },
-{"srai", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_rd_nonzero, INSN_ALIAS },
+{"srai", 0, INSN_CLASS_ZCA, "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 },
-{"sra", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_rd_nonzero, INSN_ALIAS },
+{"sra", 0, INSN_CLASS_ZCA, "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 },
{"sub", 0, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
@@ -1174,12 +1191,12 @@ const struct riscv_opcode riscv_opcodes[] =
{"c.and", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
{"c.or", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
{"c.xor", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
-{"c.slli64", 0, INSN_CLASS_ZCA, "d", MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, INSN_ALIAS },
-{"c.srli64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, INSN_ALIAS },
-{"c.srai64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, INSN_ALIAS },
{"c.slli", 0, INSN_CLASS_ZCA, "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_opcode, 0 },
{"c.srli", 0, INSN_CLASS_ZCA, "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
{"c.srai", 0, INSN_CLASS_ZCA, "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
+{"c.slli64", 0, INSN_CLASS_ZCA, "d", MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, INSN_ALIAS }, /* Deprecated. */
+{"c.srli64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, INSN_ALIAS }, /* Deprecated. */
+{"c.srai64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, INSN_ALIAS }, /* Deprecated. */
{"c.andi", 0, INSN_CLASS_ZCA, "Cs,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
{"c.addiw", 64, INSN_CLASS_ZCA, "d,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
{"c.addw", 64, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },