summaryrefslogtreecommitdiffhomepage
path: root/ir/be
diff options
context:
space:
mode:
authorJohannes Bucher <johannes.bucher2@student.kit.edu>2021-03-10 17:38:18 +0100
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2021-03-22 12:04:24 +0100
commit6f4e380152d6189430c359b2f6c24bcc5bf52f83 (patch)
tree8d3e2095a43068ba43aa30e363b5772870e5e54c /ir/be
parentd893d24f66b2d9ea57e70c65209e9972dfb4b64c (diff)
ia32/amd64: split up architecture variant and cpu features into different bitsets
this allows to add support for more architecture variants and cpu features as the current bitset was nearly full
Diffstat (limited to 'ir/be')
-rw-r--r--ir/be/amd64/amd64_architecture.c18
-rw-r--r--ir/be/ia32/ia32_architecture.c71
-rw-r--r--ir/be/ia32/x86_architecture.c90
-rw-r--r--ir/be/ia32/x86_architecture.h147
4 files changed, 204 insertions, 122 deletions
diff --git a/ir/be/amd64/amd64_architecture.c b/ir/be/amd64/amd64_architecture.c
index 795717d..bb474d5 100644
--- a/ir/be/amd64/amd64_architecture.c
+++ b/ir/be/amd64/amd64_architecture.c
@@ -9,8 +9,10 @@
amd64_code_gen_config_t amd64_cg_config;
-static cpu_arch_features arch = cpu_generic64;
-static cpu_arch_features opt_arch = 0;
+static x86_cpu arch_val = cpu_generic64;
+static x86_cpu opt_arch_val = cpu_autodetect;
+static cpu_arch_features arch;
+static cpu_arch_features opt_arch;
static bool use_red_zone = false;
static bool use_scalar_fma3 = false;
@@ -26,11 +28,11 @@ static const lc_opt_enum_int_items_t arch_items[] = {
};
static lc_opt_enum_int_var_t arch_var = {
- (int*) &arch, arch_items
+ (int*) &arch_val, arch_items
};
static lc_opt_enum_int_var_t opt_arch_var = {
- (int*) &opt_arch, arch_items
+ (int*) &opt_arch_val, arch_items
};
static const lc_opt_table_entry_t amd64_architecture_options[] = {
@@ -43,20 +45,22 @@ static const lc_opt_table_entry_t amd64_architecture_options[] = {
void amd64_setup_cg_config(void)
{
+ arch = cpu_arch_feature_defs[arch_val];
+ opt_arch = cpu_arch_feature_defs[opt_arch_val];
/* auto detection code only works if we're on an x86 cpu obviously */
#ifdef NATIVE_X86
- if (arch == cpu_autodetect) {
+ if (arch_val == cpu_autodetect) {
arch = autodetect_arch();
opt_arch = arch;
}
#endif
- if (opt_arch == 0)
+ if (opt_arch_val == cpu_autodetect)
opt_arch = arch;
amd64_code_gen_config_t *const c = &amd64_cg_config;
memset(c, 0, sizeof(*c));
- c->use_scalar_fma3 = flags(arch, arch_feature_fma) && use_scalar_fma3;
+ c->use_scalar_fma3 = feature_flags(arch, arch_feature_fma) && use_scalar_fma3;
}
void amd64_init_architecture(void)
diff --git a/ir/be/ia32/ia32_architecture.c b/ir/be/ia32/ia32_architecture.c
index 160ead8..38c3570 100644
--- a/ir/be/ia32/ia32_architecture.c
+++ b/ir/be/ia32/ia32_architecture.c
@@ -35,8 +35,10 @@ static bool use_sse4_2 = false;
static bool use_sse4a = false;
static bool use_sse5 = false;
static bool use_ssse3 = false;
-static cpu_arch_features arch = cpu_generic;
-static cpu_arch_features opt_arch = 0;
+static x86_cpu arch_val = cpu_generic;
+static x86_cpu opt_arch_val = cpu_autodetect;
+static cpu_arch_features arch;
+static cpu_arch_features opt_arch;
static int fpu_arch = 0;
static bool opt_cc = true;
static bool opt_unsafe_floatconv = false;
@@ -102,11 +104,11 @@ static const lc_opt_enum_int_items_t arch_items[] = {
};
static lc_opt_enum_int_var_t arch_var = {
- (int*) &arch, arch_items
+ (int*) &arch_val, arch_items
};
static lc_opt_enum_int_var_t opt_arch_var = {
- (int*) &opt_arch, arch_items
+ (int*) &opt_arch_val, arch_items
};
typedef enum ia32_fpu_mode_t {
@@ -335,7 +337,7 @@ static void set_arch_costs(void)
arch_costs = &size_cost;
return;
}
- switch (opt_arch & arch_mask) {
+ switch (opt_arch.arch) {
case arch_i386: arch_costs = &i386_cost; break;
case arch_i486: arch_costs = &i486_cost; break;
case arch_pentium: arch_costs = &pentium_cost; break;
@@ -393,16 +395,19 @@ int ia32_evaluate_insn(insn_kind kind, const ir_mode *mode, ir_tarval *tv)
void ia32_setup_cg_config(void)
{
+ arch = cpu_arch_feature_defs[arch_val];
+ opt_arch = cpu_arch_feature_defs[opt_arch_val];
+
if (use_softfloat)
fpu_arch = IA32_FPU_SOFTFLOAT;
#ifdef NATIVE_X86
- if (arch == cpu_autodetect) {
+ if (arch_val == cpu_autodetect) {
arch = autodetect_arch();
opt_arch = arch;
}
#endif
- if (opt_arch == 0)
+ if (opt_arch_val == cpu_autodetect)
opt_arch = arch;
set_arch_costs();
@@ -412,33 +417,33 @@ void ia32_setup_cg_config(void)
c->optimize_size = opt_size != 0;
/* on newer intel cpus mov, pop is often faster than leave although it has a
* longer opcode */
- c->use_leave = flags(opt_arch, arch_i386 | arch_all_amd | arch_core2) || opt_size;
+ c->use_leave = arch_flags(opt_arch, arch_i386 | arch_all_amd | arch_core2) || opt_size;
/* P4s don't like inc/decs because they only partially write the flags
* register which produces false dependencies */
- c->use_incdec = !flags(opt_arch, arch_netburst | arch_nocona | arch_core2 | arch_geode) || opt_size;
+ c->use_incdec = !arch_flags(opt_arch, arch_netburst | arch_nocona | arch_core2 | arch_geode) || opt_size;
c->use_softfloat = (fpu_arch & IA32_FPU_SOFTFLOAT) != 0;
- c->use_sse2 = (fpu_arch & IA32_FPU_SSE2) != 0 && flags(arch, arch_feature_sse2);
- c->use_ffreep = flags(opt_arch, arch_athlon_plus);
- c->use_femms = flags(opt_arch, arch_athlon_plus) && flags(arch, arch_feature_3DNow);
- c->use_fucomi = flags(arch, arch_feature_p6_insn);
- c->use_cmov = flags(arch, arch_feature_cmov) && use_cmov;
- c->use_modeD_moves = flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_geode);
- c->use_add_esp_4 = flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_geode) && !opt_size;
- c->use_add_esp_8 = flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_geode | arch_i386 | arch_i486) && !opt_size;
- c->use_sub_esp_4 = flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro) && !opt_size;
- c->use_sub_esp_8 = flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_i386 | arch_i486) && !opt_size;
- c->use_imul_mem_imm32 = !flags(opt_arch, arch_k8 | arch_k10) || opt_size;
- c->use_pxor = flags(opt_arch, arch_netburst);
- c->use_mov_0 = flags(opt_arch, arch_k6) && !opt_size;
- c->use_short_sex_eax = !flags(opt_arch, arch_k6) || opt_size;
- c->use_pad_return = flags(opt_arch, arch_athlon_plus) && !opt_size;
- c->use_bt = flags(opt_arch, arch_core2 | arch_athlon_plus) || opt_size;
- c->use_fisttp = flags(opt_arch & arch, arch_feature_sse3);
- c->use_sse_prefetch = flags(arch, (arch_feature_3DNowE | arch_feature_sse1));
- c->use_3dnow_prefetch = flags(arch, arch_feature_3DNow);
- c->use_popcnt = flags(arch, arch_feature_popcnt);
- c->use_bswap = (arch & arch_mask) >= arch_i486;
- c->use_cmpxchg = (arch & arch_mask) != arch_i386;
+ c->use_sse2 = (fpu_arch & IA32_FPU_SSE2) != 0 && feature_flags(arch, arch_feature_sse2);
+ c->use_ffreep = arch_flags(opt_arch, arch_athlon_plus);
+ c->use_femms = arch_flags(opt_arch, arch_athlon_plus) && feature_flags(arch, arch_feature_3DNow);
+ c->use_fucomi = feature_flags(arch, arch_feature_p6_insn);
+ c->use_cmov = feature_flags(arch, arch_feature_cmov) && use_cmov;
+ c->use_modeD_moves = arch_flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_geode);
+ c->use_add_esp_4 = arch_flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_geode) && !opt_size;
+ c->use_add_esp_8 = arch_flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_geode | arch_i386 | arch_i486) && !opt_size;
+ c->use_sub_esp_4 = arch_flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro) && !opt_size;
+ c->use_sub_esp_8 = arch_flags(opt_arch, arch_generic32 | arch_athlon_plus | arch_netburst | arch_nocona | arch_core2 | arch_ppro | arch_i386 | arch_i486) && !opt_size;
+ c->use_imul_mem_imm32 = !arch_flags(opt_arch, arch_k8 | arch_k10) || opt_size;
+ c->use_pxor = arch_flags(opt_arch, arch_netburst);
+ c->use_mov_0 = arch_flags(opt_arch, arch_k6) && !opt_size;
+ c->use_short_sex_eax = !arch_flags(opt_arch, arch_k6) || opt_size;
+ c->use_pad_return = arch_flags(opt_arch, arch_athlon_plus) && !opt_size;
+ c->use_bt = arch_flags(opt_arch, arch_core2 | arch_athlon_plus) || opt_size;
+ c->use_fisttp = feature_flags(opt_arch, arch_feature_sse3) && feature_flags(arch, arch_feature_sse3);
+ c->use_sse_prefetch = feature_flags(arch, (arch_feature_3DNowE | arch_feature_sse1));
+ c->use_3dnow_prefetch = feature_flags(arch, arch_feature_3DNow);
+ c->use_popcnt = feature_flags(arch, arch_feature_popcnt);
+ c->use_bswap = (arch.arch) >= arch_i486;
+ c->use_cmpxchg = (arch.arch) != arch_i386;
c->optimize_cc = opt_cc;
c->use_unsafe_floatconv = opt_unsafe_floatconv;
c->emit_machcode = emit_machcode;
@@ -448,8 +453,8 @@ void ia32_setup_cg_config(void)
c->label_alignment_max_skip = arch_costs->label_alignment_max_skip;
c->label_alignment_factor =
- flags(opt_arch, arch_i386 | arch_i486) || opt_size ? 0 :
- opt_arch & arch_all_amd ? 3 :
+ arch_flags(opt_arch, arch_i386 | arch_i486) || opt_size ? 0 :
+ arch_flags(opt_arch, arch_all_amd) ? 3 :
2;
}
diff --git a/ir/be/ia32/x86_architecture.c b/ir/be/ia32/x86_architecture.c
index 3e3ad4c..79a0ebb 100644
--- a/ir/be/ia32/x86_architecture.c
+++ b/ir/be/ia32/x86_architecture.c
@@ -75,9 +75,58 @@ enum {
CPUID_FEAT_EDX_PBE = 1 << 31
};
+cpu_arch_features cpu_arch_feature_defs[cpu_max] = {
+ [cpu_generic] = {arch_generic32, arch_feature_none},
+ [cpu_generic64] = {arch_generic32, arch_64bit_insn},
+
+ /* Intel CPUs */
+ [cpu_i386] = {arch_i386, arch_feature_none},
+ [cpu_i486] = {arch_i486, arch_feature_none},
+ [cpu_pentium] = {arch_pentium, arch_feature_none},
+ [cpu_pentium_mmx] = {arch_pentium, arch_mmx_insn},
+ [cpu_pentium_pro_generic] = {arch_ppro, arch_feature_p6_insn},
+ [cpu_pentium_pro] = {arch_ppro, arch_feature_cmov | arch_feature_p6_insn},
+ [cpu_pentium_2] = {arch_ppro, arch_feature_cmov | arch_feature_p6_insn | arch_mmx_insn},
+ [cpu_pentium_3] = {arch_ppro, arch_feature_cmov | arch_feature_p6_insn | arch_sse1_insn},
+ [cpu_pentium_m] = {arch_ppro, arch_feature_cmov | arch_feature_p6_insn | arch_sse2_insn},
+ [cpu_netburst_generic] = {arch_netburst, arch_feature_p6_insn},
+ [cpu_pentium_4] = {arch_netburst, arch_feature_cmov | arch_feature_p6_insn | arch_sse2_insn},
+ [cpu_prescott] = {arch_nocona, arch_feature_cmov | arch_feature_p6_insn | arch_sse3_insn},
+ [cpu_nocona] = {arch_nocona, arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse3_insn},
+ [cpu_core2_generic] = {arch_core2, arch_feature_p6_insn},
+ [cpu_core2] = {arch_core2, arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_ssse3_insn},
+ [cpu_penryn] = {arch_core2, arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse4_1_insn},
+ [cpu_atom_generic] = {arch_atom, arch_feature_p6_insn},
+ [cpu_atom] = {arch_atom, arch_feature_cmov | arch_feature_p6_insn | arch_ssse3_insn},
+
+
+ /* AMD CPUs */
+ [cpu_k6_generic] = {arch_k6, arch_feature_none},
+ [cpu_k6] = {arch_k6, arch_mmx_insn},
+ [cpu_k6_PLUS] = {arch_k6, arch_3DNow_insn},
+ [cpu_geode_generic] = {arch_geode, arch_feature_none},
+ [cpu_geode] = {arch_geode, arch_sse1_insn | arch_3DNowE_insn},
+ [cpu_athlon_generic] = {arch_athlon, arch_feature_p6_insn},
+ [cpu_athlon_old] = {arch_athlon, arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn},
+ [cpu_athlon] = {arch_athlon, arch_sse1_insn | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn},
+ [cpu_athlon64] = {arch_athlon, arch_sse2_insn | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn},
+ [cpu_k8_generic] = {arch_k8, arch_feature_p6_insn},
+ [cpu_k8] = {arch_k8, arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn},
+ [cpu_k8_sse3] = {arch_k8, arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse3_insn},
+ [cpu_k10_generic] = {arch_k10, arch_feature_p6_insn},
+ [cpu_k10] = {arch_k10, arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_feature_popcnt | arch_64bit_insn | arch_sse4a_insn},
+
+ /* other CPUs */
+ [cpu_winchip_c6] = {arch_i486, arch_feature_mmx},
+ [cpu_winchip2] = {arch_i486, arch_feature_mmx | arch_feature_3DNow},
+ [cpu_c3] = {arch_i486, arch_feature_mmx | arch_feature_3DNow},
+ [cpu_c3_2] = {arch_ppro, arch_feature_cmov | arch_feature_p6_insn | arch_sse1_insn}, /* really no 3DNow! */
+
+};
+
static cpu_arch_features auto_detect_Intel(x86_cpu_info_t const *info)
{
- cpu_arch_features auto_arch = cpu_generic;
+ x86_cpu auto_arch = cpu_generic;
unsigned family = info->cpu_ext_family + info->cpu_family;
unsigned model = (info->cpu_ext_model << 4) | info->cpu_model;
@@ -144,12 +193,12 @@ static cpu_arch_features auto_detect_Intel(x86_cpu_info_t const *info)
break;
}
- return auto_arch;
+ return cpu_arch_feature_defs[auto_arch];
}
static cpu_arch_features auto_detect_AMD(x86_cpu_info_t const *info)
{
- cpu_arch_features auto_arch = cpu_generic;
+ x86_cpu auto_arch = cpu_generic;
unsigned family, model;
@@ -219,7 +268,7 @@ static cpu_arch_features auto_detect_AMD(x86_cpu_info_t const *info)
break;
}
- return auto_arch;
+ return cpu_arch_feature_defs[auto_arch];
}
typedef union {
@@ -300,7 +349,7 @@ static bool x86_toggle_cpuid(void)
cpu_arch_features autodetect_arch(void)
{
- cpu_arch_features auto_arch = cpu_generic;
+ cpu_arch_features auto_arch = cpu_arch_feature_defs[cpu_generic];
/* We use the cpuid instruction to detect the CPU features */
if (x86_toggle_cpuid()) {
@@ -333,36 +382,41 @@ cpu_arch_features autodetect_arch(void)
} else if (streq(vendorid, "AuthenticAMD")) {
auto_arch = auto_detect_AMD(&cpu_info);
} else if (streq(vendorid, "Geode by NSC")) {
- auto_arch = cpu_geode_generic;
+ auto_arch = cpu_arch_feature_defs[cpu_geode_generic];
}
if (cpu_info.edx_features & CPUID_FEAT_EDX_CMOV)
- auto_arch |= arch_feature_cmov;
+ auto_arch.features |= arch_feature_cmov;
if (cpu_info.edx_features & CPUID_FEAT_EDX_MMX)
- auto_arch |= arch_feature_mmx;
+ auto_arch.features |= arch_feature_mmx;
if (cpu_info.edx_features & CPUID_FEAT_EDX_SSE)
- auto_arch |= arch_feature_sse1;
+ auto_arch.features |= arch_feature_sse1;
if (cpu_info.edx_features & CPUID_FEAT_EDX_SSE2)
- auto_arch |= arch_feature_sse2;
+ auto_arch.features |= arch_feature_sse2;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_SSE3)
- auto_arch |= arch_feature_sse3;
+ auto_arch.features |= arch_feature_sse3;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_SSSE3)
- auto_arch |= arch_feature_ssse3;
+ auto_arch.features |= arch_feature_ssse3;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_SSE4_1)
- auto_arch |= arch_feature_sse4_1;
+ auto_arch.features |= arch_feature_sse4_1;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_SSE4_2)
- auto_arch |= arch_feature_sse4_2;
+ auto_arch.features |= arch_feature_sse4_2;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_POPCNT)
- auto_arch |= arch_feature_popcnt;
+ auto_arch.features |= arch_feature_popcnt;
if (cpu_info.ecx_features & CPUID_FEAT_ECX_FMA)
- auto_arch |= arch_feature_fma;
+ auto_arch.features |= arch_feature_fma;
}
return auto_arch;
}
-bool flags(cpu_arch_features features, cpu_arch_features flags)
+bool arch_flags(cpu_arch_features features, x86_cpu_architectures flags)
+{
+ return (features.arch & flags) != 0;
+}
+
+bool feature_flags(cpu_arch_features features, x86_cpu_features flags)
{
- return (features & flags) != 0;
+ return (features.features & flags) != 0;
}
diff --git a/ir/be/ia32/x86_architecture.h b/ir/be/ia32/x86_architecture.h
index cdbb804..7d01a9f 100644
--- a/ir/be/ia32/x86_architecture.h
+++ b/ir/be/ia32/x86_architecture.h
@@ -17,10 +17,9 @@
#endif
#endif
-/**
- * CPU architectures and features.
- */
-typedef enum cpu_arch_features {
+
+
+typedef enum x86_cpu_architectures {
arch_generic32 = 0x00000001, /**< no specific architecture */
arch_i386 = 0x00000002, /**< i386 architecture */
@@ -38,26 +37,34 @@ typedef enum cpu_arch_features {
arch_k8 = 0x00001000, /**< K8/Opteron architecture */
arch_k10 = 0x00002000, /**< K10/Barcelona architecture */
- arch_mask = 0x00003FFF,
-
arch_athlon_plus = arch_athlon | arch_k8 | arch_k10,
arch_all_amd = arch_k6 | arch_geode | arch_athlon_plus,
- arch_feature_mmx = 0x00004000, /**< MMX instructions */
- arch_feature_cmov = 0x00008000, /**< cmov instructions */
- arch_feature_p6_insn = 0x00010000, /**< PentiumPro instructions */
- arch_feature_sse1 = 0x00020000, /**< SSE1 instructions */
- arch_feature_sse2 = 0x00040000, /**< SSE2 instructions */
- arch_feature_sse3 = 0x00080000, /**< SSE3 instructions */
- arch_feature_ssse3 = 0x00100000, /**< SSSE3 instructions */
- arch_feature_3DNow = 0x00200000, /**< 3DNow! instructions */
- arch_feature_3DNowE = 0x00400000, /**< Enhanced 3DNow! instructions */
- arch_feature_64bit = 0x00800000, /**< x86_64 support */
- arch_feature_sse4_1 = 0x01000000, /**< SSE4.1 instructions */
- arch_feature_sse4_2 = 0x02000000, /**< SSE4.2 instructions */
- arch_feature_sse4a = 0x04000000, /**< SSE4a instructions */
- arch_feature_popcnt = 0x08000000, /**< popcnt instruction */
- arch_feature_fma = 0x10000000, /**< FMA instructions */
+} x86_cpu_architectures;
+ENUM_BITSET(x86_cpu_architectures)
+
+/**
+ * CPU architectures and features.
+ */
+typedef enum x86_cpu_features {
+
+ arch_feature_none = 0,
+
+ arch_feature_mmx = 0x00000001, /**< MMX instructions */
+ arch_feature_cmov = 0x00000002, /**< cmov instructions */
+ arch_feature_p6_insn = 0x00000004, /**< PentiumPro instructions */
+ arch_feature_sse1 = 0x00000008, /**< SSE1 instructions */
+ arch_feature_sse2 = 0x00000010, /**< SSE2 instructions */
+ arch_feature_sse3 = 0x00000020, /**< SSE3 instructions */
+ arch_feature_ssse3 = 0x00000040, /**< SSSE3 instructions */
+ arch_feature_3DNow = 0x00000080, /**< 3DNow! instructions */
+ arch_feature_3DNowE = 0x00000100, /**< Enhanced 3DNow! instructions */
+ arch_feature_64bit = 0x00000200, /**< x86_64 support */
+ arch_feature_sse4_1 = 0x00000400, /**< SSE4.1 instructions */
+ arch_feature_sse4_2 = 0x00000800, /**< SSE4.2 instructions */
+ arch_feature_sse4a = 0x00001000, /**< SSE4a instructions */
+ arch_feature_popcnt = 0x00002000, /**< popcnt instruction */
+ arch_feature_fma = 0x00004000, /**< FMA instructions */
arch_mmx_insn = arch_feature_mmx, /**< MMX instructions */
arch_sse1_insn = arch_feature_sse1 | arch_mmx_insn, /**< SSE1 instructions, include MMX */
@@ -72,59 +79,71 @@ typedef enum cpu_arch_features {
arch_3DNowE_insn = arch_feature_3DNowE | arch_3DNow_insn, /**< Enhanced 3DNow! instructions */
arch_64bit_insn = arch_feature_64bit | arch_sse2_insn, /**< x86_64 support, includes SSE2 */
- arch_generic64 = arch_generic32 | arch_64bit_insn,
+} x86_cpu_features;
+ENUM_BITSET(x86_cpu_features)
+
+typedef struct cpu_arch_features {
+ x86_cpu_architectures arch;
+ x86_cpu_features features;
+} cpu_arch_features;
+
- cpu_generic = arch_generic32,
- cpu_generic64 = arch_generic64,
+typedef enum x86_cpu {
+ cpu_autodetect = 0,
+ cpu_generic = 1,
+ cpu_generic64,
/* intel CPUs */
- cpu_i386 = arch_i386,
- cpu_i486 = arch_i486,
- cpu_pentium = arch_pentium,
- cpu_pentium_mmx = arch_pentium | arch_mmx_insn,
- cpu_pentium_pro_generic = arch_ppro | arch_feature_p6_insn,
- cpu_pentium_pro = arch_ppro | arch_feature_cmov | arch_feature_p6_insn,
- cpu_pentium_2 = arch_ppro | arch_feature_cmov | arch_feature_p6_insn | arch_mmx_insn,
- cpu_pentium_3 = arch_ppro | arch_feature_cmov | arch_feature_p6_insn | arch_sse1_insn,
- cpu_pentium_m = arch_ppro | arch_feature_cmov | arch_feature_p6_insn | arch_sse2_insn,
- cpu_netburst_generic = arch_netburst | arch_feature_p6_insn,
- cpu_pentium_4 = arch_netburst | arch_feature_cmov | arch_feature_p6_insn | arch_sse2_insn,
- cpu_prescott = arch_nocona | arch_feature_cmov | arch_feature_p6_insn | arch_sse3_insn,
- cpu_nocona = arch_nocona | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse3_insn,
- cpu_core2_generic = arch_core2 | arch_feature_p6_insn,
- cpu_core2 = arch_core2 | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_ssse3_insn,
- cpu_penryn = arch_core2 | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse4_1_insn,
- cpu_atom_generic = arch_atom | arch_feature_p6_insn,
- cpu_atom = arch_atom | arch_feature_cmov | arch_feature_p6_insn | arch_ssse3_insn,
+ cpu_i386,
+ cpu_i486,
+ cpu_pentium,
+ cpu_pentium_mmx,
+ cpu_pentium_pro_generic,
+ cpu_pentium_pro,
+ cpu_pentium_2,
+ cpu_pentium_3,
+ cpu_pentium_m,
+ cpu_netburst_generic,
+ cpu_pentium_4,
+ cpu_prescott,
+ cpu_nocona,
+ cpu_core2_generic,
+ cpu_core2,
+ cpu_penryn,
+ cpu_atom_generic,
+ cpu_atom,
/* AMD CPUs */
- cpu_k6_generic = arch_k6,
- cpu_k6 = arch_k6 | arch_mmx_insn,
- cpu_k6_PLUS = arch_k6 | arch_3DNow_insn,
- cpu_geode_generic = arch_geode,
- cpu_geode = arch_geode | arch_sse1_insn | arch_3DNowE_insn,
- cpu_athlon_generic = arch_athlon | arch_feature_p6_insn,
- cpu_athlon_old = arch_athlon | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn,
- cpu_athlon = arch_athlon | arch_sse1_insn | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn,
- cpu_athlon64 = arch_athlon | arch_sse2_insn | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn,
- cpu_k8_generic = arch_k8 | arch_feature_p6_insn,
- cpu_k8 = arch_k8 | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn,
- cpu_k8_sse3 = arch_k8 | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_64bit_insn | arch_sse3_insn,
- cpu_k10_generic = arch_k10 | arch_feature_p6_insn,
- cpu_k10 = arch_k10 | arch_3DNowE_insn | arch_feature_cmov | arch_feature_p6_insn | arch_feature_popcnt | arch_64bit_insn | arch_sse4a_insn,
+ cpu_k6_generic,
+ cpu_k6,
+ cpu_k6_PLUS,
+ cpu_geode_generic,
+ cpu_geode,
+ cpu_athlon_generic,
+ cpu_athlon_old,
+ cpu_athlon,
+ cpu_athlon64,
+ cpu_k8_generic,
+ cpu_k8,
+ cpu_k8_sse3,
+ cpu_k10_generic,
+ cpu_k10,
/* other CPUs */
- cpu_winchip_c6 = arch_i486 | arch_feature_mmx,
- cpu_winchip2 = arch_i486 | arch_feature_mmx | arch_feature_3DNow,
- cpu_c3 = arch_i486 | arch_feature_mmx | arch_feature_3DNow,
- cpu_c3_2 = arch_ppro | arch_feature_cmov | arch_feature_p6_insn | arch_sse1_insn, /* really no 3DNow! */
+ cpu_winchip_c6,
+ cpu_winchip2,
+ cpu_c3,
+ cpu_c3_2,
- cpu_autodetect = 0,
-} cpu_arch_features;
-ENUM_BITSET(cpu_arch_features)
+ cpu_max
+} x86_cpu;
+
+extern cpu_arch_features cpu_arch_feature_defs[];
cpu_arch_features autodetect_arch(void);
-bool flags(cpu_arch_features features, cpu_arch_features flags);
+bool arch_flags(cpu_arch_features arch_features, x86_cpu_architectures flags);
+
+bool feature_flags(cpu_arch_features arch_features, x86_cpu_features flags);
#endif