diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-11-10 07:26:18 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-11-10 07:26:18 -0800 |
commit | 8d703821c69062c0cd255787d793e44f1a95d463 (patch) | |
tree | 6b1df9cdc36cc47b6164db69a14bc86a63dc77c6 /gcc/common | |
parent | 9cd320ea6572c577cdf17ce1f9ea5230b166af6d (diff) | |
parent | cf392dbdf17e38026f8e3c0e9af7f5b87f63be56 (diff) | |
download | gcc-8d703821c69062c0cd255787d793e44f1a95d463.zip gcc-8d703821c69062c0cd255787d793e44f1a95d463.tar.gz gcc-8d703821c69062c0cd255787d793e44f1a95d463.tar.bz2 |
Merge from trunk revision cf392dbdf17e38026f8e3c0e9af7f5b87f63be56.
Diffstat (limited to 'gcc/common')
-rw-r--r-- | gcc/common/config/i386/cpuinfo.h | 24 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-common.c | 116 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-cpuinfo.h | 5 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-isas.h | 5 | ||||
-rw-r--r-- | gcc/common/config/riscv/riscv-common.c | 183 |
5 files changed, 277 insertions, 56 deletions
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index c96455c..7a93e17 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -523,6 +523,8 @@ get_available_features (struct __processor_model *cpu_model, int avx_usable = 0; int avx512_usable = 0; int amx_usable = 0; + /* Check if KL is usable. */ + int has_kl = 0; if ((ecx & bit_OSXSAVE)) { /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and @@ -667,6 +669,8 @@ get_available_features (struct __processor_model *cpu_model, if (edx & bit_AMX_BF16) set_feature (FEATURE_AMX_BF16); } + if (ecx & bit_KL) + has_kl = 1; if (avx512_usable) { if (ebx & bit_AVX512F) @@ -701,10 +705,15 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_AVX5124FMAPS); if (edx & bit_AVX512VP2INTERSECT) set_feature (FEATURE_AVX512VP2INTERSECT); + if (edx & bit_UINTR) + set_feature (FEATURE_UINTR); __cpuid_count (7, 1, eax, ebx, ecx, edx); if (eax & bit_AVX512BF16) set_feature (FEATURE_AVX512BF16); + if (eax & bit_HRESET) + set_feature (FEATURE_HRESET); + } } @@ -728,6 +737,21 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_PTWRITE); } + /* Get Advanced Features at level 0x19 (eax = 0x19). */ + if (max_cpuid_level >= 0x19) + { + set_feature (FEATURE_AESKLE); + __cpuid (19, eax, ebx, ecx, edx); + /* Check if OS support keylocker. */ + if (ebx & bit_AESKLE) + { + if (ebx & bit_WIDEKL) + set_feature (FEATURE_WIDEKL); + if (has_kl) + set_feature (FEATURE_KL); + } + } + /* Check cpuid level of extended features. */ __cpuid (0x80000000, ext_level, ebx, ecx, edx); diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index 62a620b..e29320d 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -163,6 +163,11 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_ENQCMD_SET OPTION_MASK_ISA2_ENQCMD #define OPTION_MASK_ISA2_SERIALIZE_SET OPTION_MASK_ISA2_SERIALIZE #define OPTION_MASK_ISA2_TSXLDTRK_SET OPTION_MASK_ISA2_TSXLDTRK +#define OPTION_MASK_ISA2_UINTR_SET OPTION_MASK_ISA2_UINTR +#define OPTION_MASK_ISA2_HRESET_SET OPTION_MASK_ISA2_HRESET +#define OPTION_MASK_ISA2_KL_SET OPTION_MASK_ISA2_KL +#define OPTION_MASK_ISA2_WIDEKL_SET \ + (OPTION_MASK_ISA2_WIDEKL | OPTION_MASK_ISA2_KL_SET) /* Define a set of ISAs which aren't available when a given ISA is disabled. MMX and SSE ISAs are handled separately. */ @@ -254,6 +259,11 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AMX_TILE_UNSET OPTION_MASK_ISA2_AMX_TILE #define OPTION_MASK_ISA2_AMX_INT8_UNSET OPTION_MASK_ISA2_AMX_INT8 #define OPTION_MASK_ISA2_AMX_BF16_UNSET OPTION_MASK_ISA2_AMX_BF16 +#define OPTION_MASK_ISA2_UINTR_UNSET OPTION_MASK_ISA2_UINTR +#define OPTION_MASK_ISA2_HRESET_UNSET OPTION_MASK_ISA2_HRESET +#define OPTION_MASK_ISA2_KL_UNSET \ + (OPTION_MASK_ISA2_KL | OPTION_MASK_ISA2_WIDEKL_UNSET) +#define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -300,6 +310,16 @@ along with GCC; see the file COPYING3. If not see | OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET) #define OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET \ (OPTION_MASK_ISA2_AVX512F_UNSET) +#define OPTION_MASK_ISA2_AVX2_UNSET OPTION_MASK_ISA2_AVX512F_UNSET +#define OPTION_MASK_ISA2_AVX_UNSET OPTION_MASK_ISA2_AVX2_UNSET +#define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET +#define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET +#define OPTION_MASK_ISA2_SSE4_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET +#define OPTION_MASK_ISA2_SSSE3_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET +#define OPTION_MASK_ISA2_SSE3_UNSET OPTION_MASK_ISA2_SSSE3_UNSET +#define OPTION_MASK_ISA2_SSE2_UNSET \ + (OPTION_MASK_ISA2_SSE3_UNSET | OPTION_MASK_ISA2_KL_UNSET) +#define OPTION_MASK_ISA2_SSE_UNSET OPTION_MASK_ISA2_SSE2_UNSET #define OPTION_MASK_ISA2_AVX512BW_UNSET OPTION_MASK_ISA2_AVX512BF16_UNSET @@ -395,8 +415,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE_UNSET; } return true; @@ -410,8 +430,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE2_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE2_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE2_UNSET; } return true; @@ -425,8 +445,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE3_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE3_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE3_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE3_UNSET; } return true; @@ -440,8 +460,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSSE3_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSSE3_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSSE3_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSSE3_UNSET; } return true; @@ -455,8 +475,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_1_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_1_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE4_1_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE4_1_UNSET; } return true; @@ -470,8 +490,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_2_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_2_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE4_2_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE4_2_UNSET; } return true; @@ -485,8 +505,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX_UNSET; } return true; @@ -500,8 +520,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX2_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX2_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX2_UNSET; } return true; @@ -687,6 +707,40 @@ ix86_handle_option (struct gcc_options *opts, opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_ENQCMD_UNSET; opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_ENQCMD_UNSET; } + return true; + + case OPT_mkl: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_KL_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_KL_SET; + + /* The Keylocker instructions need XMM registers from SSE2. */ + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_KL_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_KL_UNSET; + } + return true; + + case OPT_mwidekl: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_WIDEKL_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_WIDEKL_SET; + + /* The Widekl instructions need XMM registers from SSE2. */ + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_WIDEKL_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_WIDEKL_UNSET; + } return true; case OPT_mserialize: @@ -702,6 +756,32 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_muintr: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_UINTR_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_UINTR_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_UNSET; + } + return true; + + case OPT_mhreset: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_HRESET_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_HRESET_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_HRESET_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_HRESET_UNSET; + } + return true; + case OPT_mavx5124fmaps: if (value) { @@ -1013,8 +1093,8 @@ ix86_handle_option (struct gcc_options *opts, case OPT_mno_sse4: opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_UNSET; opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_UNSET; - opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVX512F_UNSET; - opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVX512F_UNSET; + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SSE4_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SSE4_UNSET; return true; case OPT_msse4a: diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 5b94b1f..2138220 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -219,6 +219,11 @@ enum processor_features FEATURE_AMX_TILE, FEATURE_AMX_INT8, FEATURE_AMX_BF16, + FEATURE_UINTR, + FEATURE_HRESET, + FEATURE_KL, + FEATURE_AESKLE, + FEATURE_WIDEKL, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index 3c830ea..921db06 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -163,4 +163,9 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("amx-tile", FEATURE_AMX_TILE, P_NONE, "-mamx-tile") ISA_NAMES_TABLE_ENTRY("amx-int8", FEATURE_AMX_INT8, P_NONE, "-mamx-int8") ISA_NAMES_TABLE_ENTRY("amx-bf16", FEATURE_AMX_BF16, P_NONE, "-mamx-bf16") + ISA_NAMES_TABLE_ENTRY("uintr", FEATURE_UINTR, P_NONE, "-muintr") + ISA_NAMES_TABLE_ENTRY("hreset", FEATURE_HRESET, P_NONE, "-mhreset") + ISA_NAMES_TABLE_ENTRY("kl", FEATURE_KL, P_NONE, "-mkl") + ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL) + ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl") ISA_NAMES_TABLE_END diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index 82c5154..9a576eb 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -54,12 +54,20 @@ struct riscv_implied_info_t }; /* Implied ISA info, must end with NULL sentinel. */ -riscv_implied_info_t riscv_implied_info[] = +static const riscv_implied_info_t riscv_implied_info[] = { {"d", "f"}, {NULL, NULL} }; +static const riscv_cpu_info riscv_cpu_tables[] = +{ +#define RISCV_CORE(CORE_NAME, ARCH, TUNE) \ + {CORE_NAME, ARCH, TUNE}, +#include "../../../config/riscv/riscv-cores.def" + {NULL, NULL, NULL} +}; + /* Subset list. */ class riscv_subset_list { @@ -451,7 +459,7 @@ riscv_subset_list::handle_implied_ext (const char *ext, int minor_version, bool explicit_version_p) { - riscv_implied_info_t *implied_info; + const riscv_implied_info_t *implied_info; for (implied_info = &riscv_implied_info[0]; implied_info->ext; ++implied_info) @@ -516,6 +524,14 @@ riscv_subset_list::parse_multiletter_ext (const char *p, *q = '\0'; + if (strlen (subset) == 1) + { + error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter", + m_arch, ext_type_str); + free (subset); + return NULL; + } + add (subset, major_version, minor_version, explicit_version_p); free (subset); p += end_of_version - subset; @@ -604,48 +620,70 @@ fail: std::string riscv_arch_str (bool version_p) { - gcc_assert (current_subset_list); - return current_subset_list->to_string (version_p); + if (current_subset_list) + return current_subset_list->to_string (version_p); + else + return std::string(); } +/* Type for pointer to member of gcc_options. */ +typedef int (gcc_options::*opt_var_ref_t); + +/* Types for recording extension to internal flag. */ +struct riscv_ext_flag_table_t { + const char *ext; + opt_var_ref_t var_ref; + int mask; +}; + +/* Mapping table between extension to internal flag. */ +static const riscv_ext_flag_table_t riscv_ext_flag_table[] = +{ + {"e", &gcc_options::x_target_flags, MASK_RVE}, + {"m", &gcc_options::x_target_flags, MASK_MUL}, + {"a", &gcc_options::x_target_flags, MASK_ATOMIC}, + {"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT}, + {"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT}, + {"c", &gcc_options::x_target_flags, MASK_RVC}, + {NULL, NULL, 0} +}; + /* Parse a RISC-V ISA string into an option mask. Must clear or set all arch dependent mask bits, in case more than one -march string is passed. */ static void -riscv_parse_arch_string (const char *isa, int *flags, location_t loc) +riscv_parse_arch_string (const char *isa, + struct gcc_options *opts, + location_t loc) { riscv_subset_list *subset_list; subset_list = riscv_subset_list::parse (isa, loc); if (!subset_list) return; - if (subset_list->xlen () == 32) - *flags &= ~MASK_64BIT; - else if (subset_list->xlen () == 64) - *flags |= MASK_64BIT; - - *flags &= ~MASK_RVE; - if (subset_list->lookup ("e")) - *flags |= MASK_RVE; - - *flags &= ~MASK_MUL; - if (subset_list->lookup ("m")) - *flags |= MASK_MUL; - - *flags &= ~MASK_ATOMIC; - if (subset_list->lookup ("a")) - *flags |= MASK_ATOMIC; - - *flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT); - if (subset_list->lookup ("f")) - *flags |= MASK_HARD_FLOAT; - - if (subset_list->lookup ("d")) - *flags |= MASK_DOUBLE_FLOAT; - - *flags &= ~MASK_RVC; - if (subset_list->lookup ("c")) - *flags |= MASK_RVC; + if (opts) + { + const riscv_ext_flag_table_t *arch_ext_flag_tab; + /* Clean up target flags before we set. */ + for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; + arch_ext_flag_tab->ext; + ++arch_ext_flag_tab) + opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask; + + if (subset_list->xlen () == 32) + opts->x_target_flags &= ~MASK_64BIT; + else if (subset_list->xlen () == 64) + opts->x_target_flags |= MASK_64BIT; + + + for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; + arch_ext_flag_tab->ext; + ++arch_ext_flag_tab) + { + if (subset_list->lookup (arch_ext_flag_tab->ext)) + opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask; + } + } if (current_subset_list) delete current_subset_list; @@ -653,6 +691,21 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc) current_subset_list = subset_list; } +/* Return the riscv_cpu_info entry for CPU, NULL if not found. */ + +const riscv_cpu_info * +riscv_find_cpu (const char *cpu) +{ + const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0]; + for (;cpu_info->name != NULL; ++cpu_info) + { + const char *name = cpu_info->name; + if (strcmp (cpu, name) == 0) + return cpu_info; + } + return NULL; +} + /* Implement TARGET_HANDLE_OPTION. */ static bool @@ -664,7 +717,13 @@ riscv_handle_option (struct gcc_options *opts, switch (decoded->opt_index) { case OPT_march_: - riscv_parse_arch_string (decoded->arg, &opts->x_target_flags, loc); + riscv_parse_arch_string (decoded->arg, opts, loc); + return true; + + case OPT_mcpu_: + if (riscv_find_cpu (decoded->arg) == NULL) + error_at (loc, "%<-mcpu=%s%>: unknown CPU", + decoded->arg); return true; default: @@ -678,15 +737,63 @@ const char * riscv_expand_arch (int argc ATTRIBUTE_UNUSED, const char **argv) { - static char *_arch_buf; gcc_assert (argc == 1); - int flags; location_t loc = UNKNOWN_LOCATION; - riscv_parse_arch_string (argv[0], &flags, loc); - _arch_buf = xstrdup (riscv_arch_str (false).c_str ()); - return _arch_buf; + riscv_parse_arch_string (argv[0], NULL, loc); + const std::string arch = riscv_arch_str (false); + if (arch.length()) + return xasprintf ("-march=%s", arch.c_str()); + else + return ""; } +/* Expand default -mtune option from -mcpu option, use default --with-tune value + if -mcpu don't have valid value. */ + +const char * +riscv_default_mtune (int argc, const char **argv) +{ + gcc_assert (argc == 2); + const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]); + const char *default_mtune = argv[1]; + if (cpu) + return cpu->tune; + else + return default_mtune; +} + +/* Expand arch string with implied extensions from -mcpu option. */ + +const char * +riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED, + const char **argv) +{ + gcc_assert (argc > 0 && argc <= 2); + const char *default_arch_str = NULL; + const char *arch_str = NULL; + if (argc >= 2) + default_arch_str = argv[1]; + + const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]); + + if (cpu == NULL) + { + if (default_arch_str == NULL) + return ""; + else + arch_str = default_arch_str; + } + else + arch_str = cpu->arch; + + location_t loc = UNKNOWN_LOCATION; + + riscv_parse_arch_string (arch_str, NULL, loc); + const std::string arch = riscv_arch_str (false); + return xasprintf ("-march=%s", arch.c_str()); +} + + /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ static const struct default_options riscv_option_optimization_table[] = { |