Skip to content

Commit f3c2a5c

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 e4d4e27 commit f3c2a5c

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
{"smcntrpmf", "zicsr", check_implicit_always},
11961226
{"smstateen", "ssstateen", check_implicit_always},
@@ -1260,13 +1290,21 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
12601290
{"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12611291
{"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12621292
{"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1293+
{"zicntr", ISA_SPEC_CLASS_2P2, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1294+
{"zicntr", ISA_SPEC_CLASS_20190608, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1295+
{"zicntr", ISA_SPEC_CLASS_20191213, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1296+
{"zicntr", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
12631297
{"zicond", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12641298
{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
12651299
{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
12661300
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
12671301
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
12681302
{"zihintntl", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12691303
{"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
1304+
{"zihpm", ISA_SPEC_CLASS_2P2, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1305+
{"zihpm", ISA_SPEC_CLASS_20190608, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1306+
{"zihpm", ISA_SPEC_CLASS_20191213, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, /* Compat. */
1307+
{"zihpm", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
12701308
{"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12711309
{"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
12721310
{"zfa", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 },
@@ -1686,9 +1724,12 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
16861724
rps->error_handler
16871725
(_("x ISA extension `%s' must be set with the versions"),
16881726
subset);
1689-
/* Allow old ISA spec can recognize zicsr and zifencei. */
1727+
/* Allow old ISA spec (version 2.2) can recognize extensions
1728+
effectively split from the base 'I' extension version 2.0. */
16901729
else if (strcmp (subset, "zicsr") != 0
1691-
&& strcmp (subset, "zifencei") != 0)
1730+
&& strcmp (subset, "zifencei") != 0
1731+
&& strcmp (subset, "zicntr") != 0
1732+
&& strcmp (subset, "zihpm") != 0)
16921733
rps->error_handler
16931734
(_("cannot find default versions of the ISA extension `%s'"),
16941735
subset);
@@ -2398,6 +2439,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
23982439
return riscv_subset_supports (rps, "zicbop");
23992440
case INSN_CLASS_ZICBOZ:
24002441
return riscv_subset_supports (rps, "zicboz");
2442+
case INSN_CLASS_ZICNTR:
2443+
return riscv_subset_supports (rps, "zicntr");
24012444
case INSN_CLASS_ZICOND:
24022445
return riscv_subset_supports (rps, "zicond");
24032446
case INSN_CLASS_ZICSR:
@@ -2601,6 +2644,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
26012644
return "zicbop";
26022645
case INSN_CLASS_ZICBOZ:
26032646
return "zicboz";
2647+
case INSN_CLASS_ZICNTR:
2648+
return "zicntr";
26042649
case INSN_CLASS_ZICOND:
26052650
return "zicond";
26062651
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 */
@@ -1033,6 +1037,18 @@ riscv_csr_address (const char *csr_name,
10331037
need_check_version = true;
10341038
extension = "i";
10351039
break;
1040+
case CSR_CLASS_ZICNTR_32:
1041+
is_rv32_only = true;
1042+
/* Fall through. */
1043+
case CSR_CLASS_ZICNTR:
1044+
extension = "zicntr";
1045+
break;
1046+
case CSR_CLASS_ZIHPM_32:
1047+
is_rv32_only = true;
1048+
/* Fall through. */
1049+
case CSR_CLASS_ZIHPM:
1050+
extension = "zihpm";
1051+
break;
10361052
case CSR_CLASS_H_32:
10371053
is_rv32_only = true;
10381054
/* 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)