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
39 changes: 38 additions & 1 deletion bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,9 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"b", "zbs", check_implicit_always},
{"a", "zaamo", check_implicit_always},
{"a", "zalrsc", check_implicit_always},

{"zilsd", "zicsr", check_implicit_always},
{"zclsd", "zilsd", check_implicit_always},
{"zclsd", "zca", check_implicit_always},
{"xsfvcp", "zve32x", check_implicit_always},
{NULL, NULL, NULL}
};
Expand Down Expand Up @@ -1435,6 +1437,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, 1, 0, 0 },
{"zclsd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -2103,6 +2107,31 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
(_("`zfinx' is conflict with the `f/d/q/zfh/zfhmin' extension"));
no_conflict = false;
}
//Add zclsd conflicts
if (riscv_lookup_subset (rps->subset_list, "zclsd", &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
(_("`zclsd' is conflict with the `c+f'/ `zcf' extension"));
no_conflict = false;
}
if (riscv_lookup_subset (rps->subset_list, "zclsd", &subset)
&& xlen > 32)
{
rps->error_handler
(_("rv%d does not support the `zclsd' extension"), xlen);
no_conflict = false;
}
//Add zilsd conflicts
if (riscv_lookup_subset (rps->subset_list, "zilsd", &subset)
&& xlen > 32)
{
rps->error_handler
(_("rv%d does not support the `zilsd' extension"), xlen);
no_conflict = false;
}
if (riscv_lookup_subset (rps->subset_list, "xtheadvector", &subset)
&& riscv_lookup_subset (rps->subset_list, "v", &subset))
{
Expand Down Expand Up @@ -2738,6 +2767,10 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "xsfvcp");
case INSN_CLASS_XSFCEASE:
return riscv_subset_supports (rps, "xsfcease");
case INSN_CLASS_ZILSD:
return riscv_subset_supports(rps, "zilsd");
case INSN_CLASS_ZCLSD:
return riscv_subset_supports(rps, "zclsd");
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
Expand Down Expand Up @@ -3008,6 +3041,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "xtheadzvamo";
case INSN_CLASS_XSFCEASE:
return "xsfcease";
case INSN_CLASS_ZILSD:
return "zilsd";
case INSN_CLASS_ZCLSD:
return "zclsd";
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 @@ -1714,6 +1714,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 @@ -4048,6 +4057,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
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zclsd-01.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv64i_zca_zclsd
#source: empty.s
#error_output: march-fail-zclsd-01.l
2 changes: 2 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zclsd-01.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.*Assembler messages:
.*Error: .*rv64 does not support the `zclsd' extension
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zclsd-02.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i_zcf_zclsd
#source: empty.s
#error_output: march-fail-zclsd-02.l
2 changes: 2 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zclsd-02.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.*Assembler messages:
.*Error: .*`zclsd' is conflict with the `c+f'/ `zcf' extension
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zilsd.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv64i_zilsd
#source: empty.s
#error_output: march-fail-zilsd.l
2 changes: 2 additions & 0 deletions gas/testsuite/gas/riscv/march-fail-zilsd.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.*Assembler messages:
.*Error: .*rv64 does not support the `zilsd' extension
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/zclsd.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#as: -march=rv32g_zca_zilsd_zclsd
#source: zclsd.s
#objdump: -dr -Mno-aliases

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+7218[ ]+c.ld[ ]+a4,32\(a2\)
[ ]+[0-9a-f]+:[ ]+f218[ ]+c.sd[ ]+a4,32\(a2\)
[ ]+[0-9a-f]+:[ ]+6222[ ]+c.ldsp[ ]+tp,8\(sp\)
[ ]+[0-9a-f]+:[ ]+e412[ ]+c.sdsp[ ]+tp,8\(sp\)
6 changes: 6 additions & 0 deletions gas/testsuite/gas/riscv/zclsd.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+target:
c.ld a4, 32(a2)
c.sd a4, 32(a2)
c.ldsp x4, 8(x2)
c.sdsp x4, 8(x2)

11 changes: 11 additions & 0 deletions gas/testsuite/gas/riscv/zilsd.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#as: -march=rv64g_zilsd
#source: zilsd.s
#objdump: -dr

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00053503[ ]+ld[ ]+a0,0\(a0\)
[ ]+[0-9a-f]+:[ ]+00a53023[ ]+sd[ ]+a0,0\(a0\)
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/zilsd.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target:
ld a0, 0(a0)
sd a0, 0(a0)
2 changes: 2 additions & 0 deletions include/opcode/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ enum riscv_insn_class
INSN_CLASS_XVENTANACONDOPS,
INSN_CLASS_XSFVCP,
INSN_CLASS_XSFCEASE,
INSN_CLASS_ZILSD,
INSN_CLASS_ZCLSD,
};

/* 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 @@ -838,6 +838,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 @@ -562,10 +562,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_ZCLSD, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"ld", 32, INSN_CLASS_ZCLSD, "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_ZCLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"sd", 32, INSN_CLASS_ZCLSD, "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 @@ -1093,9 +1101,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_ZCLSD, "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_ZCLSD, "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_ZCLSD, "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_ZCLSD, "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