return match_opcode (op, insn) && EXTRACT_RVC_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)
+{
+ return match_opcode (op, insn) && EXTRACT_RVC_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_RVC_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)
+{
+ return match_opcode (op, insn) && EXTRACT_RVC_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_RVC_IMM (insn) != 0;
+}
+
const struct riscv_opcode riscv_opcodes[] =
{
/* name, isa, operands, match, mask, match_func, pinfo. */
{"la.tls.gd", "I", "d,A", 0, (int) M_LA_TLS_GD, match_never, INSN_MACRO },
{"la.tls.ie", "I", "d,A", 0, (int) M_LA_TLS_IE, match_never, INSN_MACRO },
{"neg", "I", "d,t", MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
-{"slli", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"slli", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
{"slli", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, 0 },
-{"sll", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"sll", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
{"sll", "I", "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, 0 },
{"sll", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS },
-{"srli", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, INSN_ALIAS },
+{"srli", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srli", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, 0 },
-{"srl", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, INSN_ALIAS },
+{"srl", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srl", "I", "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, 0 },
{"srl", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS },
-{"srai", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, INSN_ALIAS },
+{"srai", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srai", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, 0 },
-{"sra", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, INSN_ALIAS },
+{"sra", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
{"sra", "I", "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, 0 },
{"sra", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS },
{"sub", "C", "Cs,Cw,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
{"c.and", "C", "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
{"c.or", "C", "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
{"c.xor", "C", "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
-{"c.slli", "C", "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_opcode, 0 },
-{"c.srli", "C", "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
-{"c.srai", "C", "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
+{"c.slli", "C", "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_c_slli, 0 },
+{"c.srli", "C", "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_c_slli, 0 },
+{"c.srai", "C", "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_c_slli, 0 },
+{"c.slli64", "C", "d", MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, 0 },
+{"c.srli64", "C", "Cs", MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, 0 },
+{"c.srai64", "C", "Cs", MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, 0 },
{"c.andi", "C", "Cs,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
{"c.addiw", "64C", "d,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
{"c.addw", "64C", "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },