From 3212936b74e0a58d1003e19585d496b84f75a763 Mon Sep 17 00:00:00 2001 From: dysun Date: Tue, 18 Jun 2024 15:39:08 +0800 Subject: [PATCH] Add zilsd & zcmlsd new instruction --- bfd/elfxx-riscv.c | 23 ++++++++++++++++++++++- gas/config/tc-riscv.c | 36 ++++++++++++++++++++++++++++++++++++ include/opcode/riscv.h | 2 ++ opcodes/riscv-dis.c | 18 ++++++++++++++++++ opcodes/riscv-opc.c | 12 ++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index dfacb87eda0..0e7ac264f04 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1282,7 +1282,8 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"b", "zbs", check_implicit_always}, {"a", "zaamo", check_implicit_always}, {"a", "zalrsc", check_implicit_always}, - + {"zcmlsd", "zilsd", check_implicit_always}, + {"zcmlsd", "zca", check_implicit_always}, {"xsfvcp", "zve32x", check_implicit_always}, {NULL, NULL, NULL} }; @@ -1425,6 +1426,8 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zilsd", ISA_SPEC_CLASS_DRAFT, 0, 81, 0 }, + {"zcmlsd", ISA_SPEC_CLASS_DRAFT, 0, 81, 0 }, {NULL, 0, 0, 0, 0} }; @@ -2094,6 +2097,16 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps) (_("`xtheadvector' is conflict with the `v' extension")); no_conflict = false; } + //Add zcmlsd conflicts + if (riscv_lookup_subset (rps->subset_list, "zcmlsd", &subset) + && ((riscv_lookup_subset (rps->subset_list, "c", &subset) + && riscv_lookup_subset (rps->subset_list, "f", &subset)) + || riscv_lookup_subset (rps->subset_list, "zcf", &subset))) + { + rps->error_handler + (_("`zcmlsd' is conflict with the `c+f'/ `zcf' extension")); + no_conflict = false; + } bool support_zve = false; bool support_zvl = false; @@ -2706,6 +2719,10 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "xventanacondops"); case INSN_CLASS_XSFVCP: return riscv_subset_supports (rps, "xsfvcp"); + case INSN_CLASS_ZILSD: + return riscv_subset_supports(rps, "zilsd"); + case INSN_CLASS_ZCMLSD: + return riscv_subset_supports(rps, "zcmlsd"); default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); @@ -2960,6 +2977,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "xtheadvector"; case INSN_CLASS_XTHEADZVAMO: return "xtheadzvamo"; + case INSN_CLASS_ZILSD: + return "zilsd"; + case INSN_CLASS_ZCMLSD: + return "zcmlsd"; default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 8d749581c1d..838550d4332 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1692,6 +1692,15 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) goto unknown_validate_operand; } break; + case 'G': /* Zilsd operand */ + switch (*++oparg) + { + case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break; + case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break; + default: + goto unknown_validate_operand; + } + break; default: unknown_validate_operand: as_bad (_("internal: bad RISC-V opcode " @@ -4016,6 +4025,33 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, } break; + case 'G': /* Zilsd ld,sd specific operands. */ + switch(*++oparg) + { + case 'd': + case 't': + if (reg_lookup (&asarg, RCLASS_GPR, ®no)&&(regno%2==0)) + { + char c = *oparg; + if (*asarg == ' ') + ++asarg; + + /* Now that we have assembled one operand, we use the args + string to figure out where it goes in the instruction. */ + switch (c) + { + case 'd': + INSERT_OPERAND (RD, *ip, regno); + break; + case 't': + INSERT_OPERAND (RS2, *ip, regno); + break; + } + continue; + } + } + break; + default: unknown_riscv_ip_operand: as_fatal (_("internal: unknown argument type `%s'"), diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 5f516a1026e..accc28ff784 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -505,6 +505,8 @@ enum riscv_insn_class INSN_CLASS_XTHEADZVAMO, INSN_CLASS_XVENTANACONDOPS, INSN_CLASS_XSFVCP, + INSN_CLASS_ZILSD, + INSN_CLASS_ZCMLSD, }; /* This structure holds information for a particular instruction. */ diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index e6596c47423..ae27bfa72f8 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -806,6 +806,24 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info goto undefined_modifier; } break; + case 'G': /* Zilsd ld,sd specific operands. */ + switch (*++oparg) + { + case 'd': + if ((l & MASK_AUIPC) == MATCH_AUIPC) + pd->hi_addr[rd] = pc + EXTRACT_UTYPE_IMM (l); + else if ((l & MASK_LUI) == MATCH_LUI) + pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l); + else if ((l & MASK_C_LUI) == MATCH_C_LUI) + pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l); + print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]); + break; + case 't': + print (info->stream, dis_style_register, "%s", + riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]); + break; + } + break; default: undefined_modifier: diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 1ef4eaddf4d..3e11a316cef 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -554,10 +554,18 @@ const struct riscv_opcode riscv_opcodes[] = {"xor", 0, INSN_CLASS_I, "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, 0 }, {"lwu", 64, INSN_CLASS_I, "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, INSN_DREF|INSN_4_BYTE }, {"lwu", 64, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO }, +{"ld", 32, INSN_CLASS_ZCMLSD, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, +{"ld", 32, INSN_CLASS_ZCMLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, +{"ld", 32, INSN_CLASS_ZILSD, "Gd,o(s)", MATCH_LD, MASK_LD, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"ld", 32, INSN_CLASS_ZILSD, "Gd,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO }, {"ld", 64, INSN_CLASS_C, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, {"ld", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, {"ld", 64, INSN_CLASS_I, "d,o(s)", MATCH_LD, MASK_LD, match_opcode, INSN_DREF|INSN_8_BYTE }, {"ld", 64, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO }, +{"sd", 32, INSN_CLASS_ZCMLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, +{"sd", 32, INSN_CLASS_ZCMLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, +{"sd", 32, INSN_CLASS_ZILSD, "Gt,q(s)", MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"sd", 32, INSN_CLASS_ZILSD, "Gt,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO }, {"sd", 64, INSN_CLASS_C, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, {"sd", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, {"sd", 64, INSN_CLASS_I, "t,q(s)", MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE }, @@ -1062,9 +1070,13 @@ const struct riscv_opcode riscv_opcodes[] = {"c.addiw", 64, INSN_CLASS_C, "d,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 }, {"c.addw", 64, INSN_CLASS_C, "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 }, {"c.subw", 64, INSN_CLASS_C, "Cs,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 }, +{"c.ldsp", 32, INSN_CLASS_ZCMLSD, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE }, {"c.ldsp", 64, INSN_CLASS_C, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE }, +{"c.ld", 32, INSN_CLASS_ZCMLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE }, {"c.ld", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"c.sdsp", 32, INSN_CLASS_ZCMLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE }, {"c.sdsp", 64, INSN_CLASS_C, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"c.sd", 32, INSN_CLASS_ZCMLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_DREF|INSN_8_BYTE }, {"c.sd", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_DREF|INSN_8_BYTE }, {"c.fldsp", 0, INSN_CLASS_D_AND_C, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_DREF|INSN_8_BYTE }, {"c.fld", 0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_DREF|INSN_8_BYTE },