Re: [PATCH 1/2] RISC-V: add vendor opcodes
夏立方
lifang_xia@c-sky.com
Fri Aug 27 07:18:43 GMT 2021
More information about the Binutils mailing list
Fri Aug 27 07:18:43 GMT 2021
- Previous message (by thread): [PATCH 1/2] RISC-V: add vendor opcodes
- Next message (by thread): [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Thanks. That's a good choice. I will re-send these patch with "[integaration XXXX] RISC-V XXXXXXXXX". Lifang ------------------------------------------------------------------ Sender:Nelson Chu <nelson.chu@sifive.com> Sent At:2021 Aug. 27 (Fri.) 12:01 Recipient:夏立方 <lifang_xia@c-sky.com> Cc:binutils@sourceware.org <binutils@sourceware.org>; Palmer Dabbelt <palmer@dabbelt.com>; Jim Wilson <jimw@sifive.com>; Kito Cheng <kito.cheng@sifive.com>; rjiejie <rjiejie@linux.alibaba.com> Subject:Re: [PATCH 1/2] RISC-V: add vendor opcodes I suppose you should add vendor extensions to the integration branch, rather than mainline. Please check the users/riscv/binutils-integration-branch. Nelson On Fri, Aug 27, 2021 at 11:39 AM Lifang Xia <lifang_xia@c-sky.com> wrote: > > This patch uses the T-HEAD Xuantie processor as an example to solve that > how to add the vendor's opcode and CSR. > Without modifying the existing mechanism, create a new > opcodes/riscv-vendor-opc.c, similar to opcodes/riscv-opc.c, used to > describe the vendor's opcodes. > New file, include/opcodes/riscv-vendor-opc.h, used to define the encoding, > mask and CSR of the opcodes. > > The sub-string from -march option is used to pick the suitable list of > the vendor's opcodes. > > bfd/ > * cpu-riscv.h (enum riscv_spec_class): New > ISA_SPEC_CLASS_VENDOR. > gas/ > * config/tc-riscv.c (ext_version_table): New "theadc". > (riscv_vendor_get_opcodes): New. > (riscv_multi_subset_supports): Check xtheadc extensions. > (riscv_get_default_ext_version): Skip for vendor. > (init_opcode_hash): Add vendor's extensions to the hash. > (md_begin): Init opcode hash. > include/ > * opcode/riscv-opc.h: Include riscv-vendor-opc.h > * opcode/riscv-vendor-opc.h: New. > * opcode/riscv.h (enum riscv_insn_class): New class for vendor. > (struct riscv_vendor_opcode): New. > (riscv_vendor_list): New. > opcodes/ > * Makefile.am: Add riscv-vendor-opc.c. > * Makefile.in: Likewise. > * configure: Likewise > * configure.ac: Likewise > * riscv-dis.c (arch_string): New. > (get_vendor_opcodes): Get the vendor opcodes. > (riscv_disassemble_insn): Add vendor's opcode to the hash. > (riscv_get_disassembler): Setup arch_string with attr. > * riscv-vendor-opc.c: New. > --- > bfd/cpu-riscv.h | 1 + > gas/config/tc-riscv.c | 55 +++++++++++++++++++++++++++++-- > include/opcode/riscv-opc.h | 1 + > include/opcode/riscv-vendor-opc.h | 34 +++++++++++++++++++ > include/opcode/riscv.h | 10 ++++++ > opcodes/Makefile.am | 1 + > opcodes/Makefile.in | 2 ++ > opcodes/configure | 2 +- > opcodes/configure.ac | 2 +- > opcodes/riscv-dis.c | 23 +++++++++++++ > opcodes/riscv-vendor-opc.c | 43 ++++++++++++++++++++++++ > 11 files changed, 170 insertions(+), 4 deletions(-) > create mode 100644 include/opcode/riscv-vendor-opc.h > create mode 100644 opcodes/riscv-vendor-opc.c > > diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h > index cafaca23be0..06ede1b2bef 100644 > --- a/bfd/cpu-riscv.h > +++ b/bfd/cpu-riscv.h > @@ -26,6 +26,7 @@ enum riscv_spec_class > ISA_SPEC_CLASS_20190608, > ISA_SPEC_CLASS_20191213, > ISA_SPEC_CLASS_DRAFT, > + ISA_SPEC_CLASS_VENDOR, > > /* Privileged spec. */ > PRIV_SPEC_CLASS_NONE, > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c > index 460667e4349..260a10ab9b9 100644 > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -143,6 +143,9 @@ static const struct riscv_ext_version ext_version_table[] = > {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93}, > {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93}, > > + /* T-HEAD extentions for Xuantie C9xx. */ > + {"xtheadc", ISA_SPEC_CLASS_VENDOR, 2, 0}, > + > /* Terminate the list. */ > {NULL, 0, 0, 0} > }; > @@ -211,6 +214,22 @@ riscv_set_default_isa_spec (const char *s) > return 1; > } > > +/* Get the opcodes from vendors. */ > +static struct riscv_opcode * > +riscv_vendor_get_opcodes (riscv_subset_list_t *subsets) > +{ > + unsigned int i = 0; > + struct riscv_subset_t *subset = NULL; > + > + for (i = 0; riscv_vendor_list[i].vendor; i++) > + { > + if (riscv_lookup_subset (subsets, riscv_vendor_list[i].vendor, &subset)) > + return riscv_vendor_list[i].opcodes; > + } > + > + return NULL; > +} > + > /* Set the default_priv_spec. Find the privileged elf attributes when > the input string is NULL. Return 0 if the spec isn't supported. > Otherwise, return 1. */ > @@ -343,6 +362,9 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class) > case INSN_CLASS_ZBC: > return riscv_subset_supports ("zbc"); > > + case INSN_CLASS_THEADC: > + return riscv_subset_supports ("xtheadc"); > + > default: > as_fatal ("internal: unreachable"); > return false; > @@ -390,6 +412,7 @@ riscv_get_default_ext_version (const char *name, > && strcmp (ext->name, name) == 0) > { > if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT > + || ext->isa_spec_class == ISA_SPEC_CLASS_VENDOR > || ext->isa_spec_class == default_isa_spec) > { > *major_version = ext->major_version; > @@ -1176,6 +1199,7 @@ struct percent_op_match > > static htab_t > init_opcode_hash (const struct riscv_opcode *opcodes, > + const struct riscv_opcode *ext_opcodes, > bool insn_directive_p) > { > int i = 0; > @@ -1206,6 +1230,29 @@ init_opcode_hash (const struct riscv_opcode *opcodes, > while (opcodes[i].name && !strcmp (opcodes[i].name, name)); > } > > + i = 0; > + while (ext_opcodes && ext_opcodes[i].name) > + { > + const char *name = ext_opcodes[i].name; > + if (str_hash_insert (hash, name, &ext_opcodes[i], 0) != NULL) > + as_fatal (_("internal: duplicate %s"), name); > + > + do > + { > + if (ext_opcodes[i].pinfo != INSN_MACRO) > + { > + length = 0; /* Let assembler determine the length. */ > + if (!validate_riscv_insn (&ext_opcodes[i], length)) > + as_fatal (_("internal: broken assembler. " > + "No assembly attempted")); > + } > + else > + gas_assert (!insn_directive_p); > + ++i; > + } > + while (ext_opcodes[i].name && !strcmp (ext_opcodes[i].name, name)); > + } > + > return hash; > } > > @@ -1220,8 +1267,11 @@ md_begin (void) > if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach)) > as_warn (_("could not set architecture and machine")); > > - op_hash = init_opcode_hash (riscv_opcodes, false); > - insn_type_hash = init_opcode_hash (riscv_insn_types, true); > + op_hash = init_opcode_hash (riscv_opcodes, > + riscv_vendor_get_opcodes (&riscv_subsets), > + false); > + > + insn_type_hash = init_opcode_hash (riscv_insn_types, NULL, true); > > reg_names_hash = str_htab_create (); > hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR); > @@ -3916,3 +3966,4 @@ riscv_pop_insert (void) > > pop_insert (riscv_pseudo_table); > } > + > diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h > index 9999da6241a..84fc2ee0e8e 100644 > --- a/include/opcode/riscv-opc.h > +++ b/include/opcode/riscv-opc.h > @@ -20,6 +20,7 @@ > > #ifndef RISCV_ENCODING_H > #define RISCV_ENCODING_H > +#include "opcode/riscv-vendor-opc.h" > /* Instruction opcode macros. */ > #define MATCH_SLLI_RV32 0x1013 > #define MASK_SLLI_RV32 0xfe00707f > diff --git a/include/opcode/riscv-vendor-opc.h b/include/opcode/riscv-vendor-opc.h > new file mode 100644 > index 00000000000..949047239f8 > --- /dev/null > +++ b/include/opcode/riscv-vendor-opc.h > @@ -0,0 +1,34 @@ > +/* riscv-vendor-opc.h. RISC-V instruction opcode and CSR macros from vendors. > + Copyright (C) 2011-2021 Free Software Foundation, Inc. > + Contributed by Andrew Waterman > + > + This file is part of GDB, GAS, and the GNU binutils. > + > + GDB, GAS, and the GNU binutils are free software; you can redistribute > + them and/or modify them under the terms of the GNU General Public > + License as published by the Free Software Foundation; either version > + 3, or (at your option) any later version. > + > + GDB, GAS, and the GNU binutils are distributed in the hope that they > + will be useful, but WITHOUT ANY WARRANTY; without even the implied > + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See > + the GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; see the file COPYING3. If not, > + see <http://www.gnu.org/licenses/>. */ > + > +#ifndef __RISCV_VENDOR_OPC_H__ > +#define __RISCV_VENDOR_OPC_H__ > + > + > +/* Opcodes for VENDOR 0. */ > + > + > +/* Opcodes for VENDOR 1. */ > + > + > +/* Opcodes for VENDOR 2. */ > + > + > +#endif > diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h > index fdf3df4f5c1..96dace50729 100644 > --- a/include/opcode/riscv.h > +++ b/include/opcode/riscv.h > @@ -319,6 +319,9 @@ enum riscv_insn_class > INSN_CLASS_ZBA, > INSN_CLASS_ZBB, > INSN_CLASS_ZBC, > + > + /* INSN class for THEAD. */ > + INSN_CLASS_THEADC, > }; > > /* This structure holds information for a particular instruction. */ > @@ -359,6 +362,12 @@ struct riscv_opcode > unsigned long pinfo; > }; > > +struct riscv_vendor_opcode > +{ > + const char *vendor; > + struct riscv_opcode *opcodes; > +}; > + > /* Instruction is a simple alias (e.g. "mv" for "addi"). */ > #define INSN_ALIAS 0x00000001 > > @@ -433,5 +442,6 @@ extern const char * const riscv_fpr_names_abi[NFPR]; > > extern const struct riscv_opcode riscv_opcodes[]; > extern const struct riscv_opcode riscv_insn_types[]; > +extern const struct riscv_vendor_opcode riscv_vendor_list[]; > > #endif /* _RISCV_H_ */ > diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am > index 0e04b4c05c4..4f3ad0e69cd 100644 > --- a/opcodes/Makefile.am > +++ b/opcodes/Makefile.am > @@ -229,6 +229,7 @@ TARGET_LIBOPCODES_CFILES = \ > pru-opc.c \ > riscv-dis.c \ > riscv-opc.c \ > + riscv-vendor-opc.c \ > rl78-decode.c \ > rl78-dis.c \ > rx-decode.c \ > diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in > index 42c15f00d30..5dcbc204a1e 100644 > --- a/opcodes/Makefile.in > +++ b/opcodes/Makefile.in > @@ -620,6 +620,7 @@ TARGET_LIBOPCODES_CFILES = \ > pru-opc.c \ > riscv-dis.c \ > riscv-opc.c \ > + riscv-vendor-opc.c \ > rl78-decode.c \ > rl78-dis.c \ > rx-decode.c \ > @@ -1036,6 +1037,7 @@ distclean-compile: > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pru-opc.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-dis.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-opc.Plo@am__quote@ > +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-vendor-opc.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-decode.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-dis.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx-decode.Plo@am__quote@ > diff --git a/opcodes/configure b/opcodes/configure > index 3513e408ce1..ad9ec966411 100755 > --- a/opcodes/configure > +++ b/opcodes/configure > @@ -12265,7 +12265,7 @@ if test x${all_targets} = xfalse ; then > bfd_pru_arch) ta="$ta pru-dis.lo pru-opc.lo" ;; > bfd_pyramid_arch) ;; > bfd_romp_arch) ;; > - bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;; > + bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;; > bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; > bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";; > bfd_rx_arch) ta="$ta rx-dis.lo rx-decode.lo";; > diff --git a/opcodes/configure.ac b/opcodes/configure.ac > index e564f067334..16024f2f0d5 100644 > --- a/opcodes/configure.ac > +++ b/opcodes/configure.ac > @@ -326,7 +326,7 @@ if test x${all_targets} = xfalse ; then > bfd_pru_arch) ta="$ta pru-dis.lo pru-opc.lo" ;; > bfd_pyramid_arch) ;; > bfd_romp_arch) ;; > - bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;; > + bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;; > bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; > bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";; > bfd_rx_arch) ta="$ta rx-dis.lo rx-decode.lo";; > diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c > index fe8dfb88d90..cafcf1ecfaa 100644 > --- a/opcodes/riscv-dis.c > +++ b/opcodes/riscv-dis.c > @@ -33,6 +33,7 @@ > #include <ctype.h> > > static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE; > +static const char *arch_string = NULL; > > struct riscv_private_data > { > @@ -140,6 +141,21 @@ parse_riscv_dis_options (const char *opts_in) > free (opts); > } > > +static struct riscv_opcode* > +get_vendor_opcodes (const char *arch) > +{ > + int i = 0; > + if (arch == NULL) > + return NULL; > + > + for (i = 0; riscv_vendor_list[i].vendor; i++) > + { > + if (strstr(arch, riscv_vendor_list[i].vendor) != NULL) > + return riscv_vendor_list[i].opcodes; > + } > + return NULL; > +} > + > /* Print one argument from an array. */ > > static void > @@ -443,6 +459,11 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) > if (!riscv_hash[OP_HASH_IDX (op->match)]) > riscv_hash[OP_HASH_IDX (op->match)] = op; > > + op = get_vendor_opcodes (arch_string); > + for (; op && op->name; op++) > + if (!riscv_hash[OP_HASH_IDX (op->match)]) > + riscv_hash[OP_HASH_IDX (op->match)] = op; > + > init = 1; > } > > @@ -611,6 +632,8 @@ riscv_get_disassembler (bfd *abfd) > attr[Tag_b].i, > attr[Tag_c].i, > &default_priv_spec); > + /* Get Vendor opcodes. */ > + arch_string = attr[Tag_RISCV_arch].s; > } > } > } > diff --git a/opcodes/riscv-vendor-opc.c b/opcodes/riscv-vendor-opc.c > new file mode 100644 > index 00000000000..9191b654c14 > --- /dev/null > +++ b/opcodes/riscv-vendor-opc.c > @@ -0,0 +1,43 @@ > +/* RISC-V opcode list from vendors. > + Copyright (C) 2011-2021 Free Software Foundation, Inc. > + > + Contributed by Andrew Waterman (andrew@sifive.com). > + Based on MIPS target. > + > + This file is part of the GNU opcodes library. > + > + This library is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3, or (at your option) > + any later version. > + > + It is distributed in the hope that it will be useful, but WITHOUT > + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY > + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public > + License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; see the file COPYING3. If not, > + see <http://www.gnu.org/licenses/>. */ > + > + > +#include "sysdep.h" > +#include "opcode/riscv.h" > +#include <stdio.h> > +#include "bfd.h" > + > +/* The vendor extension opcodes for T-HEAD. */ > +struct riscv_opcode vendor_thead_opcodes[] = > +{ > + {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0} > + > +}; > + > +/* The vendor opcodes list. */ > +const struct riscv_vendor_opcode riscv_vendor_list[] = > +{ > + /* Vendor T-HEAD. */ > + {"xtheadc", vendor_thead_opcodes}, > + {NULL, NULL}, > +}; > + > -- > 2.17.1 >
- Previous message (by thread): [PATCH 1/2] RISC-V: add vendor opcodes
- Next message (by thread): [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list