diff options
-rw-r--r-- | bfd/config.in | 3 | ||||
-rwxr-xr-x | bfd/configure | 10 | ||||
-rw-r--r-- | bfd/configure.ac | 6 | ||||
-rw-r--r-- | bfd/cpu-riscv.c | 2 | ||||
-rw-r--r-- | bfd/cpu-riscv.h | 5 | ||||
-rw-r--r-- | bfd/elfxx-riscv.c | 28 | ||||
-rw-r--r-- | gas/config/tc-riscv.c | 18 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/extended/sifive-insns.d | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/extended/sifive-insns.s | 4 | ||||
-rw-r--r-- | include/opcode/riscv-opc-extended.h | 11 | ||||
-rw-r--r-- | include/opcode/riscv.h | 5 | ||||
-rw-r--r-- | opcodes/riscv-opc.c | 14 |
12 files changed, 113 insertions, 5 deletions
diff --git a/bfd/config.in b/bfd/config.in index f54a3ca..abd1385 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 58449ee..53263db 100755 --- a/bfd/configure +++ b/bfd/configure @@ -13658,6 +13658,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 50ba391..94885ba 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -822,6 +822,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 813f2c3..981f8d7 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 c43a4ce..4657c0e 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 34bcab6..10c05c3 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1109,7 +1109,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. */ @@ -1134,7 +1135,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 }, @@ -1223,6 +1224,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, @@ -1231,6 +1240,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 }; @@ -1495,7 +1505,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; @@ -1507,6 +1520,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; @@ -1917,8 +1931,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 99165f5..8e28adb7 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 }; @@ -310,6 +311,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; @@ -461,6 +469,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; @@ -1481,7 +1492,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 @@ -1593,6 +1607,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 0000000..ea6377a --- /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 0000000..b44dad0 --- /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 de9741f..1010661 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 8cef449..568e33b 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -529,6 +529,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 22474f0..c55a264 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -2302,10 +2302,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 }; |