diff options
-rw-r--r-- | bfd/elfxx-riscv.c | 21 | ||||
-rw-r--r-- | gas/config/tc-riscv.c | 53 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/zcb.d | 32 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/zcb.s | 25 | ||||
-rw-r--r-- | include/opcode/riscv-opc.h | 38 | ||||
-rw-r--r-- | include/opcode/riscv.h | 14 | ||||
-rw-r--r-- | opcodes/riscv-dis.c | 14 | ||||
-rw-r--r-- | opcodes/riscv-opc.c | 28 |
8 files changed, 225 insertions, 0 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 8635187..ee96608 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1173,6 +1173,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zvksc", "zvbc", check_implicit_always}, {"zcf", "zca", check_implicit_always}, {"zcd", "zca", check_implicit_always}, + {"zcb", "zca", check_implicit_always}, {"smaia", "ssaia", check_implicit_always}, {"smstateen", "ssstateen", check_implicit_always}, {"smepmp", "zicsr", check_implicit_always}, @@ -1307,6 +1308,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"ztso", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 }, {"zca", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {NULL, 0, 0, 0, 0} @@ -2494,6 +2496,17 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zvksed"); case INSN_CLASS_ZVKSH: return riscv_subset_supports (rps, "zvksh"); + case INSN_CLASS_ZCB: + return riscv_subset_supports (rps, "zcb"); + case INSN_CLASS_ZCB_AND_ZBB: + return (riscv_subset_supports (rps, "zcb") + && riscv_subset_supports (rps, "zbb")); + case INSN_CLASS_ZCB_AND_ZBA: + return (riscv_subset_supports (rps, "zcb") + && riscv_subset_supports (rps, "zba")); + case INSN_CLASS_ZCB_AND_ZMMUL: + return (riscv_subset_supports (rps, "zcb") + && riscv_subset_supports (rps, "zmmul")); case INSN_CLASS_SVINVAL: return riscv_subset_supports (rps, "svinval"); case INSN_CLASS_H: @@ -2702,6 +2715,14 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return _("zvksed"); case INSN_CLASS_ZVKSH: return _("zvksh"); + case INSN_CLASS_ZCB: + return "zcb"; + case INSN_CLASS_ZCB_AND_ZBA: + return _("zcb' and `zba"); + case INSN_CLASS_ZCB_AND_ZBB: + return _("zcb' and `zbb"); + case INSN_CLASS_ZCB_AND_ZMMUL: + return _("zcb' and `zmmul', or `zcb' and `m"); case INSN_CLASS_SVINVAL: return "svinval"; case INSN_CLASS_H: diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 8c23c6a..80c14a3 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1426,6 +1426,18 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) goto unknown_validate_operand; } break; + case 'c': + switch (*++oparg) + { + /* byte immediate operators, load/store byte insns. */ + case 'h': used_bits |= ENCODE_ZCB_HALFWORD_UIMM (-1U); break; + /* halfword immediate operators, load/store halfword insns. */ + case 'b': used_bits |= ENCODE_ZCB_BYTE_UIMM (-1U); break; + case 'f': break; + default: + goto unknown_validate_operand; + } + break; default: goto unknown_validate_operand; } @@ -3559,6 +3571,47 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, goto unknown_riscv_ip_operand; } break; + + case 'c': + switch (*++oparg) + { + case 'h': /* Immediate field for c.lh/c.lhu/c.sh. */ + /* Handle cases, such as c.sh rs2', (rs1'). */ + if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) + continue; + if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p) + || imm_expr->X_op != O_constant + || !VALID_ZCB_HALFWORD_UIMM ((valueT) imm_expr->X_add_number)) + break; + ip->insn_opcode |= ENCODE_ZCB_HALFWORD_UIMM (imm_expr->X_add_number); + goto rvc_imm_done; + + case 'b': /* Immediate field for c.lbu/c.sb. */ + /* Handle cases, such as c.lbu rd', (rs1'). */ + if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) + continue; + if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p) + || imm_expr->X_op != O_constant + || !VALID_ZCB_BYTE_UIMM ((valueT) imm_expr->X_add_number)) + break; + ip->insn_opcode |= ENCODE_ZCB_BYTE_UIMM (imm_expr->X_add_number); + goto rvc_imm_done; + + case 'f': /* Operand for matching immediate 255. */ + if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p) + || imm_expr->X_op != O_constant + || imm_expr->X_add_number != 255) + break; + /* This operand is used for matching immediate 255, and + we do not write anything to encoding by this operand. */ + asarg = expr_parse_end; + imm_expr->X_op = O_absent; + continue; + + default: + goto unknown_riscv_ip_operand; + } + break; default: goto unknown_riscv_ip_operand; } diff --git a/gas/testsuite/gas/riscv/zcb.d b/gas/testsuite/gas/riscv/zcb.d new file mode 100644 index 0000000..26a122b --- /dev/null +++ b/gas/testsuite/gas/riscv/zcb.d @@ -0,0 +1,32 @@ +#as: -march=rv64im_zba_zbb_zcb +#objdump: -d -Mno-aliases + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+8020[ ]+c.lbu[ ]+s0,2\(s0\) +[ ]+[0-9a-f]+:[ ]+8380[ ]+c.lbu[ ]+s0,0\(a5\) +[ ]+[0-9a-f]+:[ ]+8420[ ]+c.lhu[ ]+s0,2\(s0\) +[ ]+[0-9a-f]+:[ ]+8780[ ]+c.lhu[ ]+s0,0\(a5\) +[ ]+[0-9a-f]+:[ ]+8460[ ]+c.lh[ ]+s0,2\(s0\) +[ ]+[0-9a-f]+:[ ]+87c0[ ]+c.lh[ ]+s0,0\(a5\) +[ ]+[0-9a-f]+:[ ]+8820[ ]+c.sb[ ]+s0,2\(s0\) +[ ]+[0-9a-f]+:[ ]+8b80[ ]+c.sb[ ]+s0,0\(a5\) +[ ]+[0-9a-f]+:[ ]+8c20[ ]+c.sh[ ]+s0,2\(s0\) +[ ]+[0-9a-f]+:[ ]+8f80[ ]+c.sh[ ]+s0,0\(a5\) +[ ]+[0-9a-f]+:[ ]+9c61[ ]+c.zext.b[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9fe1[ ]+c.zext.b[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c65[ ]+c.sext.b[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9fe5[ ]+c.sext.b[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c69[ ]+c.zext.h[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9fe9[ ]+c.zext.h[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c6d[ ]+c.sext.h[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9fed[ ]+c.sext.h[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c71[ ]+c.zext.w[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9ff1[ ]+c.zext.w[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c75[ ]+c.not[ ]+s0 +[ ]+[0-9a-f]+:[ ]+9ff5[ ]+c.not[ ]+a5 +[ ]+[0-9a-f]+:[ ]+9c5d[ ]+c.mul[ ]+s0,a5 +[ ]+[0-9a-f]+:[ ]+9cd1[ ]+c.mul[ ]+s1,a2 diff --git a/gas/testsuite/gas/riscv/zcb.s b/gas/testsuite/gas/riscv/zcb.s new file mode 100644 index 0000000..2e70ab2 --- /dev/null +++ b/gas/testsuite/gas/riscv/zcb.s @@ -0,0 +1,25 @@ +target: + lbu x8,2(x8) + c.lbu x8,(x15) + lhu x8,2(x8) + c.lhu x8,(x15) + lh x8,2(x8) + c.lh x8,(x15) + sb x8,2(x8) + c.sb x8,(x15) + sh x8,2(x8) + c.sh x8,(x15) + zext.b x8,x8 + c.zext.b x15 + sext.b x8,x8 + c.sext.b x15 + zext.h x8,x8 + c.zext.h x15 + sext.h x8,x8 + c.sext.h x15 + zext.w x8,x8 + c.zext.w x15 + not x8,x8 + c.not x15 + mul x8,x8,x15 + c.mul x9,x12 diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 90f4415..53f5f20 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2210,6 +2210,31 @@ #define MASK_VSM3C_VI 0xfe00707f #define MATCH_VSM3ME_VV 0x82002077 #define MASK_VSM3ME_VV 0xfe00707f +/* Zcb instructions. */ +#define MATCH_C_LBU 0x8000 +#define MASK_C_LBU 0xfc03 +#define MATCH_C_LHU 0x8400 +#define MASK_C_LHU 0xfc43 +#define MATCH_C_LH 0x8440 +#define MASK_C_LH 0xfc43 +#define MATCH_C_SB 0x8800 +#define MASK_C_SB 0xfc03 +#define MATCH_C_SH 0x8c00 +#define MASK_C_SH 0xfc43 +#define MATCH_C_ZEXT_B 0x9c61 +#define MASK_C_ZEXT_B 0xfc7f +#define MATCH_C_SEXT_B 0x9c65 +#define MASK_C_SEXT_B 0xfc7f +#define MATCH_C_ZEXT_H 0x9c69 +#define MASK_C_ZEXT_H 0xfc7f +#define MATCH_C_SEXT_H 0x9c6d +#define MASK_C_SEXT_H 0xfc7f +#define MATCH_C_ZEXT_W 0x9c71 +#define MASK_C_ZEXT_W 0xfc7f +#define MATCH_C_NOT 0x9c75 +#define MASK_C_NOT 0xfc7f +#define MATCH_C_MUL 0x9c41 +#define MASK_C_MUL 0xfc63 /* Svinval instruction. */ #define MATCH_SINVAL_VMA 0x16000073 #define MASK_SINVAL_VMA 0xfe007fff @@ -3367,6 +3392,19 @@ DECLARE_INSN(vsm4r_vv, MATCH_VSM4R_VV, MASK_VSM4R_VV) /* Zvksh instructions. */ DECLARE_INSN(vsm3c_vi, MATCH_VSM3C_VI, MASK_VSM3C_VI) DECLARE_INSN(vsm3me_vv, MATCH_VSM3ME_VV, MASK_VSM3ME_VV) +/* Zcb instructions. */ +DECLARE_INSN(c_sext_b, MATCH_C_SEXT_B, MASK_C_SEXT_B) +DECLARE_INSN(c_sext_h, MATCH_C_SEXT_H, MASK_C_SEXT_H) +DECLARE_INSN(c_zext_b, MATCH_C_ZEXT_B, MASK_C_ZEXT_B) +DECLARE_INSN(c_zext_h, MATCH_C_ZEXT_H, MASK_C_ZEXT_H) +DECLARE_INSN(c_zext_w, MATCH_C_ZEXT_W, MASK_C_ZEXT_W) +DECLARE_INSN(c_mul, MATCH_C_MUL, MASK_C_MUL) +DECLARE_INSN(c_not, MATCH_C_NOT, MASK_C_NOT) +DECLARE_INSN(c_lbu, MATCH_C_LBU, MASK_C_LBU) +DECLARE_INSN(c_lhu, MATCH_C_LHU, MASK_C_LHU) +DECLARE_INSN(c_lh, MATCH_C_LH, MASK_C_LH) +DECLARE_INSN(c_sb, MATCH_C_SB, MASK_C_SB) +DECLARE_INSN(c_sh, MATCH_C_SH, MASK_C_SH) /* Vendor-specific (T-Head) XTheadBa instructions. */ DECLARE_INSN(th_addsl, MATCH_TH_ADDSL, MASK_TH_ADDSL) /* Vendor-specific (T-Head) XTheadBb instructions. */ diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 739d6da..808f365 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -108,6 +108,10 @@ static inline unsigned int riscv_insn_length (insn_t insn) (RV_X(x, 20, 10)) #define EXTRACT_RVV_VC_IMM(x) \ (RV_X(x, 20, 11)) +#define EXTRACT_ZCB_BYTE_UIMM(x) \ + (RV_X(x, 6, 1) | (RV_X(x, 5, 1) << 1)) +#define EXTRACT_ZCB_HALFWORD_UIMM(x) \ + (RV_X(x, 5, 1) << 1) #define ENCODE_ITYPE_IMM(x) \ (RV_X(x, 0, 12) << 20) @@ -155,6 +159,10 @@ static inline unsigned int riscv_insn_length (insn_t insn) (RV_X(x, 0, 11) << 20) #define ENCODE_RVV_VI_UIMM6(x) \ (RV_X(x, 0, 5) << 15 | RV_X(x, 5, 1) << 26) +#define ENCODE_ZCB_BYTE_UIMM(x) \ + ((RV_X(x, 0, 1) << 6) | (RV_X(x, 1, 1) << 5)) +#define ENCODE_ZCB_HALFWORD_UIMM(x) \ + (RV_X(x, 1, 1) << 5) #define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x)) #define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x)) @@ -180,6 +188,8 @@ static inline unsigned int riscv_insn_length (insn_t insn) #define VALID_CJTYPE_IMM(x) (EXTRACT_CJTYPE_IMM(ENCODE_CJTYPE_IMM(x)) == (x)) #define VALID_RVV_VB_IMM(x) (EXTRACT_RVV_VB_IMM(ENCODE_RVV_VB_IMM(x)) == (x)) #define VALID_RVV_VC_IMM(x) (EXTRACT_RVV_VC_IMM(ENCODE_RVV_VC_IMM(x)) == (x)) +#define VALID_ZCB_BYTE_UIMM(x) (EXTRACT_ZCB_BYTE_UIMM(ENCODE_ZCB_BYTE_UIMM(x)) == (x)) +#define VALID_ZCB_HALFWORD_UIMM(x) (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x)) #define RISCV_RTYPE(insn, rd, rs1, rs2) \ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2)) @@ -421,6 +431,10 @@ enum riscv_insn_class INSN_CLASS_ZVKNHA_OR_ZVKNHB, INSN_CLASS_ZVKSED, INSN_CLASS_ZVKSH, + INSN_CLASS_ZCB, + INSN_CLASS_ZCB_AND_ZBA, + INSN_CLASS_ZCB_AND_ZBB, + INSN_CLASS_ZCB_AND_ZMMUL, INSN_CLASS_SVINVAL, INSN_CLASS_ZICBOM, INSN_CLASS_ZICBOP, diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 827d9b6..2826248 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -614,6 +614,20 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info goto undefined_modifier; } break; + case 'c': /* Zcb extension 16 bits length instruction fields. */ + switch (*++oparg) + { + case 'b': + print (info->stream, dis_style_immediate, "%d", + (int)EXTRACT_ZCB_BYTE_UIMM (l)); + break; + case 'h': + print (info->stream, dis_style_immediate, "%d", + (int)EXTRACT_ZCB_HALFWORD_UIMM (l)); + break; + default: break; + } + break; default: goto undefined_modifier; } diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 533e3f4..6a85473 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -380,12 +380,14 @@ const struct riscv_opcode riscv_opcodes[] = {"mv", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS }, {"move", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, {"move", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS }, +{"zext.b", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, INSN_ALIAS }, {"zext.b", 0, INSN_CLASS_I, "d,s", MATCH_ANDI|ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS }, {"and", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, {"and", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, {"and", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, {"and", 0, INSN_CLASS_I, "d,s,t", MATCH_AND, MASK_AND, match_opcode, 0 }, {"and", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS }, +{"andi", 0, INSN_CLASS_ZCB, "Cs,Cw,Wcf",MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, INSN_ALIAS }, {"andi", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, {"andi", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 }, {"beqz", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH }, @@ -449,16 +451,20 @@ const struct riscv_opcode riscv_opcodes[] = {"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 }, {"lb", 0, INSN_CLASS_I, "d,A", 0, (int) M_LB, match_never, INSN_MACRO }, +{"lbu", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_LBU, MASK_C_LBU, match_opcode, INSN_ALIAS|INSN_DREF|INSN_1_BYTE }, {"lbu", 0, INSN_CLASS_I, "d,o(s)", MATCH_LBU, MASK_LBU, match_opcode, INSN_DREF|INSN_1_BYTE }, {"lbu", 0, INSN_CLASS_I, "d,A", 0, (int) M_LBU, match_never, INSN_MACRO }, +{"lh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LH, MASK_C_LH, match_opcode, INSN_ALIAS|INSN_DREF|INSN_2_BYTE }, {"lh", 0, INSN_CLASS_I, "d,o(s)", MATCH_LH, MASK_LH, match_opcode, INSN_DREF|INSN_2_BYTE }, {"lh", 0, INSN_CLASS_I, "d,A", 0, (int) M_LH, match_never, INSN_MACRO }, +{"lhu", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LHU, MASK_C_LHU, match_opcode, INSN_ALIAS|INSN_DREF|INSN_2_BYTE }, {"lhu", 0, INSN_CLASS_I, "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, INSN_DREF|INSN_2_BYTE }, {"lhu", 0, INSN_CLASS_I, "d,A", 0, (int) M_LHU, match_never, INSN_MACRO }, {"lw", 0, INSN_CLASS_C, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_4_BYTE }, {"lw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE }, {"lw", 0, INSN_CLASS_I, "d,o(s)", MATCH_LW, MASK_LW, match_opcode, INSN_DREF|INSN_4_BYTE }, {"lw", 0, INSN_CLASS_I, "d,A", 0, (int) M_LW, match_never, INSN_MACRO }, +{"not", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_NOT, MASK_C_NOT, match_opcode, INSN_ALIAS }, {"not", 0, INSN_CLASS_I, "d,s", MATCH_XORI|MASK_IMM, MASK_XORI|MASK_IMM, match_opcode, INSN_ALIAS }, {"or", 0, INSN_CLASS_I, "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS }, {"or", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS }, @@ -478,8 +484,10 @@ const struct riscv_opcode riscv_opcodes[] = {"sltu", 0, INSN_CLASS_I, "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, INSN_ALIAS }, {"sgt", 0, INSN_CLASS_I, "d,t,s", MATCH_SLT, MASK_SLT, match_opcode, INSN_ALIAS }, {"sgtu", 0, INSN_CLASS_I, "d,t,s", MATCH_SLTU, MASK_SLTU, match_opcode, INSN_ALIAS }, +{"sb", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_SB, MASK_C_SB, match_opcode, INSN_DREF|INSN_1_BYTE|INSN_ALIAS }, {"sb", 0, INSN_CLASS_I, "t,q(s)", MATCH_SB, MASK_SB, match_opcode, INSN_DREF|INSN_1_BYTE }, {"sb", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SB, match_never, INSN_MACRO }, +{"sh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_SH, MASK_C_SH, match_opcode, INSN_DREF|INSN_2_BYTE|INSN_ALIAS }, {"sh", 0, INSN_CLASS_I, "t,q(s)", MATCH_SH, MASK_SH, match_opcode, INSN_DREF|INSN_2_BYTE }, {"sh", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SH, match_never, INSN_MACRO }, {"sw", 0, INSN_CLASS_C, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE }, @@ -626,6 +634,7 @@ const struct riscv_opcode riscv_opcodes[] = {"amominu.d.aqrl", 64, INSN_CLASS_A, "d,t,0(s)", MATCH_AMOMINU_D|MASK_AQRL, MASK_AMOMINU_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE }, /* Multiply/Divide instruction subset. */ +{"mul", 0, INSN_CLASS_ZCB_AND_ZMMUL, "Cs,Cw,Ct", MATCH_C_MUL, MASK_C_MUL, match_opcode, INSN_ALIAS }, {"mul", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, 0 }, {"mulh", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, 0 }, {"mulhu", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, 0 }, @@ -1016,10 +1025,13 @@ const struct riscv_opcode riscv_opcodes[] = {"max", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MAX, MASK_MAX, match_opcode, 0 }, {"minu", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MINU, MASK_MINU, match_opcode, 0 }, {"maxu", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MAXU, MASK_MAXU, match_opcode, 0 }, +{"sext.b", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_SEXT_B, MASK_C_SEXT_B, match_opcode, INSN_ALIAS }, {"sext.b", 0, INSN_CLASS_ZBB, "d,s", MATCH_SEXT_B, MASK_SEXT_B, match_opcode, 0 }, {"sext.b", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTB, match_never, INSN_MACRO }, +{"sext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_SEXT_H, MASK_C_SEXT_H, match_opcode, INSN_ALIAS }, {"sext.h", 0, INSN_CLASS_ZBB, "d,s", MATCH_SEXT_H, MASK_SEXT_H, match_opcode, 0 }, {"sext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTH, match_never, INSN_MACRO }, +{"zext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_ZEXT_H, MASK_C_ZEXT_H, match_opcode, INSN_ALIAS }, {"zext.h", 32, INSN_CLASS_ZBB, "d,s", MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, 0 }, {"zext.h", 64, INSN_CLASS_ZBB, "d,s", MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, 0 }, {"zext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTH, match_never, INSN_MACRO }, @@ -1055,6 +1067,7 @@ const struct riscv_opcode riscv_opcodes[] = {"sh1add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH1ADD_UW, MASK_SH1ADD_UW, match_opcode, 0 }, {"sh2add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH2ADD_UW, MASK_SH2ADD_UW, match_opcode, 0 }, {"sh3add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH3ADD_UW, MASK_SH3ADD_UW, match_opcode, 0 }, +{"zext.w", 64, INSN_CLASS_ZCB_AND_ZBA, "Cs,Cw", MATCH_C_ZEXT_W, MASK_C_ZEXT_W, match_opcode, INSN_ALIAS }, {"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 }, @@ -1939,6 +1952,21 @@ const struct riscv_opcode riscv_opcodes[] = {"vsm3c.vi", 0, INSN_CLASS_ZVKSH, "Vd,Vt,Vj", MATCH_VSM3C_VI, MASK_VSM3C_VI, match_opcode, 0}, {"vsm3me.vv", 0, INSN_CLASS_ZVKSH, "Vd,Vt,Vs", MATCH_VSM3ME_VV, MASK_VSM3ME_VV, match_opcode, 0}, +/* ZCB instructions. */ +{"c.lbu", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_LBU, MASK_C_LBU, match_opcode, INSN_DREF|INSN_1_BYTE }, +{"c.lhu", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LHU, MASK_C_LHU, match_opcode, INSN_DREF|INSN_2_BYTE }, +{"c.lh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LH, MASK_C_LH, match_opcode, INSN_DREF|INSN_2_BYTE }, +{"c.sb", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_SB, MASK_C_SB, match_opcode, INSN_DREF|INSN_1_BYTE }, +{"c.sh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_SH, MASK_C_SH, match_opcode, INSN_DREF|INSN_2_BYTE }, +{"c.not", 0, INSN_CLASS_ZCB, "Cs", MATCH_C_NOT, MASK_C_NOT, match_opcode, 0 }, +{"c.mul", 0, INSN_CLASS_ZCB_AND_ZMMUL, "Cs,Ct", MATCH_C_MUL, MASK_C_MUL, match_opcode, 0 }, +{"c.sext.b", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_SEXT_B, MASK_C_SEXT_B, match_opcode, 0 }, +{"c.sext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_SEXT_H, MASK_C_SEXT_H, match_opcode, 0 }, +{"c.zext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_ZEXT_H, MASK_C_ZEXT_H, match_opcode, 0 }, +{"c.zext.w", 64, INSN_CLASS_ZCB_AND_ZBA, "Cs", MATCH_C_ZEXT_W, MASK_C_ZEXT_W, match_opcode, 0 }, +{"c.zext.b", 0, INSN_CLASS_ZCB, "Cs", MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, 0 }, +{"c.sext.w", 64, INSN_CLASS_ZCB, "d", MATCH_C_ADDIW, MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, + /* Supervisor instructions. */ {"csrr", 0, INSN_CLASS_ZICSR, "d,E", MATCH_CSRRS, MASK_CSRRS|MASK_RS1, match_opcode, INSN_ALIAS }, {"csrw", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRW, MASK_CSRRW|MASK_RD, match_opcode, INSN_ALIAS }, |