Skip to content

Commit 11d9ed4

Browse files
committed
RISC-V: Add 'Zicntr' and 'Zihpm' support with compatibility measures
This commit adds support for 'Zicntr' and 'Zihpm' extensions (version 2.0). However, because GNU Binutils handled those as a part of 'I' and there was a time when a ratified specification did split counters from the 'I' extension without separate extension names. To preserve maximum compatibility, this commit implements as follows: * For RISC-V ISA version 20191213 or less (all current non-draft ones), imply counter extensions from 'I' and DO NOT imply the 'Zicsr' extension from counter extensions. We also suppress outputting the existence of counter extensions unless the version number is explicitly specified. * For future ratified ISAs, leave two options (each require minor edits): * Continue previous behaviors or * DO NOT imply counter extensions from 'I'. DO imply the 'Zicsr' extension from counter extensions. DO NOT suppress outputting the existence of such counter extensions by having a known version number (version 2.0 or [though unlikely] later). Make small changes to the disassembler to keep compatibility when disassembling old files. bfd/ChangeLog: * elfxx-riscv.c (check_implicit_compat_counter_from_i): New function for counter compatibility from 'I' to counter extensions. (check_implicit_compat_counter_to_zicsr): New function for counter compatibility from counter extensions to the 'Zicsr' extension. (riscv_implicit_subsets): Add implications related to counter extensions with compatibility measures. (riscv_supported_std_z_ext): Add 'Zicntr' and 'Zihpm' extensions. But make version "unknown" to suppress outputting implicit dependencies on older ISAs. (riscv_parse_add_subset): Add "zicntr" and "zihpm" to exceptions to recognize on older ISAs if there's no version number. (riscv_multi_subset_supports): Add support for 'Zicntr'. (riscv_multi_subset_supports_ext): Likewise. gas/ChangeLog: * config/tc-riscv.c (enum riscv_csr_class): Add CSR classes for 'Zicntr' and 'Zihpm' extensions. (riscv_csr_address): Add handling for new CSR classes. * testsuite/gas/riscv/march-imply-i.s: Add 'Zicntr' instructions. include/ChangeLog: * opcode/riscv-opc.h: Change CSR classes for counter CSRs. * opcode/riscv.h (enum riscv_insn_class): Add INSN_CLASS_ZICNTR for 'Zicntr' pseudoinstructions. opcodes/ChangeLog: * riscv-opc.c (riscv_opcodes): Recategorize counter pseudoinstructions to the 'Zicntr' extension.
1 parent 2beec86 commit 11d9ed4

File tree

6 files changed

+233
-163
lines changed

6 files changed

+233
-163
lines changed

bfd/elfxx-riscv.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,13 +1099,41 @@ check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED,
10991099
&& subset->minor_version < 1));
11001100
}
11011101

1102+
/* Compatibility measure for counters (Zicntr and Zihpm):
1103+
Do or do not add the IMPLICIT only when the ISA version is
1104+
less than the border. */
1105+
1106+
static bool
1107+
check_implicit_compat_counter_from_i (riscv_parse_subset_t *rps,
1108+
const riscv_implicit_subset_t *implicit
1109+
ATTRIBUTE_UNUSED,
1110+
const riscv_subset_t *subset
1111+
ATTRIBUTE_UNUSED)
1112+
{
1113+
/* When rps->isa_spec is NULL, we don't need to care about implicit
1114+
extensions because the caller is the linker. */
1115+
return rps->isa_spec && *rps->isa_spec <= ISA_SPEC_CLASS_20191213;
1116+
}
1117+
1118+
static bool
1119+
check_implicit_compat_counter_to_zicsr (riscv_parse_subset_t *rps,
1120+
const riscv_implicit_subset_t
1121+
*implicit,
1122+
const riscv_subset_t *subset)
1123+
{
1124+
return (rps->isa_spec
1125+
&& !check_implicit_compat_counter_from_i (rps, implicit, subset));
1126+
}
1127+
11021128
/* All extension implications. */
11031129

11041130
static riscv_implicit_subset_t riscv_implicit_subsets[] =
11051131
{
11061132
{"e", "i", check_implicit_always},
11071133
{"i", "zicsr", check_implicit_for_i},
11081134
{"i", "zifencei", check_implicit_for_i},
1135+
{"i", "zicntr", check_implicit_compat_counter_from_i},
1136+
{"i", "zihpm", check_implicit_compat_counter_from_i},
11091137
{"g", "i", check_implicit_always},
11101138
{"g", "m", check_implicit_always},
11111139
{"g", "a", check_implicit_always},
@@ -1191,6 +1219,8 @@ static riscv_implicit_subset_t riscv_implicit_subsets[] =
11911219
{"zcf", "zca", check_implicit_always},
11921220
{"zcd", "zca", check_implicit_always},
11931221
{"zcb", "zca", check_implicit_always},
1222+
{"zicntr", "zicsr", check_implicit_compat_counter_to_zicsr},
1223+
{"zihpm", "zicsr", check_implicit_compat_counter_to_zicsr},
11941224
{"smaia", "ssaia", check_implicit_always},
11951225
{"smstateen", "ssstateen", check_implicit_always},
11961226
{"smepmp", "zicsr", check_implicit_always},
@@ -1258,12 +1288,20 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
12581288
{"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12591289
{"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12601290
{"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1291+
{"zicntr", ISA_SPEC_CLASS_2P2, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1292+
{"zicntr", ISA_SPEC_CLASS_20190608, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1293+
{"zicntr", ISA_SPEC_CLASS_20191213, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1294+
{"zicntr", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
12611295
{"zicond", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12621296
{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
12631297
{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
12641298
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
12651299
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
12661300
{"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
1301+
{"zihpm", ISA_SPEC_CLASS_2P2, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1302+
{"zihpm", ISA_SPEC_CLASS_20190608, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1303+
{"zihpm", ISA_SPEC_CLASS_20191213, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1304+
{"zihpm", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
12671305
{"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12681306
{"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12691307
{"zfa", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 },
@@ -1682,9 +1720,12 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
16821720
rps->error_handler
16831721
(_("x ISA extension `%s' must be set with the versions"),
16841722
subset);
1685-
/* Allow old ISA spec can recognize zicsr and zifencei. */
1723+
/* Allow old ISA spec (version 2.2) can recognize extensions
1724+
effectively split from the base 'I' extension version 2.0. */
16861725
else if (strcmp (subset, "zicsr") != 0
1687-
&& strcmp (subset, "zifencei") != 0)
1726+
&& strcmp (subset, "zifencei") != 0
1727+
&& strcmp (subset, "zicntr") != 0
1728+
&& strcmp (subset, "zihpm") != 0)
16881729
rps->error_handler
16891730
(_("cannot find default versions of the ISA extension `%s'"),
16901731
subset);
@@ -2394,6 +2435,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
23942435
return riscv_subset_supports (rps, "zicbop");
23952436
case INSN_CLASS_ZICBOZ:
23962437
return riscv_subset_supports (rps, "zicboz");
2438+
case INSN_CLASS_ZICNTR:
2439+
return riscv_subset_supports (rps, "zicntr");
23972440
case INSN_CLASS_ZICOND:
23982441
return riscv_subset_supports (rps, "zicond");
23992442
case INSN_CLASS_ZICSR:
@@ -2587,6 +2630,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
25872630
return "zicbop";
25882631
case INSN_CLASS_ZICBOZ:
25892632
return "zicboz";
2633+
case INSN_CLASS_ZICNTR:
2634+
return "zicntr";
25902635
case INSN_CLASS_ZICOND:
25912636
return "zicond";
25922637
case INSN_CLASS_ZICSR:

gas/config/tc-riscv.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ enum riscv_csr_class
6666

6767
CSR_CLASS_I,
6868
CSR_CLASS_I_32, /* rv32 only */
69+
CSR_CLASS_ZICNTR, /* basic hardware perf counter */
70+
CSR_CLASS_ZICNTR_32, /* basic hardware perf counter, rv32 only */
71+
CSR_CLASS_ZIHPM, /* additional hardware perf counter */
72+
CSR_CLASS_ZIHPM_32, /* additional hardware perf counter, rv32 only */
6973
CSR_CLASS_F, /* f-ext only */
7074
CSR_CLASS_ZKR, /* zkr only */
7175
CSR_CLASS_V, /* rvv only */
@@ -1031,6 +1035,18 @@ riscv_csr_address (const char *csr_name,
10311035
need_check_version = true;
10321036
extension = "i";
10331037
break;
1038+
case CSR_CLASS_ZICNTR_32:
1039+
is_rv32_only = true;
1040+
/* Fall through. */
1041+
case CSR_CLASS_ZICNTR:
1042+
extension = "zicntr";
1043+
break;
1044+
case CSR_CLASS_ZIHPM_32:
1045+
is_rv32_only = true;
1046+
/* Fall through. */
1047+
case CSR_CLASS_ZIHPM:
1048+
extension = "zihpm";
1049+
break;
10341050
case CSR_CLASS_H_32:
10351051
is_rv32_only = true;
10361052
/* Fall through. */

gas/testsuite/gas/riscv/march-imply-i.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,11 @@ target:
2222

2323
# zifencei
2424
fence.i
25+
26+
# zicntr
27+
rdcycle t0
28+
rdtime t0
29+
rdinstret t0
30+
rdcycleh t0
31+
rdtimeh t0
32+
rdinstreth t0

0 commit comments

Comments
 (0)