aboutsummaryrefslogtreecommitdiff
path: root/gcc/common
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-11-10 07:26:18 -0800
committerIan Lance Taylor <iant@golang.org>2020-11-10 07:26:18 -0800
commit8d703821c69062c0cd255787d793e44f1a95d463 (patch)
tree6b1df9cdc36cc47b6164db69a14bc86a63dc77c6 /gcc/common
parent9cd320ea6572c577cdf17ce1f9ea5230b166af6d (diff)
parentcf392dbdf17e38026f8e3c0e9af7f5b87f63be56 (diff)
downloadgcc-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.h24
-rw-r--r--gcc/common/config/i386/i386-common.c116
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h5
-rw-r--r--gcc/common/config/i386/i386-isas.h5
-rw-r--r--gcc/common/config/riscv/riscv-common.c183
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[] =
{