Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension: Zicntr and Zihpm #102

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
52 changes: 47 additions & 5 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,8 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"e", "i", check_implicit_always},
{"i", "zicsr", check_implicit_for_i},
{"i", "zifencei", check_implicit_for_i},
{"i", "zicntr", check_implicit_for_i},
{"i", "zihpm", check_implicit_for_i},
{"g", "i", check_implicit_always},
{"g", "m", check_implicit_always},
{"g", "a", check_implicit_always},
Expand Down Expand Up @@ -1148,6 +1150,8 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zhinx", "zhinxmin", check_implicit_always},
{"zhinxmin", "zfinx", check_implicit_always},
{"zfinx", "zicsr", check_implicit_always},
{"zicntr", "zicsr", check_implicit_always},
{"zihpm", "zicsr", check_implicit_always},
{"zk", "zkn", check_implicit_always},
{"zk", "zkr", check_implicit_always},
{"zk", "zkt", check_implicit_always},
Expand Down Expand Up @@ -1251,13 +1255,17 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicntr", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
{"zicond", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
{"zicsr", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
{"zihintntl", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
{"zihpm", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
{"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zfa", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 },
Expand Down Expand Up @@ -1649,6 +1657,18 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
}
}

/* Check if the subset is one of the extensions split from
the 'I' extension version 2.0. */

static bool
riscv_is_subset_of_i_2p0 (const char *subset)
{
return (strcmp (subset, "zicsr") == 0
|| strcmp (subset, "zifencei") == 0
|| strcmp (subset, "zicntr") == 0
|| strcmp (subset, "zihpm") == 0);
}

/* Find the default versions for the extension before adding them to
the subset list, if their versions are RISCV_UNKNOWN_VERSION.
Afterwards, report errors if we can not find their default versions. */
Expand All @@ -1662,9 +1682,26 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
{
int major_version = major;
int minor_version = minor;
bool handle_subset_of_i_2p0 = false;

/* If a subset of the 'I' extension version 2.0 is being added,
check the version of 'I' and allow its version unknown when the
'I' extension version is less than 2.1.
Draft 'E' is arbitrarily handled since it's a draft but the default
handling is the same as 'I' >= 2.1 because non-draft 'E' extension
does not have 'I' version 2.0 subsets. */
if (riscv_is_subset_of_i_2p0 (subset))
{
riscv_subset_t *ext_i;
if (riscv_lookup_subset (rps->subset_list, "i", &ext_i)
&& (ext_i->major_version < 2
|| (ext_i->major_version == 2 && ext_i->minor_version < 1)))
handle_subset_of_i_2p0 = true;
}

if (major_version == RISCV_UNKNOWN_VERSION
|| minor_version == RISCV_UNKNOWN_VERSION)
if (!handle_subset_of_i_2p0
&& (major_version == RISCV_UNKNOWN_VERSION
|| minor_version == RISCV_UNKNOWN_VERSION))
riscv_get_default_ext_version (rps->isa_spec, subset,
&major_version, &minor_version);

Expand All @@ -1677,9 +1714,9 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
rps->error_handler
(_("x ISA extension `%s' must be set with the versions"),
subset);
/* Allow old ISA spec can recognize zicsr and zifencei. */
else if (strcmp (subset, "zicsr") != 0
&& strcmp (subset, "zifencei") != 0)
/* Allow old ISA spec (version 2.2) can recognize extensions
effectively split from the base 'I' extension version 2.0. */
else if (!riscv_is_subset_of_i_2p0 (subset))
rps->error_handler
(_("cannot find default versions of the ISA extension `%s'"),
subset);
Expand Down Expand Up @@ -2389,6 +2426,9 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "zicbop");
case INSN_CLASS_ZICBOZ:
return riscv_subset_supports (rps, "zicboz");
case INSN_CLASS_ZICNTR:
/* Instead of 'Zicntr', query for 'I' for compatibility. */
return riscv_subset_supports (rps, "i");
case INSN_CLASS_ZICOND:
return riscv_subset_supports (rps, "zicond");
case INSN_CLASS_ZICSR:
Expand Down Expand Up @@ -2592,6 +2632,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zicbop";
case INSN_CLASS_ZICBOZ:
return "zicboz";
case INSN_CLASS_ZICNTR:
return "zicntr";
case INSN_CLASS_ZICOND:
return "zicond";
case INSN_CLASS_ZICSR:
Expand Down
25 changes: 25 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ enum riscv_csr_class

CSR_CLASS_I,
CSR_CLASS_I_32, /* rv32 only */
CSR_CLASS_ZICNTR, /* basic hardware perf counter */
CSR_CLASS_ZICNTR_32, /* basic hardware perf counter, rv32 only */
CSR_CLASS_ZIHPM, /* additional hardware perf counter */
CSR_CLASS_ZIHPM_32, /* additional hardware perf counter, rv32 only */
CSR_CLASS_F, /* f-ext only */
CSR_CLASS_ZKR, /* zkr only */
CSR_CLASS_V, /* rvv only */
Expand Down Expand Up @@ -1033,6 +1037,18 @@ riscv_csr_address (const char *csr_name,
need_check_version = true;
extension = "i";
break;
case CSR_CLASS_ZICNTR_32:
is_rv32_only = true;
/* Fall through. */
case CSR_CLASS_ZICNTR:
extension = "zicntr";
break;
case CSR_CLASS_ZIHPM_32:
is_rv32_only = true;
/* Fall through. */
case CSR_CLASS_ZIHPM:
extension = "zihpm";
break;
case CSR_CLASS_H_32:
is_rv32_only = true;
/* Fall through. */
Expand Down Expand Up @@ -2611,6 +2627,15 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
insn_with_csr = false;
}

/* Check if we are using a 'Zicntr' pseudoinstruction
without the 'Zicntr' extension. */
if (insn->insn_class == INSN_CLASS_ZICNTR
&& !riscv_subset_supports (&riscv_rps_as, "zicntr"))
{
as_warn (_("`%s' needs `zicntr' extension"),
insn->name);
}

/* The (segmant) load and store with EEW 64 cannot be used
when zve32x is enabled. */
if (ip->insn_mo->pinfo & INSN_V_EEW64
Expand Down
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/csr-insns-pseudo-noalias.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#source: csr-insns-pseudo.s
#as: -march=rv32if
#as: -march=rv32if_zicntr
#objdump: -dr -Mno-aliases

.*:[ ]+file format .*
Expand Down
37 changes: 37 additions & 0 deletions gas/testsuite/gas/riscv/csr-insns-pseudo-nozicntr.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#source: csr-insns-pseudo.s
#as: -march=rv32i2p1_f2p2
#warning_output: csr-insns-pseudo-nozicntr.l
#objdump: -dr

.*:[ ]+file format .*


Disassembly of section .text:

0+000 <pseudo_csr_insn>:
[ ]+[0-9a-f]+:[ ]+000022f3[ ]+csrr[ ]+t0,ustatus
[ ]+[0-9a-f]+:[ ]+00029073[ ]+csrw[ ]+ustatus,t0
[ ]+[0-9a-f]+:[ ]+0002a073[ ]+csrs[ ]+ustatus,t0
[ ]+[0-9a-f]+:[ ]+0002b073[ ]+csrc[ ]+ustatus,t0
[ ]+[0-9a-f]+:[ ]+000fd073[ ]+csrwi[ ]+ustatus,31
[ ]+[0-9a-f]+:[ ]+000fe073[ ]+csrsi[ ]+ustatus,31
[ ]+[0-9a-f]+:[ ]+000ff073[ ]+csrci[ ]+ustatus,31
[ ]+[0-9a-f]+:[ ]+c00022f3[ ]+rdcycle[ ]+t0
[ ]+[0-9a-f]+:[ ]+c01022f3[ ]+rdtime[ ]+t0
[ ]+[0-9a-f]+:[ ]+c02022f3[ ]+rdinstret[ ]+t0
[ ]+[0-9a-f]+:[ ]+c80022f3[ ]+rdcycleh[ ]+t0
[ ]+[0-9a-f]+:[ ]+c81022f3[ ]+rdtimeh[ ]+t0
[ ]+[0-9a-f]+:[ ]+c82022f3[ ]+rdinstreth[ ]+t0
[ ]+[0-9a-f]+:[ ]+003022f3[ ]+frcsr[ ]+t0
[ ]+[0-9a-f]+:[ ]+003392f3[ ]+fscsr[ ]+t0,t2
[ ]+[0-9a-f]+:[ ]+00339073[ ]+fscsr[ ]+t2
[ ]+[0-9a-f]+:[ ]+002022f3[ ]+frrm[ ]+t0
[ ]+[0-9a-f]+:[ ]+002312f3[ ]+fsrm[ ]+t0,t1
[ ]+[0-9a-f]+:[ ]+00231073[ ]+fsrm[ ]+t1
[ ]+[0-9a-f]+:[ ]+002fd2f3[ ]+fsrmi[ ]+t0,31
[ ]+[0-9a-f]+:[ ]+002fd073[ ]+fsrmi[ ]+zero,31
[ ]+[0-9a-f]+:[ ]+001022f3[ ]+frflags[ ]+t0
[ ]+[0-9a-f]+:[ ]+001312f3[ ]+fsflags[ ]+t0,t1
[ ]+[0-9a-f]+:[ ]+00131073[ ]+fsflags[ ]+t1
[ ]+[0-9a-f]+:[ ]+001fd2f3[ ]+fsflagsi[ ]+t0,31
[ ]+[0-9a-f]+:[ ]+001fd073[ ]+fsflagsi[ ]+zero,31
7 changes: 7 additions & 0 deletions gas/testsuite/gas/riscv/csr-insns-pseudo-nozicntr.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.*Assembler messages:
.*Warning: `rdcycle' needs `zicntr' extension
.*Warning: `rdtime' needs `zicntr' extension
.*Warning: `rdinstret' needs `zicntr' extension
.*Warning: `rdcycleh' needs `zicntr' extension
.*Warning: `rdtimeh' needs `zicntr' extension
.*Warning: `rdinstreth' needs `zicntr' extension
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/csr-insns-pseudo-zfinx.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#source: csr-insns-pseudo.s
#as: -march=rv32i_zfinx
#as: -march=rv32i_zicntr_zfinx
#objdump: -dr

.*:[ ]+file format .*
Expand Down
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/csr-insns-pseudo.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#source: csr-insns-pseudo.s
#as: -march=rv32if
#as: -march=rv32if_zicntr
#objdump: -dr

.*:[ ]+file format .*
Expand Down
3 changes: 2 additions & 1 deletion gas/testsuite/gas/riscv/csr-insns-pseudo.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ pseudo_csr_insn:
csrsi 0x0, 31
csrci 0x0, 31

# Zicntr
rdcycle t0
rdtime t0
rdinstret t0

# rv32i-ext
# Zicntr (RV32)
rdcycleh t0
rdtimeh t0
rdinstreth t0
Expand Down
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/csr-insns-read-only.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#as: -march=rv32if -mcsr-check -mpriv-spec=1.11
#as: -march=rv32if_zicntr -mcsr-check -mpriv-spec=1.11
#source: csr-insns-read-only.s
#warning_output: csr-insns-read-only.l
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/csr-version-1p10.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#as: -march=rv64i_zicsr -mcsr-check -mpriv-spec=1.10
#as: -march=rv64i2p1_zicsr2p0 -mcsr-check -mpriv-spec=1.10
#source: csr.s
#warning_output: csr-version-1p10.l
#objdump: -dr -Mpriv-spec=1.10
Expand Down
Loading