[integration] RISC-V/SiFive: Added SiFive custom cache control instructions.
Nelson Chu
nelson.chu@sifive.com
Thu Oct 28 02:10:00 GMT 2021
Committed.
Thanks
Nelson
On Mon, Oct 25, 2021 at 10:23 AM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> Hi Guys,
>
> Ping. If there are no other concerns, I will commit this patch into
> the riscv integration branch recently.
>
> Thanks
> Nelson
>
> On Mon, Sep 27, 2021 at 4:30 PM Nelson Chu <nelson.chu@sifive.com> wrote:
> >
> > According to the chapter 10 of the following U74-MC manual,
> > https://sifive.cdn.prismic.io/sifive/6d9a2510-2632-44f3-adb9-d0430f139372_sifive_coreip_U74MC_AXI4_rtl_v19_08p2p0_release_manual.pdf
> >
> > and the implementations of freedom-metal,
> > https://github.com/sifive/freedom-metal/blob/v201908-branch/src/cache.c
> >
> > * Encodings,
> > 31-25 24-20 19-15 14-12 11-7 6-0
> > FUNCT7 RS2 RS1 FUNCT3 RD OPCODE
> > 1111110 00000 xxxxx 000 00000 1110011 CFLUSH.D.L1
> > 1111110 00010 xxxxx 000 00000 1110011 CDISCARD.D.L1
> > 1111110 00001 00000 000 00000 1110011 CFLUSH.I.L1
> >
> > * Extension names,
> > xsfcflushdlone: CFLUSH.D.L1.
> > xsfcdiscarddlone: CDISCARD.D.L1.
> > xsfcflushilone: CFLUSH.I.L1.
> >
> > * Vendor target triples,
> > For assembler, the target vendor is defined as TARGET_VENDOR in the
> > gas/config.h, but I don't see any related settings in bfd/config.h
> > and opcode/config. Since we may have vendor relocations in the future,
> > and these relocation numbers may repeat, I add a new RISCV_TARGET_VENDOR
> > in the bfd/config.h for riscv. The vendor name will be stored in the
> > bfd/cpu-riscv.c, so that all tools (gas, bfd, opcode, ...) can get
> > the vendor name from the configure setting.
> >
> > If the --with-arch configure option, -march gas option and elf architecture
> > attributes are not set, then we will generate the default ISA string
> > according to the chosen target vendor. For example, if you build the
> > binutils with the configure option, --target=riscv64-sifive-elf, then
> > the assembler will find the whole supported extension tables in the
> > bfd/elfxx-riscv.c, and generate the suitable ISA string.
> >
> > bfd/
> > * configure.ac (RISCV_TARGET_VENDOR): Defined to store target_vendor,
> > only when the target is riscv*.
> > * config.in: Regenerated.
> > * configure: Regenerated.
> > * cpu-riscv.c (riscv_vendor_name): Defined to RISCV_TARGET_VENDOR.
> > * cpu-riscv.h (enum riscv_spec_class): Added VENDOR_SPEC_CLASS_SIFIVE.
> > * elfxx-riscv. (EXT_SIFIVE): Defined to choose the default extensions
> > for sifive.
> > (riscv_supported_vendor_sifive_ext): Added extensions for sifive cache
> > control instructions.
> > (riscv_supported_std_ext, riscv_all_supported_ext): Updated.
> > (riscv_get_default_ext_version): Updated.
> > (riscv_set_default_arch): Updated.
> > gas/
> > * config/tc-riscv.c (VENDOR_SIFIVE_EXT): Added.
> > (riscv_extended_subset_supports): Handle INSN_CLASS_XSF*.
> > (op_vendor_sifive_hash): Added to store sifive opcodes.
> > (md_begin): Init the op_vendor_sifive_hash.
> > (riscv_find_extended_opcode_hash): Find the opcodes from
> > op_vendor_sifive_hash.
> > * testsuite/gas/riscv/extended/sifive-insns.d: New testcase.
> > * testsuite/gas/riscv/extended/sifive-insns.s: Likewise.
> > include/
> > * opcode/riscv-opc-extended.h: Added opcodes for sifive cache
> > instructions.
> > * opcode/riscv.h (enum riscv_extended_insn_class): Added INSN_CLASS_XSF*.
> > opcodes/
> > * riscv-opc.c (riscv_vendor_sifive_opcodes): Added.
> > (riscv_extended_opcodes): Updated.
> > ---
> > bfd/config.in | 3 ++
> > bfd/configure | 10 +++++++
> > bfd/configure.ac | 6 ++++
> > bfd/cpu-riscv.c | 2 ++
> > bfd/cpu-riscv.h | 5 ++++
> > bfd/elfxx-riscv.c | 28 ++++++++++++++++---
> > gas/config/tc-riscv.c | 18 +++++++++++-
> > .../gas/riscv/extended/sifive-insns.d | 12 ++++++++
> > .../gas/riscv/extended/sifive-insns.s | 4 +++
> > include/opcode/riscv-opc-extended.h | 11 ++++++++
> > include/opcode/riscv.h | 5 ++++
> > opcodes/riscv-opc.c | 14 ++++++++++
> > 12 files changed, 113 insertions(+), 5 deletions(-)
> > create mode 100644 gas/testsuite/gas/riscv/extended/sifive-insns.d
> > create mode 100644 gas/testsuite/gas/riscv/extended/sifive-insns.s
> >
> > diff --git a/bfd/config.in b/bfd/config.in
> > index f54a3cacbea..abd1385a185 100644
> > --- a/bfd/config.in
> > +++ b/bfd/config.in
> > @@ -257,6 +257,9 @@
> > /* Define to the version of this package. */
> > #undef PACKAGE_VERSION
> >
> > +/* RISCV target vendor. */
> > +#undef RISCV_TARGET_VENDOR
> > +
> > /* The size of `int', as computed by sizeof. */
> > #undef SIZEOF_INT
> >
> > diff --git a/bfd/configure b/bfd/configure
> > index cae69d413d4..5670a62b095 100755
> > --- a/bfd/configure
> > +++ b/bfd/configure
> > @@ -13655,6 +13655,16 @@ test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selar
> >
> >
> >
> > +case "${target_cpu}" in
> > + riscv*)
> > +
> > +cat >>confdefs.h <<_ACEOF
> > +#define RISCV_TARGET_VENDOR "${target_vendor}"
> > +_ACEOF
> > +
> > + ;;
> > +esac
> > +
> > # If we are configured native, pick a core file support file.
> > COREFILE=
> > COREFLAG=
> > diff --git a/bfd/configure.ac b/bfd/configure.ac
> > index 9ff303ab6e1..ace0b65a631 100644
> > --- a/bfd/configure.ac
> > +++ b/bfd/configure.ac
> > @@ -820,6 +820,12 @@ AC_SUBST(bfd_default_target_size)
> > AC_SUBST(tdefaults)
> > AC_SUBST(havevecs)
> >
> > +case "${target_cpu}" in
> > + riscv*)
> > + AC_DEFINE_UNQUOTED(RISCV_TARGET_VENDOR, "${target_vendor}", [RISCV target vendor.])
> > + ;;
> > +esac
> > +
> > # If we are configured native, pick a core file support file.
> > COREFILE=
> > COREFLAG=
> > diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c
> > index 813f2c3df8d..981f8d72e5c 100644
> > --- a/bfd/cpu-riscv.c
> > +++ b/bfd/cpu-riscv.c
> > @@ -25,6 +25,8 @@
> > #include "libbfd.h"
> > #include "cpu-riscv.h"
> >
> > +const char *riscv_vendor_name = RISCV_TARGET_VENDOR;
> > +
> > static const bfd_arch_info_type *
> > riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
> > {
> > diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
> > index c43a4ceae58..4657c0e3e90 100644
> > --- a/bfd/cpu-riscv.h
> > +++ b/bfd/cpu-riscv.h
> > @@ -18,6 +18,8 @@
> > Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> > MA 02110-1301, USA. */
> >
> > +extern const char *riscv_vendor_name;
> > +
> > enum riscv_spec_class
> > {
> > /* ISA spec. */
> > @@ -36,6 +38,9 @@ enum riscv_spec_class
> >
> > /* Vendor spec for T_HEAD XuanTie. */
> > VENDOR_SPEC_CLASS_THEAD,
> > +
> > + /* Vendor spec for SiFive. */
> > + VENDOR_SPEC_CLASS_SIFIVE,
> > };
> >
> > struct riscv_spec
> > diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> > index e61319cf395..bb77a5f67b1 100644
> > --- a/bfd/elfxx-riscv.c
> > +++ b/bfd/elfxx-riscv.c
> > @@ -1083,7 +1083,8 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
> > /* For default_enable field, decide if the extension should
> > be enbaled by default. */
> >
> > -#define EXT_DEFAULT 0x1
> > +#define EXT_DEFAULT 0x1
> > +#define EXT_SIFIVE (0x1 << 2)
> >
> > /* List all extensions that binutils should know about. */
> >
> > @@ -1108,7 +1109,7 @@ static struct riscv_supported_ext riscv_supported_std_ext[] =
> > {"i", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
> > /* The g is a special case which we don't want to output it,
> > but still need it when adding implicit extensions. */
> > - {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
> > + {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT|EXT_SIFIVE },
> > {"m", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
> > {"m", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
> > {"m", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
> > @@ -1179,6 +1180,14 @@ static struct riscv_supported_ext riscv_supported_vendor_thead_ext[] =
> > {NULL, 0, 0, 0, 0}
> > };
> >
> > +static struct riscv_supported_ext riscv_supported_vendor_sifive_ext[] =
> > +{
> > + {"xsfcdiscarddlone", VENDOR_SPEC_CLASS_SIFIVE, 0, 1, EXT_SIFIVE},
> > + {"xsfcflushdlone", VENDOR_SPEC_CLASS_SIFIVE, 0, 1, EXT_SIFIVE},
> > + {"xsfcflushilone", VENDOR_SPEC_CLASS_SIFIVE, 0, 1, EXT_SIFIVE},
> > + {NULL, 0, 0, 0, 0}
> > +};
> > +
> > const struct riscv_supported_ext *riscv_all_supported_ext[] =
> > {
> > riscv_supported_std_ext,
> > @@ -1187,6 +1196,7 @@ const struct riscv_supported_ext *riscv_all_supported_ext[] =
> > riscv_supported_std_h_ext,
> > riscv_supported_std_zxm_ext,
> > riscv_supported_vendor_thead_ext,
> > + riscv_supported_vendor_sifive_ext,
> > NULL
> > };
> >
> > @@ -1451,7 +1461,10 @@ riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec,
> > case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
> > case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
> > case RV_ISA_CLASS_X:
> > - table = riscv_supported_vendor_thead_ext;
> > + if (strncmp (name, "xsf", 3) == 0)
> > + table = riscv_supported_vendor_sifive_ext;
> > + else
> > + table = riscv_supported_vendor_thead_ext;
> > break;
> > default:
> > table = riscv_supported_std_ext;
> > @@ -1463,6 +1476,7 @@ riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec,
> > if (strcmp (table[i].name, name) == 0
> > && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
> > || table[i].isa_spec_class == VENDOR_SPEC_CLASS_THEAD
> > + || table[i].isa_spec_class == VENDOR_SPEC_CLASS_SIFIVE
> > || table[i].isa_spec_class == default_isa_spec))
> > {
> > *major_version = table[i].major_version;
> > @@ -1849,8 +1863,14 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
> > static void
> > riscv_set_default_arch (riscv_parse_subset_t *rps)
> > {
> > - unsigned long enable = EXT_DEFAULT;
> > + unsigned long enable;
> > int i, j;
> > +
> > + if (strcmp (riscv_vendor_name, "sifive") == 0)
> > + enable = EXT_SIFIVE;
> > + else
> > + enable = EXT_DEFAULT;
> > +
> > for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
> > {
> > const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
> > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> > index d4cf99e002b..c1b3c84b5b9 100644
> > --- a/gas/config/tc-riscv.c
> > +++ b/gas/config/tc-riscv.c
> > @@ -40,6 +40,7 @@ enum
> > {
> > DRAFT_EXT = 0,
> > VENDOR_THEAD_EXT,
> > + VENDOR_SIFIVE_EXT,
> > EXTENDED_EXT_NUM
> > };
> >
> > @@ -309,6 +310,13 @@ riscv_extended_subset_supports (int insn_class)
> > case INSN_CLASS_THEADSE:
> > return riscv_subset_supports ("xtheadse");
> >
> > + case INSN_CLASS_XSF_CDISCARDDLONE:
> > + return riscv_subset_supports ("xsfcdiscarddlone");
> > + case INSN_CLASS_XSF_CFLUSHDLONE:
> > + return riscv_subset_supports ("xsfcflushdlone");
> > + case INSN_CLASS_XSF_CFLUSHILONE:
> > + return riscv_subset_supports ("xsfcflushilone");
> > +
> > default:
> > as_fatal ("internal: unknown INSN_CLASS (0x%x)", insn_class);
> > return false;
> > @@ -457,6 +465,9 @@ static htab_t op_draft_hash = NULL;
> > /* Handle of the T-HEAD OPCODE hash table. */
> > static htab_t op_vendor_thead_hash = NULL;
> >
> > +/* Handle of the sifive OPCODE hash table. */
> > +static htab_t op_vendor_sifive_hash = NULL;
> > +
> > /* Handle of the type of .insn hash table. */
> > static htab_t insn_type_hash = NULL;
> >
> > @@ -1478,7 +1489,10 @@ md_begin (void)
> > hash_reg_names (RCLASS_VECR, riscv_vecr_names_numeric, NVECR);
> > hash_reg_names (RCLASS_VECM, riscv_vecm_names_numeric, NVECM);
> > op_draft_hash = init_opcode_hash (riscv_extended_opcodes[DRAFT_EXT], false);
> > - op_vendor_thead_hash = init_opcode_hash (riscv_extended_opcodes[VENDOR_THEAD_EXT], false);
> > + op_vendor_thead_hash =
> > + init_opcode_hash (riscv_extended_opcodes[VENDOR_THEAD_EXT], false);
> > + op_vendor_sifive_hash =
> > + init_opcode_hash (riscv_extended_opcodes[VENDOR_SIFIVE_EXT], false);
> > }
> >
> > static insn_t
> > @@ -1590,6 +1604,8 @@ riscv_find_extended_opcode_hash (char *str ATTRIBUTE_UNUSED)
> > case VENDOR_THEAD_EXT:
> > insn = (struct riscv_opcode *) str_hash_find (op_vendor_thead_hash, str);
> > break;
> > + case VENDOR_SIFIVE_EXT:
> > + insn = (struct riscv_opcode *) str_hash_find (op_vendor_sifive_hash, str);
> > default:
> > break;
> > }
> > diff --git a/gas/testsuite/gas/riscv/extended/sifive-insns.d b/gas/testsuite/gas/riscv/extended/sifive-insns.d
> > new file mode 100644
> > index 00000000000..ea6377ad756
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/extended/sifive-insns.d
> > @@ -0,0 +1,12 @@
> > +#as: -march=rv32i_xsfcdiscarddlone_xsfcflushdlone_xsfcflushilone
> > +#objdump: -dr
> > +
> > +.*:[ ]+file format .*
> > +
> > +
> > +Disassembly of section .text:
> > +
> > +0+000 <target>:
> > +[ ]+0:[ ]+fc050073[ ]+cflush.d.l1[ ]+a0
> > +[ ]+4:[ ]+fc250073[ ]+cdiscard.d.l1[ ]+a0
> > +[ ]+8:[ ]+fc100073[ ]+cflush.i.l1
> > diff --git a/gas/testsuite/gas/riscv/extended/sifive-insns.s b/gas/testsuite/gas/riscv/extended/sifive-insns.s
> > new file mode 100644
> > index 00000000000..b44dad08bd2
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/extended/sifive-insns.s
> > @@ -0,0 +1,4 @@
> > +target:
> > + cflush.d.l1 x10
> > + cdiscard.d.l1 x10
> > + cflush.i.l1
> > diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h
> > index 3de8809b4c2..f0f7490537c 100644
> > --- a/include/opcode/riscv-opc-extended.h
> > +++ b/include/opcode/riscv-opc-extended.h
> > @@ -2078,3 +2078,14 @@ DECLARE_CSR(shpmcounter29, CSR_SHPMCOUNTER29, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_
> > DECLARE_CSR(shpmcounter30, CSR_SHPMCOUNTER30, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> > DECLARE_CSR(shpmcounter31, CSR_SHPMCOUNTER31, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> > #endif /* DECLARE_CSR */
> > +
> > +#ifndef __RISCV_OPC_SIFIVE_THEAD__
> > +#define __RISCV_OPC_SIFIVE_THEAD__
> > +/* SiFive cache control instructions. */
> > +#define MATCH_CFLUSH_D_L1 0xfc000073
> > +#define MASK_CFLUSH_D_L1 0xfff07fff
> > +#define MATCH_CDISCARD_D_L1 0xfc200073
> > +#define MASK_CDISCARD_D_L1 0xfff07fff
> > +#define MATCH_CFLUSH_I_L1 0xfc100073
> > +#define MASK_CFLUSH_I_L1 0xffffffff
> > +#endif /* __RISCV_OPC_SIFIVE_THEAD__ */
> > diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> > index 1603fcfc495..7f97bb2cf3a 100644
> > --- a/include/opcode/riscv.h
> > +++ b/include/opcode/riscv.h
> > @@ -527,6 +527,11 @@ enum riscv_extended_insn_class
> > INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,
> > INSN_CLASS_THEADE,
> > INSN_CLASS_THEADSE,
> > +
> > + /* SiFive. */
> > + INSN_CLASS_XSF_CDISCARDDLONE,
> > + INSN_CLASS_XSF_CFLUSHDLONE,
> > + INSN_CLASS_XSF_CFLUSHILONE,
> > };
> >
> > /* This is a list of macro expanded instructions for extended
> > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> > index 05f94704774..9b2a482c3e6 100644
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -2378,10 +2378,24 @@ struct riscv_opcode riscv_vendor_thead_opcodes[] =
> >
> > };
> >
> > +/* Vendor SiFive extensions. */
> > +const struct riscv_opcode riscv_vendor_sifive_opcodes[] =
> > +{
> > +/* name, xlen, isa, operands, match, mask, match_func, pinfo. */
> > +/* Half-precision floating-point instruction subset. */
> > +{"cflush.d.l1", 0, INSN_CLASS_XSF_CFLUSHDLONE, "s", MATCH_CFLUSH_D_L1, MASK_CFLUSH_D_L1, match_opcode, 0 },
> > +{"cdiscard.d.l1", 0, INSN_CLASS_XSF_CDISCARDDLONE, "s", MATCH_CDISCARD_D_L1, MASK_CDISCARD_D_L1, match_opcode, 0 },
> > +{"cflush.i.l1", 0, INSN_CLASS_XSF_CFLUSHILONE, "", MATCH_CFLUSH_I_L1, MASK_CFLUSH_I_L1, match_opcode, 0 },
> > +
> > +/* Terminate the list. */
> > +{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0 },
> > +};
> > +
> > /* The supported extended extensions. */
> > const struct riscv_opcode *riscv_extended_opcodes[] =
> > {
> > riscv_draft_opcodes,
> > riscv_vendor_thead_opcodes,
> > + riscv_vendor_sifive_opcodes,
> > NULL
> > };
> > --
> > 2.30.2
> >
More information about the Binutils
mailing list