#include "modules/arch/x86/x86arch.h"
-enum cpu_mode {
- CPU_MODE_VERBATIM = 1,
- CPU_MODE_SET,
- CPU_MODE_CLEAR
-};
+#define PROC_8086 0
+#define PROC_186 1
+#define PROC_286 2
+#define PROC_386 3
+#define PROC_486 4
+#define PROC_586 5
+#define PROC_686 6
+#define PROC_p2 7
+#define PROC_p3 8
+#define PROC_p4 9
+#define PROC_prescott 10
+#define PROC_conroe 11
+#define PROC_penryn 12
+#define PROC_nehalem 13
+
+static void
+x86_cpu_intel(wordptr cpu, unsigned int data)
+{
+ BitVector_Empty(cpu);
+
+ BitVector_Bit_On(cpu, CPU_Priv);
+ if (data >= PROC_286)
+ BitVector_Bit_On(cpu, CPU_Prot);
+ if (data >= PROC_386)
+ BitVector_Bit_On(cpu, CPU_SMM);
+ if (data >= PROC_nehalem)
+ BitVector_Bit_On(cpu, CPU_SSE42);
+ if (data >= PROC_penryn)
+ BitVector_Bit_On(cpu, CPU_SSE41);
+ if (data >= PROC_conroe)
+ BitVector_Bit_On(cpu, CPU_SSSE3);
+ if (data >= PROC_prescott)
+ BitVector_Bit_On(cpu, CPU_SSE3);
+ if (data >= PROC_p4)
+ BitVector_Bit_On(cpu, CPU_SSE2);
+ if (data >= PROC_p3)
+ BitVector_Bit_On(cpu, CPU_SSE);
+ if (data >= PROC_p2)
+ BitVector_Bit_On(cpu, CPU_MMX);
+ if (data >= PROC_486)
+ BitVector_Bit_On(cpu, CPU_FPU);
+ if (data >= PROC_prescott)
+ BitVector_Bit_On(cpu, CPU_EM64T);
+
+ if (data >= PROC_p4)
+ BitVector_Bit_On(cpu, CPU_P4);
+ if (data >= PROC_p3)
+ BitVector_Bit_On(cpu, CPU_P3);
+ if (data >= PROC_686)
+ BitVector_Bit_On(cpu, CPU_686);
+ if (data >= PROC_586)
+ BitVector_Bit_On(cpu, CPU_586);
+ if (data >= PROC_486)
+ BitVector_Bit_On(cpu, CPU_486);
+ if (data >= PROC_386)
+ BitVector_Bit_On(cpu, CPU_386);
+ if (data >= PROC_286)
+ BitVector_Bit_On(cpu, CPU_286);
+ if (data >= PROC_186)
+ BitVector_Bit_On(cpu, CPU_186);
+ BitVector_Bit_On(cpu, CPU_086);
+}
+
+static void
+x86_cpu_ia64(wordptr cpu, unsigned int data)
+{
+ BitVector_Empty(cpu);
+ BitVector_Bit_On(cpu, CPU_Priv);
+ BitVector_Bit_On(cpu, CPU_Prot);
+ BitVector_Bit_On(cpu, CPU_SMM);
+ BitVector_Bit_On(cpu, CPU_SSE2);
+ BitVector_Bit_On(cpu, CPU_SSE);
+ BitVector_Bit_On(cpu, CPU_MMX);
+ BitVector_Bit_On(cpu, CPU_FPU);
+ BitVector_Bit_On(cpu, CPU_IA64);
+ BitVector_Bit_On(cpu, CPU_P4);
+ BitVector_Bit_On(cpu, CPU_P3);
+ BitVector_Bit_On(cpu, CPU_686);
+ BitVector_Bit_On(cpu, CPU_586);
+ BitVector_Bit_On(cpu, CPU_486);
+ BitVector_Bit_On(cpu, CPU_386);
+ BitVector_Bit_On(cpu, CPU_286);
+ BitVector_Bit_On(cpu, CPU_186);
+ BitVector_Bit_On(cpu, CPU_086);
+}
+
+#define PROC_hammer 8
+#define PROC_k7 7
+#define PROC_k6 6
+
+static void
+x86_cpu_amd(wordptr cpu, unsigned int data)
+{
+ BitVector_Empty(cpu);
+
+ BitVector_Bit_On(cpu, CPU_Priv);
+ BitVector_Bit_On(cpu, CPU_Prot);
+ BitVector_Bit_On(cpu, CPU_SMM);
+ BitVector_Bit_On(cpu, CPU_3DNow);
+ if (data >= PROC_hammer)
+ BitVector_Bit_On(cpu, CPU_SSE2);
+ if (data >= PROC_k7)
+ BitVector_Bit_On(cpu, CPU_SSE);
+ if (data >= PROC_k6)
+ BitVector_Bit_On(cpu, CPU_MMX);
+ BitVector_Bit_On(cpu, CPU_FPU);
+
+ if (data >= PROC_hammer)
+ BitVector_Bit_On(cpu, CPU_Hammer);
+ if (data >= PROC_k7)
+ BitVector_Bit_On(cpu, CPU_Athlon);
+ if (data >= PROC_k6)
+ BitVector_Bit_On(cpu, CPU_K6);
+ BitVector_Bit_On(cpu, CPU_686);
+ BitVector_Bit_On(cpu, CPU_586);
+ BitVector_Bit_On(cpu, CPU_486);
+ BitVector_Bit_On(cpu, CPU_386);
+ BitVector_Bit_On(cpu, CPU_286);
+ BitVector_Bit_On(cpu, CPU_186);
+ BitVector_Bit_On(cpu, CPU_086);
+}
+
+static void
+x86_cpu_set(wordptr cpu, unsigned int data)
+{
+ BitVector_Bit_On(cpu, data);
+}
+
+static void
+x86_cpu_clear(wordptr cpu, unsigned int data)
+{
+ BitVector_Bit_Off(cpu, data);
+}
-#define PROC_186 CPU_186|CPU_Priv
-#define PROC_286 CPU_186|CPU_286|CPU_Priv
-#define PROC_386 CPU_186|CPU_286|CPU_386|CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_486 CPU_186|CPU_286|CPU_386|CPU_486|CPU_FPU|CPU_SMM|\
- CPU_Prot|CPU_Priv
-#define PROC_586 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_FPU|\
- CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_686 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_FPU|CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_p2 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_FPU|CPU_MMX|CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_p3 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_P3|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SMM|CPU_Prot|\
- CPU_Priv
-#define PROC_p4 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_P3|CPU_P4|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|\
- CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_ia64 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_P3|CPU_P4|CPU_IA64|CPU_FPU|CPU_MMX|CPU_SSE|\
- CPU_SSE2|CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_k6 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_K6|CPU_FPU|CPU_MMX|CPU_3DNow|CPU_SMM|CPU_Prot|\
- CPU_Priv
-#define PROC_k7 CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_K6|CPU_Athlon|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|\
- CPU_SMM|CPU_Prot|CPU_Priv
-#define PROC_hammer CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_K6|CPU_Athlon|CPU_Hammer|CPU_FPU|CPU_MMX|\
- CPU_SSE|CPU_SSE2|CPU_3DNow|CPU_SMM|CPU_Prot|\
- CPU_Priv
-#define PROC_prescott CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\
- CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SMM|\
- CPU_Prot|CPU_Priv
-#define PROC_conroe CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\
- CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SMM|\
- CPU_Prot|CPU_Priv
-#define PROC_penryn CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\
- CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SSE41|CPU_SMM|\
- CPU_Prot|CPU_Priv
-#define PROC_nehalem CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\
- CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\
- CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SSE41|\
- CPU_SSE42|CPU_SMM|CPU_Prot|CPU_Priv
+static void
+x86_cpu_set_sse4(wordptr cpu, unsigned int data)
+{
+ BitVector_Bit_On(cpu, CPU_SSE41);
+ BitVector_Bit_On(cpu, CPU_SSE42);
+}
+
+static void
+x86_cpu_clear_sse4(wordptr cpu, unsigned int data)
+{
+ BitVector_Bit_Off(cpu, CPU_SSE41);
+ BitVector_Bit_Off(cpu, CPU_SSE42);
+}
%}
%ignore-case
%define lookup-function-name cpu_find
struct cpu_parse_data {
const char *name;
- enum cpu_mode mode;
- unsigned long cpu;
+ void (*handler) (wordptr cpu, unsigned int data);
+ unsigned int data;
};
%%
-8086, CPU_MODE_VERBATIM, CPU_Priv
-186, CPU_MODE_VERBATIM, PROC_186
-80186, CPU_MODE_VERBATIM, PROC_186
-i186, CPU_MODE_VERBATIM, PROC_186
-286, CPU_MODE_VERBATIM, PROC_286
-80286, CPU_MODE_VERBATIM, PROC_286
-i286, CPU_MODE_VERBATIM, PROC_286
-386, CPU_MODE_VERBATIM, PROC_386
-80386, CPU_MODE_VERBATIM, PROC_386
-i386, CPU_MODE_VERBATIM, PROC_386
-486, CPU_MODE_VERBATIM, PROC_486
-80486, CPU_MODE_VERBATIM, PROC_486
-i486, CPU_MODE_VERBATIM, PROC_486
-586, CPU_MODE_VERBATIM, PROC_586
-i586, CPU_MODE_VERBATIM, PROC_586
-pentium, CPU_MODE_VERBATIM, PROC_586
-p5, CPU_MODE_VERBATIM, PROC_586
-686, CPU_MODE_VERBATIM, PROC_686
-i686, CPU_MODE_VERBATIM, PROC_686
-p6, CPU_MODE_VERBATIM, PROC_686
-ppro, CPU_MODE_VERBATIM, PROC_686
-pentiumpro, CPU_MODE_VERBATIM, PROC_686
-p2, CPU_MODE_VERBATIM, PROC_p2
-pentium2, CPU_MODE_VERBATIM, PROC_p2
-pentium-2, CPU_MODE_VERBATIM, PROC_p2
-pentiumii, CPU_MODE_VERBATIM, PROC_p2
-pentium-ii, CPU_MODE_VERBATIM, PROC_p2
-p3, CPU_MODE_VERBATIM, PROC_p3
-pentium3, CPU_MODE_VERBATIM, PROC_p3
-pentium-3, CPU_MODE_VERBATIM, PROC_p3
-pentiumiii, CPU_MODE_VERBATIM, PROC_p3
-pentium-iii, CPU_MODE_VERBATIM, PROC_p3
-katmai, CPU_MODE_VERBATIM, PROC_p3
-p4, CPU_MODE_VERBATIM, PROC_p4
-pentium4, CPU_MODE_VERBATIM, PROC_p4
-pentium-4, CPU_MODE_VERBATIM, PROC_p4
-pentiumiv, CPU_MODE_VERBATIM, PROC_p4
-pentium-iv, CPU_MODE_VERBATIM, PROC_p4
-williamette, CPU_MODE_VERBATIM, PROC_p4
-ia64, CPU_MODE_VERBATIM, PROC_ia64
-ia-64, CPU_MODE_VERBATIM, PROC_ia64
-itanium, CPU_MODE_VERBATIM, PROC_ia64
-k6, CPU_MODE_VERBATIM, PROC_k6
-k7, CPU_MODE_VERBATIM, PROC_k7
-athlon, CPU_MODE_VERBATIM, PROC_k7
-hammer, CPU_MODE_VERBATIM, PROC_hammer
-sledgehammer, CPU_MODE_VERBATIM, PROC_hammer
-opteron, CPU_MODE_VERBATIM, PROC_hammer
-athlon64, CPU_MODE_VERBATIM, PROC_hammer
-athlon-64, CPU_MODE_VERBATIM, PROC_hammer
-prescott, CPU_MODE_VERBATIM, PROC_prescott
-conroe, CPU_MODE_VERBATIM, PROC_conroe
-penryn, CPU_MODE_VERBATIM, PROC_penryn
-nehalem, CPU_MODE_VERBATIM, PROC_nehalem
+8086, x86_cpu_intel, PROC_8086
+186, x86_cpu_intel, PROC_186
+80186, x86_cpu_intel, PROC_186
+i186, x86_cpu_intel, PROC_186
+286, x86_cpu_intel, PROC_286
+80286, x86_cpu_intel, PROC_286
+i286, x86_cpu_intel, PROC_286
+386, x86_cpu_intel, PROC_386
+80386, x86_cpu_intel, PROC_386
+i386, x86_cpu_intel, PROC_386
+486, x86_cpu_intel, PROC_486
+80486, x86_cpu_intel, PROC_486
+i486, x86_cpu_intel, PROC_486
+586, x86_cpu_intel, PROC_586
+i586, x86_cpu_intel, PROC_586
+pentium, x86_cpu_intel, PROC_586
+p5, x86_cpu_intel, PROC_586
+686, x86_cpu_intel, PROC_686
+i686, x86_cpu_intel, PROC_686
+p6, x86_cpu_intel, PROC_686
+ppro, x86_cpu_intel, PROC_686
+pentiumpro, x86_cpu_intel, PROC_686
+p2, x86_cpu_intel, PROC_p2
+pentium2, x86_cpu_intel, PROC_p2
+pentium-2, x86_cpu_intel, PROC_p2
+pentiumii, x86_cpu_intel, PROC_p2
+pentium-ii, x86_cpu_intel, PROC_p2
+p3, x86_cpu_intel, PROC_p3
+pentium3, x86_cpu_intel, PROC_p3
+pentium-3, x86_cpu_intel, PROC_p3
+pentiumiii, x86_cpu_intel, PROC_p3
+pentium-iii, x86_cpu_intel, PROC_p3
+katmai, x86_cpu_intel, PROC_p3
+p4, x86_cpu_intel, PROC_p4
+pentium4, x86_cpu_intel, PROC_p4
+pentium-4, x86_cpu_intel, PROC_p4
+pentiumiv, x86_cpu_intel, PROC_p4
+pentium-iv, x86_cpu_intel, PROC_p4
+williamette, x86_cpu_intel, PROC_p4
+ia64, x86_cpu_ia64, 0
+ia-64, x86_cpu_ia64, 0
+itanium, x86_cpu_ia64, 0
+k6, x86_cpu_amd, PROC_k6
+k7, x86_cpu_amd, PROC_k7
+athlon, x86_cpu_amd, PROC_k7
+hammer, x86_cpu_amd, PROC_hammer
+sledgehammer, x86_cpu_amd, PROC_hammer
+opteron, x86_cpu_amd, PROC_hammer
+athlon64, x86_cpu_amd, PROC_hammer
+athlon-64, x86_cpu_amd, PROC_hammer
+prescott, x86_cpu_intel, PROC_prescott
+conroe, x86_cpu_intel, PROC_conroe
+penryn, x86_cpu_intel, PROC_penryn
+nehalem, x86_cpu_intel, PROC_nehalem
#
# Features have "no" versions to disable them, and only set/reset the
# specific feature being changed. All other bits are left alone.
#
-fpu, CPU_MODE_SET, CPU_FPU
-nofpu, CPU_MODE_CLEAR, CPU_FPU
-mmx, CPU_MODE_SET, CPU_MMX
-nommx, CPU_MODE_CLEAR, CPU_MMX
-sse, CPU_MODE_SET, CPU_SSE
-nosse, CPU_MODE_CLEAR, CPU_SSE
-sse2, CPU_MODE_SET, CPU_SSE2
-nosse2, CPU_MODE_CLEAR, CPU_SSE2
-sse3, CPU_MODE_SET, CPU_SSE3
-nosse3, CPU_MODE_CLEAR, CPU_SSE3
-#pni, CPU_MODE_SET, CPU_PNI
-#nopni, CPU_MODE_CLEAR, CPU_PNI
-3dnow, CPU_MODE_SET, CPU_3DNow
-no3dnow, CPU_MODE_CLEAR, CPU_3DNow
-cyrix, CPU_MODE_SET, CPU_Cyrix
-nocyrix, CPU_MODE_CLEAR, CPU_Cyrix
-amd, CPU_MODE_SET, CPU_AMD
-noamd, CPU_MODE_CLEAR, CPU_AMD
-smm, CPU_MODE_SET, CPU_SMM
-nosmm, CPU_MODE_CLEAR, CPU_SMM
-prot, CPU_MODE_SET, CPU_Prot
-noprot, CPU_MODE_CLEAR, CPU_Prot
-protected, CPU_MODE_SET, CPU_Prot
-noprotected, CPU_MODE_CLEAR, CPU_Prot
-undoc, CPU_MODE_SET, CPU_Undoc
-noundoc, CPU_MODE_CLEAR, CPU_Undoc
-undocumented, CPU_MODE_SET, CPU_Undoc
-noundocumented, CPU_MODE_CLEAR, CPU_Undoc
-obs, CPU_MODE_SET, CPU_Obs
-noobs, CPU_MODE_CLEAR, CPU_Obs
-obsolete, CPU_MODE_SET, CPU_Obs
-noobsolete, CPU_MODE_CLEAR, CPU_Obs
-priv, CPU_MODE_SET, CPU_Priv
-nopriv, CPU_MODE_CLEAR, CPU_Priv
-privileged, CPU_MODE_SET, CPU_Priv
-noprivileged, CPU_MODE_CLEAR, CPU_Priv
-svm, CPU_MODE_SET, CPU_SVM
-nosvm, CPU_MODE_CLEAR, CPU_SVM
-padlock, CPU_MODE_SET, CPU_PadLock
-nopadlock, CPU_MODE_CLEAR, CPU_PadLock
-em64t, CPU_MODE_SET, CPU_EM64T
-noem64t, CPU_MODE_CLEAR, CPU_EM64T
-ssse3, CPU_MODE_SET, CPU_SSSE3
-nossse3, CPU_MODE_CLEAR, CPU_SSSE3
-sse4.1, CPU_MODE_SET, CPU_SSE41
-nosse4.1, CPU_MODE_CLEAR, CPU_SSE41
-sse4.2, CPU_MODE_SET, CPU_SSE42
-nosse4.2, CPU_MODE_CLEAR, CPU_SSE42
-sse4, CPU_MODE_SET, CPU_SSE4
-nosse4, CPU_MODE_CLEAR, CPU_SSE4
+fpu, x86_cpu_set, CPU_FPU
+nofpu, x86_cpu_clear, CPU_FPU
+mmx, x86_cpu_set, CPU_MMX
+nommx, x86_cpu_clear, CPU_MMX
+sse, x86_cpu_set, CPU_SSE
+nosse, x86_cpu_clear, CPU_SSE
+sse2, x86_cpu_set, CPU_SSE2
+nosse2, x86_cpu_clear, CPU_SSE2
+sse3, x86_cpu_set, CPU_SSE3
+nosse3, x86_cpu_clear, CPU_SSE3
+#pni, x86_cpu_set, CPU_PNI
+#nopni, x86_cpu_clear, CPU_PNI
+3dnow, x86_cpu_set, CPU_3DNow
+no3dnow, x86_cpu_clear, CPU_3DNow
+cyrix, x86_cpu_set, CPU_Cyrix
+nocyrix, x86_cpu_clear, CPU_Cyrix
+amd, x86_cpu_set, CPU_AMD
+noamd, x86_cpu_clear, CPU_AMD
+smm, x86_cpu_set, CPU_SMM
+nosmm, x86_cpu_clear, CPU_SMM
+prot, x86_cpu_set, CPU_Prot
+noprot, x86_cpu_clear, CPU_Prot
+protected, x86_cpu_set, CPU_Prot
+noprotected, x86_cpu_clear, CPU_Prot
+undoc, x86_cpu_set, CPU_Undoc
+noundoc, x86_cpu_clear, CPU_Undoc
+undocumented, x86_cpu_set, CPU_Undoc
+noundocumented, x86_cpu_clear, CPU_Undoc
+obs, x86_cpu_set, CPU_Obs
+noobs, x86_cpu_clear, CPU_Obs
+obsolete, x86_cpu_set, CPU_Obs
+noobsolete, x86_cpu_clear, CPU_Obs
+priv, x86_cpu_set, CPU_Priv
+nopriv, x86_cpu_clear, CPU_Priv
+privileged, x86_cpu_set, CPU_Priv
+noprivileged, x86_cpu_clear, CPU_Priv
+svm, x86_cpu_set, CPU_SVM
+nosvm, x86_cpu_clear, CPU_SVM
+padlock, x86_cpu_set, CPU_PadLock
+nopadlock, x86_cpu_clear, CPU_PadLock
+em64t, x86_cpu_set, CPU_EM64T
+noem64t, x86_cpu_clear, CPU_EM64T
+ssse3, x86_cpu_set, CPU_SSSE3
+nossse3, x86_cpu_clear, CPU_SSSE3
+sse4.1, x86_cpu_set, CPU_SSE41
+nosse4.1, x86_cpu_clear, CPU_SSE41
+sse4.2, x86_cpu_set, CPU_SSE42
+nosse4.2, x86_cpu_clear, CPU_SSE42
+sse4, x86_cpu_set_sse4, 0
+nosse4, x86_cpu_clear_sse4, 0
%%
void
size_t cpuid_len)
{
/*@null@*/ const struct cpu_parse_data *pdata;
+ wordptr new_cpu;
+ unsigned int i;
if (cpuid_len > 15)
return;
return;
}
- switch (pdata->mode) {
- case CPU_MODE_VERBATIM:
- arch_x86->cpu_enabled = pdata->cpu;
- break;
- case CPU_MODE_SET:
- arch_x86->cpu_enabled |= pdata->cpu;
- break;
- case CPU_MODE_CLEAR:
- arch_x86->cpu_enabled &= ~pdata->cpu;
- break;
+ new_cpu = BitVector_Clone(arch_x86->cpu_enables[arch_x86->active_cpu]);
+ pdata->handler(new_cpu, pdata->data);
+
+ /* try to find an existing match in the CPU table first */
+ for (i=0; i<arch_x86->cpu_enables_size; i++) {
+ if (BitVector_equal(arch_x86->cpu_enables[i], new_cpu)) {
+ arch_x86->active_cpu = i;
+ BitVector_Destroy(new_cpu);
+ return;
+ }
}
+
+ /* not found, need to add a new entry */
+ arch_x86->active_cpu = arch_x86->cpu_enables_size++;
+ arch_x86->cpu_enables =
+ yasm_xrealloc(arch_x86->cpu_enables,
+ arch_x86->cpu_enables_size*sizeof(wordptr));
+ arch_x86->cpu_enables[arch_x86->active_cpu] = new_cpu;
}
#include "modules/arch/x86/x86arch.h"
-static const char *cpu_find_reverse(unsigned long cpu);
+static const char *cpu_find_reverse(unsigned int cpu0, unsigned int cpu1,
+ unsigned int cpu2);
/* Opcode modifiers. The opcode bytes are in "reverse" order because the
* parameters are read from the arch-specific data in LSB->MSB order.
* cpu_enabled to see if all bits set here are set in cpu_enabled--if so,
* the instruction is available on this CPU.
*/
- unsigned long cpu;
+ unsigned int cpu0:8;
+ unsigned int cpu1:8;
+ unsigned int cpu2:8;
/* Opcode modifiers for variations of instruction. As each modifier reads
* its parameter in LSB->MSB order from the arch-specific data[1] from the
/*@null@*/ const x86_insn_info *group;
/* CPU feature flags enabled at the time of parsing the instruction */
- unsigned long cpu_enabled;
+ wordptr cpu_enabled;
/* Modifier data */
unsigned long mod_data;
YASM_BC_SPECIAL_INSN
};
-/* Empty instruction */
-static const x86_insn_info empty_insn[] = {
- { CPU_Any, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0 }
-};
-
-/* Placeholder for instructions invalid in 64-bit mode */
-static const x86_insn_info not64_insn[] = {
- { CPU_Not64, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0 }
-};
-
#include "x86insns.c"
static void
jmp->nearop.len = 0;
for (; num_info>0 && (jmp->shortop.len == 0 || jmp->nearop.len == 0);
num_info--, info++) {
- unsigned long cpu = info->cpu;
+ unsigned int cpu0 = info->cpu0;
+ unsigned int cpu1 = info->cpu1;
+ unsigned int cpu2 = info->cpu2;
- if ((cpu & CPU_64) && mode_bits != 64)
+ /* Match CPU */
+ if (mode_bits != 64 &&
+ (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64))
continue;
- if ((cpu & CPU_Not64) && mode_bits == 64)
+ if (mode_bits == 64 &&
+ (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64))
continue;
- cpu &= ~(CPU_64 | CPU_Not64);
- if ((id_insn->cpu_enabled & cpu) != cpu)
+ if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
+ cpu0 = CPU_Any;
+ if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
+ cpu1 = CPU_Any;
+ if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
+ cpu2 = CPU_Any;
+ if (!BitVector_bit_test(id_insn->cpu_enabled, cpu0) ||
+ !BitVector_bit_test(id_insn->cpu_enabled, cpu1) ||
+ !BitVector_bit_test(id_insn->cpu_enabled, cpu2))
continue;
if (info->num_operands == 0)
const x86_insn_info *info = id_insn->group;
unsigned int num_info = id_insn->num_info;
unsigned int suffix = id_insn->suffix;
+ unsigned int mode_bits = id_insn->mode_bits;
int found = 0;
/* Just do a simple linear search through the info array for a match.
for (; num_info>0 && !found; num_info--, info++) {
yasm_insn_operand *op, **use_ops;
const unsigned long *info_ops = &insn_operands[info->operands_index];
- unsigned long icpu;
+ unsigned int cpu0 = info->cpu0;
+ unsigned int cpu1 = info->cpu1;
+ unsigned int cpu2 = info->cpu2;
unsigned int size;
int mismatch = 0;
int i;
/* Match CPU */
- icpu = info->cpu;
-
- if ((icpu & CPU_64) && id_insn->mode_bits != 64)
+ if (mode_bits != 64 &&
+ (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64))
continue;
- if ((icpu & CPU_Not64) && id_insn->mode_bits == 64)
+ if (mode_bits == 64 &&
+ (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64))
continue;
- icpu &= ~(CPU_64 | CPU_Not64);
- if (bypass != 7 && (id_insn->cpu_enabled & icpu) != icpu)
+ if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
+ cpu0 = CPU_Any;
+ if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
+ cpu1 = CPU_Any;
+ if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
+ cpu2 = CPU_Any;
+ if (bypass != 7 && (!BitVector_bit_test(id_insn->cpu_enabled, cpu0) ||
+ !BitVector_bit_test(id_insn->cpu_enabled, cpu1) ||
+ !BitVector_bit_test(id_insn->cpu_enabled, cpu2)))
continue;
/* Match # of operands */
N_("invalid size for operand %d"), 3);
break;
case 7:
+ {
+ unsigned int cpu0 = i->cpu0, cpu1 = i->cpu1, cpu2 = i->cpu2;
yasm_error_set(YASM_ERROR_TYPE,
N_("requires CPU%s"),
- cpu_find_reverse(i->cpu & ~(CPU_64 | CPU_Not64)));
+ cpu_find_reverse(cpu0, cpu1, cpu2));
break;
+ }
default:
yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of opcode and operands"));
yasm_x86__bc_transform_insn(bc, insn);
}
+/* suffix flags for instructions */
+enum {
+ NONE = 0,
+ SUF_B = (MOD_GasSufB >> MOD_GasSuf_SHIFT),
+ SUF_W = (MOD_GasSufW >> MOD_GasSuf_SHIFT),
+ SUF_L = (MOD_GasSufL >> MOD_GasSuf_SHIFT),
+ SUF_Q = (MOD_GasSufQ >> MOD_GasSuf_SHIFT),
+ SUF_S = (MOD_GasSufS >> MOD_GasSuf_SHIFT),
+ WEAK = 0x80 /* Relaxed operand mode for GAS */
+} flags;
+
/* Static parse data structure for instructions */
typedef struct insnprefix_parse_data {
const char *name;
*/
unsigned long data1;
- /* For instruction, cpu flags.
+ /* For instruction, suffix flags.
* For prefix, prefix value.
*/
- unsigned long data2;
-
- /* suffix flags for instructions */
- enum {
- NONE = 0,
- SUF_B = (MOD_GasSufB >> MOD_GasSuf_SHIFT),
- SUF_W = (MOD_GasSufW >> MOD_GasSuf_SHIFT),
- SUF_L = (MOD_GasSufL >> MOD_GasSuf_SHIFT),
- SUF_Q = (MOD_GasSufQ >> MOD_GasSuf_SHIFT),
- SUF_S = (MOD_GasSufS >> MOD_GasSuf_SHIFT),
- WEAK = 0x80 /* Relaxed operand mode for GAS */
- } flags;
+ unsigned int flags:8;
+
+ /* CPU flags */
+ unsigned int cpu0:8;
+ unsigned int cpu1:8;
+ unsigned int cpu2:8;
} insnprefix_parse_data;
-#define PREFIX(name, type, value) \
- { name, NULL, type, value, NONE }
/* Pull in all parse data */
#include "x86insn_nasm.c"
#include "x86insn_gas.c"
static const char *
-cpu_find_reverse(unsigned long cpu)
+cpu_find_reverse(unsigned int cpu0, unsigned int cpu1, unsigned int cpu2)
{
static char cpuname[200];
+ wordptr cpu = BitVector_Create(128, TRUE);
+
+ if (cpu0 != CPU_Any)
+ BitVector_Bit_On(cpu, cpu0);
+ if (cpu1 != CPU_Any)
+ BitVector_Bit_On(cpu, cpu1);
+ if (cpu2 != CPU_Any)
+ BitVector_Bit_On(cpu, cpu2);
cpuname[0] = '\0';
- if (cpu & CPU_Prot)
+ if (BitVector_bit_test(cpu, CPU_Prot))
strcat(cpuname, " Protected");
- if (cpu & CPU_Undoc)
+ if (BitVector_bit_test(cpu, CPU_Undoc))
strcat(cpuname, " Undocumented");
- if (cpu & CPU_Obs)
+ if (BitVector_bit_test(cpu, CPU_Obs))
strcat(cpuname, " Obsolete");
- if (cpu & CPU_Priv)
+ if (BitVector_bit_test(cpu, CPU_Priv))
strcat(cpuname, " Privileged");
- if (cpu & CPU_FPU)
+ if (BitVector_bit_test(cpu, CPU_FPU))
strcat(cpuname, " FPU");
- if (cpu & CPU_MMX)
+ if (BitVector_bit_test(cpu, CPU_MMX))
strcat(cpuname, " MMX");
- if (cpu & CPU_SSE)
+ if (BitVector_bit_test(cpu, CPU_SSE))
strcat(cpuname, " SSE");
- if (cpu & CPU_SSE2)
+ if (BitVector_bit_test(cpu, CPU_SSE2))
strcat(cpuname, " SSE2");
- if (cpu & CPU_SSE3)
+ if (BitVector_bit_test(cpu, CPU_SSE3))
strcat(cpuname, " SSE3");
- if (cpu & CPU_3DNow)
+ if (BitVector_bit_test(cpu, CPU_3DNow))
strcat(cpuname, " 3DNow");
- if (cpu & CPU_Cyrix)
+ if (BitVector_bit_test(cpu, CPU_Cyrix))
strcat(cpuname, " Cyrix");
- if (cpu & CPU_AMD)
+ if (BitVector_bit_test(cpu, CPU_AMD))
strcat(cpuname, " AMD");
- if (cpu & CPU_SMM)
+ if (BitVector_bit_test(cpu, CPU_SMM))
strcat(cpuname, " SMM");
- if (cpu & CPU_SVM)
+ if (BitVector_bit_test(cpu, CPU_SVM))
strcat(cpuname, " SVM");
- if (cpu & CPU_PadLock)
+ if (BitVector_bit_test(cpu, CPU_PadLock))
strcat(cpuname, " PadLock");
- if (cpu & CPU_EM64T)
+ if (BitVector_bit_test(cpu, CPU_EM64T))
strcat(cpuname, " EM64T");
- if (cpu & CPU_SSSE3)
+ if (BitVector_bit_test(cpu, CPU_SSSE3))
strcat(cpuname, " SSSE3");
- if (cpu & CPU_SSE41)
+ if (BitVector_bit_test(cpu, CPU_SSE41))
strcat(cpuname, " SSE4.1");
- if (cpu & CPU_SSE42)
+ if (BitVector_bit_test(cpu, CPU_SSE42))
strcat(cpuname, " SSE4.2");
- if (cpu & CPU_186)
+ if (BitVector_bit_test(cpu, CPU_186))
strcat(cpuname, " 186");
- if (cpu & CPU_286)
+ if (BitVector_bit_test(cpu, CPU_286))
strcat(cpuname, " 286");
- if (cpu & CPU_386)
+ if (BitVector_bit_test(cpu, CPU_386))
strcat(cpuname, " 386");
- if (cpu & CPU_486)
+ if (BitVector_bit_test(cpu, CPU_486))
strcat(cpuname, " 486");
- if (cpu & CPU_586)
+ if (BitVector_bit_test(cpu, CPU_586))
strcat(cpuname, " 586");
- if (cpu & CPU_686)
+ if (BitVector_bit_test(cpu, CPU_686))
strcat(cpuname, " 686");
- if (cpu & CPU_P3)
+ if (BitVector_bit_test(cpu, CPU_P3))
strcat(cpuname, " P3");
- if (cpu & CPU_P4)
+ if (BitVector_bit_test(cpu, CPU_P4))
strcat(cpuname, " P4");
- if (cpu & CPU_IA64)
+ if (BitVector_bit_test(cpu, CPU_IA64))
strcat(cpuname, " IA64");
- if (cpu & CPU_K6)
+ if (BitVector_bit_test(cpu, CPU_K6))
strcat(cpuname, " K6");
- if (cpu & CPU_Athlon)
+ if (BitVector_bit_test(cpu, CPU_Athlon))
strcat(cpuname, " Athlon");
- if (cpu & CPU_Hammer)
+ if (BitVector_bit_test(cpu, CPU_Hammer))
strcat(cpuname, " Hammer");
+
+ BitVector_Destroy(cpu);
return cpuname;
}
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*@null@*/ const insnprefix_parse_data *pdata;
+ unsigned int cpu0, cpu1, cpu2;
size_t i;
static char lcaseid[16];
if (!pdata)
return YASM_ARCH_NOTINSNPREFIX;
+ cpu0 = pdata->cpu0;
+ cpu1 = pdata->cpu1;
+ cpu2 = pdata->cpu2;
+
if (pdata->group) {
- unsigned long cpu = pdata->data2;
x86_id_insn *id_insn;
+ wordptr cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];
- if ((cpu & CPU_64) && arch_x86->mode_bits != 64) {
+ if (arch_x86->mode_bits != 64 &&
+ (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64)) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is an instruction in 64-bit mode"), id);
return YASM_ARCH_NOTINSNPREFIX;
}
- if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64) {
+ if (arch_x86->mode_bits == 64 &&
+ (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64)) {
yasm_error_set(YASM_ERROR_GENERAL,
N_("`%s' invalid in 64-bit mode"), id);
id_insn = yasm_xmalloc(sizeof(x86_id_insn));
yasm_insn_initialize(&id_insn->insn);
id_insn->group = not64_insn;
- id_insn->cpu_enabled = CPU_Not64;
+ id_insn->cpu_enabled = cpu_enabled;
id_insn->mod_data = 0;
id_insn->num_info = NELEMS(not64_insn);
id_insn->mode_bits = arch_x86->mode_bits;
return YASM_ARCH_INSN;
}
- cpu &= ~(CPU_64 | CPU_Not64);
- if ((arch_x86->cpu_enabled & cpu) != cpu) {
+ if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
+ cpu0 = CPU_Any;
+ if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
+ cpu1 = CPU_Any;
+ if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
+ cpu2 = CPU_Any;
+ if (!BitVector_bit_test(cpu_enabled, cpu0) ||
+ !BitVector_bit_test(cpu_enabled, cpu1) ||
+ !BitVector_bit_test(cpu_enabled, cpu2)) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is an instruction in CPU%s"), id,
- cpu_find_reverse(cpu));
+ cpu_find_reverse(cpu0, cpu1, cpu2));
return YASM_ARCH_NOTINSNPREFIX;
}
id_insn = yasm_xmalloc(sizeof(x86_id_insn));
yasm_insn_initialize(&id_insn->insn);
id_insn->group = pdata->group;
- id_insn->cpu_enabled = arch_x86->cpu_enabled;
+ id_insn->cpu_enabled = cpu_enabled;
id_insn->mod_data = pdata->data1 >> 8;
id_insn->num_info = pdata->data1 & 0xff;
id_insn->mode_bits = arch_x86->mode_bits;
return YASM_ARCH_INSN;
} else {
unsigned long type = pdata->data1;
- unsigned long value = pdata->data2;
+ unsigned long value = pdata->flags;
if (arch_x86->mode_bits == 64 && type == X86_OPERSIZE && value == 32) {
yasm_error_set(YASM_ERROR_GENERAL,
return YASM_ARCH_NOTINSNPREFIX;
}
- if ((type == X86_REX ||
- (value == 64 && (type == X86_OPERSIZE || type == X86_ADDRSIZE)))
- && arch_x86->mode_bits != 64) {
+ if (arch_x86->mode_bits != 64 &&
+ (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64)) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is a prefix in 64-bit mode"), id);
return YASM_ARCH_NOTINSNPREFIX;
yasm_insn_initialize(&id_insn->insn);
id_insn->group = empty_insn;
- id_insn->cpu_enabled = arch_x86->cpu_enabled;
+ id_insn->cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];
id_insn->mod_data = 0;
id_insn->num_info = NELEMS(empty_insn);
id_insn->mode_bits = arch_x86->mode_bits;