summaryrefslogtreecommitdiffhomepage
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
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
-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