From b0a101c53a1caa3f2a9fc2032f703ca4465cfbbb Mon Sep 17 00:00:00 2001 From: Jiawei Date: Wed, 12 Jul 2023 20:40:36 +0800 Subject: [PATCH] RISC-V: Supports Zcb extension. This patch support Zcb extension, contains new compressed instructions, some instructions depend on other existed extension, like 'zba', 'zbb' and 'zmmul'. Zcb also imply Zca extension to enable the compressing features. Co-Authored by: Charlie Keaney Co-Authored by: Mary Bennett Co-Authored by: Nandni Jamnadas Co-Authored by: Sinan Lin Co-Authored by: Simon Cook Co-Authored by: Shihua Liao Co-Authored by: Yulong Shi bfd/ChangeLog: * elfxx-riscv.c (riscv_multi_subset_supports): New extension. (riscv_multi_subset_supports_ext): Ditto. gas/ChangeLog: * config/tc-riscv.c (validate_riscv_insn): New operators. (riscv_ip): Ditto. * testsuite/gas/riscv/zcb.d: New test. * testsuite/gas/riscv/zcb.s: New test. include/ChangeLog: * opcode/riscv-opc.h (MATCH_C_LBU): New opcode. (MASK_C_LBU): New mask. (MATCH_C_LHU): New opcode. (MASK_C_LHU): New mask. (MATCH_C_LH): New opcode. (MASK_C_LH): New mask. (MATCH_C_SB): New opcode. (MASK_C_SB): New mask. (MATCH_C_SH): New opcode. (MASK_C_SH): New mask. (MATCH_C_ZEXT_B): New opcode. (MASK_C_ZEXT_B): New mask. (MATCH_C_SEXT_B): New opcode. (MASK_C_SEXT_B): New mask. (MATCH_C_ZEXT_H): New opcode. (MASK_C_ZEXT_H): New mask. (MATCH_C_SEXT_H): New opcode. (MASK_C_SEXT_H): New mask. (MATCH_C_ZEXT_W): New opcode. (MASK_C_ZEXT_W): New mask. (MATCH_C_NOT): New opcode. (MASK_C_NOT): New mask. (MATCH_C_MUL): New opcode. (MASK_C_MUL): New mask. (DECLARE_INSN): New opcode. * opcode/riscv.h (EXTRACT_ZCB_BYTE_UIMM): New inline func. (EXTRACT_ZCB_HALFWORD_UIMM): Ditto. (ENCODE_ZCB_BYTE_UIMM): Ditto. (ENCODE_ZCB_HALFWORD_UIMM): Ditto. (VALID_ZCB_BYTE_UIMM): Ditto. (VALID_ZCB_HALFWORD_UIMM): Ditto. (enum riscv_insn_class): New extension class. opcodes/ChangeLog: * riscv-dis.c (print_insn_args): New operators. * riscv-opc.c: New instructions. --- bfd/elfxx-riscv.c | 21 ++++++++++++++ gas/config/tc-riscv.c | 53 +++++++++++++++++++++++++++++++++++ gas/testsuite/gas/riscv/zcb.d | 32 +++++++++++++++++++++ gas/testsuite/gas/riscv/zcb.s | 25 +++++++++++++++++ include/opcode/riscv-opc.h | 38 +++++++++++++++++++++++++ include/opcode/riscv.h | 14 +++++++++ opcodes/riscv-dis.c | 14 +++++++++ opcodes/riscv-opc.c | 28 ++++++++++++++++++ 8 files changed, 225 insertions(+) create mode 100644 gas/testsuite/gas/riscv/zcb.d create mode 100644 gas/testsuite/gas/riscv/zcb.s diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 86351872e04..ee96608358e 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 8c23c6abae7..80c14a3cd22 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 00000000000..26a122b205c --- /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 : +[ ]+[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 00000000000..2e70ab29c30 --- /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 90f44153750..53f5f200508 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 739d6dafae9..808f3657303 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 827d9b67437..2826248f8af 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 533e3f4a079..6a854736fec 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 }, -- 2.30.2