[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