Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}
};
Expand Down Expand Up @@ -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}
};

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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_*"));
Expand Down Expand Up @@ -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_*"));
Expand Down
36 changes: 36 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down Expand Up @@ -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, &regno)&&(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'"),
Expand Down
2 changes: 2 additions & 0 deletions include/opcode/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
18 changes: 18 additions & 0 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
12 changes: 12 additions & 0 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down Expand Up @@ -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 },
Expand Down