return bb3;
}
+/* Priority of i386 features, greater value is higher priority. This is
+ used to decide the order in which function dispatch must happen. For
+ instance, a version specialized for SSE4.2 should be checked for dispatch
+ before a version for SSE3, as SSE4.2 implies SSE3. */
+enum feature_priority
+{
+ P_ZERO = 0,
+ P_MMX,
+ P_SSE,
+ P_SSE2,
+ P_SSE3,
+ P_SSSE3,
+ P_PROC_SSSE3,
+ P_SSE4_A,
+ P_PROC_SSE4_A,
+ P_SSE4_1,
+ P_SSE4_2,
+ P_PROC_SSE4_2,
+ P_POPCNT,
+ P_AES,
+ P_PCLMUL,
+ P_AVX,
+ P_PROC_AVX,
+ P_BMI,
+ P_PROC_BMI,
+ P_FMA4,
+ P_XOP,
+ P_PROC_XOP,
+ P_FMA,
+ P_PROC_FMA,
+ P_BMI2,
+ P_AVX2,
+ P_PROC_AVX2,
+ P_AVX512F,
+ P_PROC_AVX512F
+};
+
+/* This is the order of bit-fields in __processor_features in cpuinfo.c */
+enum processor_features
+{
+ F_CMOV = 0,
+ F_MMX,
+ F_POPCNT,
+ F_SSE,
+ F_SSE2,
+ F_SSE3,
+ F_SSSE3,
+ F_SSE4_1,
+ F_SSE4_2,
+ F_AVX,
+ F_AVX2,
+ F_SSE4_A,
+ F_FMA4,
+ F_XOP,
+ F_FMA,
+ F_AVX512F,
+ F_BMI,
+ F_BMI2,
+ F_AES,
+ F_PCLMUL,
+ F_AVX512VL,
+ F_AVX512BW,
+ F_AVX512DQ,
+ F_AVX512CD,
+ F_AVX512ER,
+ F_AVX512PF,
+ F_AVX512VBMI,
+ F_AVX512IFMA,
+ F_AVX5124VNNIW,
+ F_AVX5124FMAPS,
+ F_AVX512VPOPCNTDQ,
+ F_AVX512VBMI2,
+ F_GFNI,
+ F_VPCLMULQDQ,
+ F_AVX512VNNI,
+ F_AVX512BITALG,
+ F_MAX
+};
+
+/* These are the values for vendor types and cpu types and subtypes
+ in cpuinfo.c. Cpu types and subtypes should be subtracted by
+ the corresponding start value. */
+enum processor_model
+{
+ M_INTEL = 1,
+ M_AMD,
+ M_CPU_TYPE_START,
+ M_INTEL_BONNELL,
+ M_INTEL_CORE2,
+ M_INTEL_COREI7,
+ M_AMDFAM10H,
+ M_AMDFAM15H,
+ M_INTEL_SILVERMONT,
+ M_INTEL_KNL,
+ M_AMD_BTVER1,
+ M_AMD_BTVER2,
+ M_AMDFAM17H,
+ M_INTEL_KNM,
+ M_INTEL_GOLDMONT,
+ M_INTEL_GOLDMONT_PLUS,
+ M_INTEL_TREMONT,
+ M_CPU_SUBTYPE_START,
+ M_INTEL_COREI7_NEHALEM,
+ M_INTEL_COREI7_WESTMERE,
+ M_INTEL_COREI7_SANDYBRIDGE,
+ M_AMDFAM10H_BARCELONA,
+ M_AMDFAM10H_SHANGHAI,
+ M_AMDFAM10H_ISTANBUL,
+ M_AMDFAM15H_BDVER1,
+ M_AMDFAM15H_BDVER2,
+ M_AMDFAM15H_BDVER3,
+ M_AMDFAM15H_BDVER4,
+ M_AMDFAM17H_ZNVER1,
+ M_INTEL_COREI7_IVYBRIDGE,
+ M_INTEL_COREI7_HASWELL,
+ M_INTEL_COREI7_BROADWELL,
+ M_INTEL_COREI7_SKYLAKE,
+ M_INTEL_COREI7_SKYLAKE_AVX512,
+ M_INTEL_COREI7_CANNONLAKE,
+ M_INTEL_COREI7_ICELAKE_CLIENT,
+ M_INTEL_COREI7_ICELAKE_SERVER,
+ M_AMDFAM17H_ZNVER2,
+ M_INTEL_COREI7_CASCADELAKE
+};
+
+struct _arch_names_table
+{
+ const char *const name;
+ const enum processor_model model;
+};
+
+static const _arch_names_table arch_names_table[] =
+{
+ {"amd", M_AMD},
+ {"intel", M_INTEL},
+ {"atom", M_INTEL_BONNELL},
+ {"slm", M_INTEL_SILVERMONT},
+ {"core2", M_INTEL_CORE2},
+ {"corei7", M_INTEL_COREI7},
+ {"nehalem", M_INTEL_COREI7_NEHALEM},
+ {"westmere", M_INTEL_COREI7_WESTMERE},
+ {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
+ {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
+ {"haswell", M_INTEL_COREI7_HASWELL},
+ {"broadwell", M_INTEL_COREI7_BROADWELL},
+ {"skylake", M_INTEL_COREI7_SKYLAKE},
+ {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
+ {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
+ {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
+ {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
+ {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
+ {"bonnell", M_INTEL_BONNELL},
+ {"silvermont", M_INTEL_SILVERMONT},
+ {"goldmont", M_INTEL_GOLDMONT},
+ {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
+ {"tremont", M_INTEL_TREMONT},
+ {"knl", M_INTEL_KNL},
+ {"knm", M_INTEL_KNM},
+ {"amdfam10h", M_AMDFAM10H},
+ {"barcelona", M_AMDFAM10H_BARCELONA},
+ {"shanghai", M_AMDFAM10H_SHANGHAI},
+ {"istanbul", M_AMDFAM10H_ISTANBUL},
+ {"btver1", M_AMD_BTVER1},
+ {"amdfam15h", M_AMDFAM15H},
+ {"bdver1", M_AMDFAM15H_BDVER1},
+ {"bdver2", M_AMDFAM15H_BDVER2},
+ {"bdver3", M_AMDFAM15H_BDVER3},
+ {"bdver4", M_AMDFAM15H_BDVER4},
+ {"btver2", M_AMD_BTVER2},
+ {"amdfam17h", M_AMDFAM17H},
+ {"znver1", M_AMDFAM17H_ZNVER1},
+ {"znver2", M_AMDFAM17H_ZNVER2},
+};
+
+/* These are the target attribute strings for which a dispatcher is
+ available, from fold_builtin_cpu. */
+struct _isa_names_table
+{
+ const char *const name;
+ const enum processor_features feature;
+ const enum feature_priority priority;
+};
+
+static const _isa_names_table isa_names_table[] =
+{
+ {"cmov", F_CMOV, P_ZERO},
+ {"mmx", F_MMX, P_MMX},
+ {"popcnt", F_POPCNT, P_POPCNT},
+ {"sse", F_SSE, P_SSE},
+ {"sse2", F_SSE2, P_SSE2},
+ {"sse3", F_SSE3, P_SSE3},
+ {"ssse3", F_SSSE3, P_SSSE3},
+ {"sse4a", F_SSE4_A, P_SSE4_A},
+ {"sse4.1", F_SSE4_1, P_SSE4_1},
+ {"sse4.2", F_SSE4_2, P_SSE4_2},
+ {"avx", F_AVX, P_AVX},
+ {"fma4", F_FMA4, P_FMA4},
+ {"xop", F_XOP, P_XOP},
+ {"fma", F_FMA, P_FMA},
+ {"avx2", F_AVX2, P_AVX2},
+ {"avx512f", F_AVX512F, P_AVX512F},
+ {"bmi", F_BMI, P_BMI},
+ {"bmi2", F_BMI2, P_BMI2},
+ {"aes", F_AES, P_AES},
+ {"pclmul", F_PCLMUL, P_PCLMUL},
+ {"avx512vl",F_AVX512VL, P_ZERO},
+ {"avx512bw",F_AVX512BW, P_ZERO},
+ {"avx512dq",F_AVX512DQ, P_ZERO},
+ {"avx512cd",F_AVX512CD, P_ZERO},
+ {"avx512er",F_AVX512ER, P_ZERO},
+ {"avx512pf",F_AVX512PF, P_ZERO},
+ {"avx512vbmi",F_AVX512VBMI, P_ZERO},
+ {"avx512ifma",F_AVX512IFMA, P_ZERO},
+ {"avx5124vnniw",F_AVX5124VNNIW, P_ZERO},
+ {"avx5124fmaps",F_AVX5124FMAPS, P_ZERO},
+ {"avx512vpopcntdq",F_AVX512VPOPCNTDQ, P_ZERO},
+ {"avx512vbmi2", F_AVX512VBMI2, P_ZERO},
+ {"gfni", F_GFNI, P_ZERO},
+ {"vpclmulqdq", F_VPCLMULQDQ, P_ZERO},
+ {"avx512vnni", F_AVX512VNNI, P_ZERO},
+ {"avx512bitalg", F_AVX512BITALG, P_ZERO}
+};
+
/* This parses the attribute arguments to target in DECL and determines
the right builtin to use to match the platform specification.
It returns the priority value for this version decl. If PREDICATE_LIST
char *tok_str = NULL;
char *token;
- /* Priority of i386 features, greater value is higher priority. This is
- used to decide the order in which function dispatch must happen. For
- instance, a version specialized for SSE4.2 should be checked for dispatch
- before a version for SSE3, as SSE4.2 implies SSE3. */
- enum feature_priority
- {
- P_ZERO = 0,
- P_MMX,
- P_SSE,
- P_SSE2,
- P_SSE3,
- P_SSSE3,
- P_PROC_SSSE3,
- P_SSE4_A,
- P_PROC_SSE4_A,
- P_SSE4_1,
- P_SSE4_2,
- P_PROC_SSE4_2,
- P_POPCNT,
- P_AES,
- P_PCLMUL,
- P_AVX,
- P_PROC_AVX,
- P_BMI,
- P_PROC_BMI,
- P_FMA4,
- P_XOP,
- P_PROC_XOP,
- P_FMA,
- P_PROC_FMA,
- P_BMI2,
- P_AVX2,
- P_PROC_AVX2,
- P_AVX512F,
- P_PROC_AVX512F
- };
-
enum feature_priority priority = P_ZERO;
- /* These are the target attribute strings for which a dispatcher is
- available, from fold_builtin_cpu. */
-
- static struct _feature_list
- {
- const char *const name;
- const enum feature_priority priority;
- }
- const feature_list[] =
- {
- {"mmx", P_MMX},
- {"sse", P_SSE},
- {"sse2", P_SSE2},
- {"sse3", P_SSE3},
- {"sse4a", P_SSE4_A},
- {"ssse3", P_SSSE3},
- {"sse4.1", P_SSE4_1},
- {"sse4.2", P_SSE4_2},
- {"popcnt", P_POPCNT},
- {"aes", P_AES},
- {"pclmul", P_PCLMUL},
- {"avx", P_AVX},
- {"bmi", P_BMI},
- {"fma4", P_FMA4},
- {"xop", P_XOP},
- {"fma", P_FMA},
- {"bmi2", P_BMI2},
- {"avx2", P_AVX2},
- {"avx512f", P_AVX512F}
- };
-
-
static unsigned int NUM_FEATURES
- = sizeof (feature_list) / sizeof (struct _feature_list);
+ = sizeof (isa_names_table) / sizeof (_isa_names_table);
unsigned int i;
}
for (i = 0; i < NUM_FEATURES; ++i)
{
- if (strcmp (token, feature_list[i].name) == 0)
+ if (strcmp (token, isa_names_table[i].name) == 0)
{
if (predicate_list)
{
predicate_arg = build_string_literal (
- strlen (feature_list[i].name) + 1,
- feature_list[i].name);
+ strlen (isa_names_table[i].name) + 1,
+ isa_names_table[i].name);
predicate_chain = tree_cons (predicate_decl, predicate_arg,
predicate_chain);
}
/* Find the maximum priority feature. */
- if (feature_list[i].priority > priority)
- priority = feature_list[i].priority;
+ if (isa_names_table[i].priority > priority)
+ priority = isa_names_table[i].priority;
break;
}
}
- if (predicate_list && i == NUM_FEATURES)
+ if (predicate_list && priority == P_ZERO)
{
error_at (DECL_SOURCE_LOCATION (decl),
- "no dispatcher found for %s", token);
+ "ISA %qs is not supported in %<target%> attribute, "
+ "use %<arch=%> syntax", token);
return 0;
}
token = strtok (NULL, ",");
DECL_FUNCTION_CODE (fndecl);
tree param_string_cst = NULL;
- /* This is the order of bit-fields in __processor_features in cpuinfo.c */
- enum processor_features
- {
- F_CMOV = 0,
- F_MMX,
- F_POPCNT,
- F_SSE,
- F_SSE2,
- F_SSE3,
- F_SSSE3,
- F_SSE4_1,
- F_SSE4_2,
- F_AVX,
- F_AVX2,
- F_SSE4_A,
- F_FMA4,
- F_XOP,
- F_FMA,
- F_AVX512F,
- F_BMI,
- F_BMI2,
- F_AES,
- F_PCLMUL,
- F_AVX512VL,
- F_AVX512BW,
- F_AVX512DQ,
- F_AVX512CD,
- F_AVX512ER,
- F_AVX512PF,
- F_AVX512VBMI,
- F_AVX512IFMA,
- F_AVX5124VNNIW,
- F_AVX5124FMAPS,
- F_AVX512VPOPCNTDQ,
- F_AVX512VBMI2,
- F_GFNI,
- F_VPCLMULQDQ,
- F_AVX512VNNI,
- F_AVX512BITALG,
- F_MAX
- };
-
- /* These are the values for vendor types and cpu types and subtypes
- in cpuinfo.c. Cpu types and subtypes should be subtracted by
- the corresponding start value. */
- enum processor_model
- {
- M_INTEL = 1,
- M_AMD,
- M_CPU_TYPE_START,
- M_INTEL_BONNELL,
- M_INTEL_CORE2,
- M_INTEL_COREI7,
- M_AMDFAM10H,
- M_AMDFAM15H,
- M_INTEL_SILVERMONT,
- M_INTEL_KNL,
- M_AMD_BTVER1,
- M_AMD_BTVER2,
- M_AMDFAM17H,
- M_INTEL_KNM,
- M_INTEL_GOLDMONT,
- M_INTEL_GOLDMONT_PLUS,
- M_INTEL_TREMONT,
- M_CPU_SUBTYPE_START,
- M_INTEL_COREI7_NEHALEM,
- M_INTEL_COREI7_WESTMERE,
- M_INTEL_COREI7_SANDYBRIDGE,
- M_AMDFAM10H_BARCELONA,
- M_AMDFAM10H_SHANGHAI,
- M_AMDFAM10H_ISTANBUL,
- M_AMDFAM15H_BDVER1,
- M_AMDFAM15H_BDVER2,
- M_AMDFAM15H_BDVER3,
- M_AMDFAM15H_BDVER4,
- M_AMDFAM17H_ZNVER1,
- M_INTEL_COREI7_IVYBRIDGE,
- M_INTEL_COREI7_HASWELL,
- M_INTEL_COREI7_BROADWELL,
- M_INTEL_COREI7_SKYLAKE,
- M_INTEL_COREI7_SKYLAKE_AVX512,
- M_INTEL_COREI7_CANNONLAKE,
- M_INTEL_COREI7_ICELAKE_CLIENT,
- M_INTEL_COREI7_ICELAKE_SERVER,
- M_AMDFAM17H_ZNVER2,
- M_INTEL_COREI7_CASCADELAKE
- };
-
- static struct _arch_names_table
- {
- const char *const name;
- const enum processor_model model;
- }
- const arch_names_table[] =
- {
- {"amd", M_AMD},
- {"intel", M_INTEL},
- {"atom", M_INTEL_BONNELL},
- {"slm", M_INTEL_SILVERMONT},
- {"core2", M_INTEL_CORE2},
- {"corei7", M_INTEL_COREI7},
- {"nehalem", M_INTEL_COREI7_NEHALEM},
- {"westmere", M_INTEL_COREI7_WESTMERE},
- {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
- {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
- {"haswell", M_INTEL_COREI7_HASWELL},
- {"broadwell", M_INTEL_COREI7_BROADWELL},
- {"skylake", M_INTEL_COREI7_SKYLAKE},
- {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
- {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
- {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
- {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
- {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
- {"bonnell", M_INTEL_BONNELL},
- {"silvermont", M_INTEL_SILVERMONT},
- {"goldmont", M_INTEL_GOLDMONT},
- {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
- {"tremont", M_INTEL_TREMONT},
- {"knl", M_INTEL_KNL},
- {"knm", M_INTEL_KNM},
- {"amdfam10h", M_AMDFAM10H},
- {"barcelona", M_AMDFAM10H_BARCELONA},
- {"shanghai", M_AMDFAM10H_SHANGHAI},
- {"istanbul", M_AMDFAM10H_ISTANBUL},
- {"btver1", M_AMD_BTVER1},
- {"amdfam15h", M_AMDFAM15H},
- {"bdver1", M_AMDFAM15H_BDVER1},
- {"bdver2", M_AMDFAM15H_BDVER2},
- {"bdver3", M_AMDFAM15H_BDVER3},
- {"bdver4", M_AMDFAM15H_BDVER4},
- {"btver2", M_AMD_BTVER2},
- {"amdfam17h", M_AMDFAM17H},
- {"znver1", M_AMDFAM17H_ZNVER1},
- {"znver2", M_AMDFAM17H_ZNVER2},
- };
-
- static struct _isa_names_table
- {
- const char *const name;
- const enum processor_features feature;
- }
- const isa_names_table[] =
- {
- {"cmov", F_CMOV},
- {"mmx", F_MMX},
- {"popcnt", F_POPCNT},
- {"sse", F_SSE},
- {"sse2", F_SSE2},
- {"sse3", F_SSE3},
- {"ssse3", F_SSSE3},
- {"sse4a", F_SSE4_A},
- {"sse4.1", F_SSE4_1},
- {"sse4.2", F_SSE4_2},
- {"avx", F_AVX},
- {"fma4", F_FMA4},
- {"xop", F_XOP},
- {"fma", F_FMA},
- {"avx2", F_AVX2},
- {"avx512f", F_AVX512F},
- {"bmi", F_BMI},
- {"bmi2", F_BMI2},
- {"aes", F_AES},
- {"pclmul", F_PCLMUL},
- {"avx512vl",F_AVX512VL},
- {"avx512bw",F_AVX512BW},
- {"avx512dq",F_AVX512DQ},
- {"avx512cd",F_AVX512CD},
- {"avx512er",F_AVX512ER},
- {"avx512pf",F_AVX512PF},
- {"avx512vbmi",F_AVX512VBMI},
- {"avx512ifma",F_AVX512IFMA},
- {"avx5124vnniw",F_AVX5124VNNIW},
- {"avx5124fmaps",F_AVX5124FMAPS},
- {"avx512vpopcntdq",F_AVX512VPOPCNTDQ},
- {"avx512vbmi2", F_AVX512VBMI2},
- {"gfni", F_GFNI},
- {"vpclmulqdq", F_VPCLMULQDQ},
- {"avx512vnni", F_AVX512VNNI},
- {"avx512bitalg", F_AVX512BITALG}
- };
-
tree __processor_model_type = build_processor_model_struct ();
tree __cpu_model_var = make_var_decl (__processor_model_type,
"__cpu_model");