blob: 944a229501378a84ba186563bebd482dd61122f2 [file] [log] [blame]
#
# x86 CPU recognition
#
# Copyright (C) 2002-2007 Peter Johnson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
%{
#include <util.h>
RCSID("$Id: x86cpu.gperf 2346 2010-08-01 01:37:37Z peter $");
#include <ctype.h>
#include <libyasm.h>
#include <libyasm/phash.h>
#include "modules/arch/x86/x86arch.h"
#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
#define PROC_westmere 14
#define PROC_sandybridge 15
static void
x86_cpu_intel(wordptr cpu, yasm_arch_x86 *arch_x86, 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_sandybridge)
BitVector_Bit_On(cpu, CPU_AVX);
if (data >= PROC_westmere) {
BitVector_Bit_On(cpu, CPU_AES);
BitVector_Bit_On(cpu, CPU_CLMUL);
}
if (data >= PROC_nehalem) {
BitVector_Bit_On(cpu, CPU_SSE42);
BitVector_Bit_On(cpu, CPU_XSAVE);
}
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);
/* Use Intel long NOPs if 686 or better */
if (data >= PROC_686)
arch_x86->nop = X86_NOP_INTEL;
else
arch_x86->nop = X86_NOP_BASIC;
}
static void
x86_cpu_ia64(wordptr cpu, yasm_arch_x86 *arch_x86, 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_bulldozer 11
#define PROC_k10 10
#define PROC_venice 9
#define PROC_hammer 8
#define PROC_k7 7
#define PROC_k6 6
static void
x86_cpu_amd(wordptr cpu, yasm_arch_x86 *arch_x86, 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_bulldozer) {
BitVector_Bit_On(cpu, CPU_XOP);
BitVector_Bit_On(cpu, CPU_FMA4);
}
if (data >= PROC_k10)
BitVector_Bit_On(cpu, CPU_SSE4a);
if (data >= PROC_venice)
BitVector_Bit_On(cpu, CPU_SSE3);
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);
/* Use AMD long NOPs if k6 or better */
if (data >= PROC_k6)
arch_x86->nop = X86_NOP_AMD;
else
arch_x86->nop = X86_NOP_BASIC;
}
static void
x86_cpu_set(wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data)
{
BitVector_Bit_On(cpu, data);
}
static void
x86_cpu_clear(wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data)
{
BitVector_Bit_Off(cpu, data);
}
static void
x86_cpu_set_sse4(wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data)
{
BitVector_Bit_On(cpu, CPU_SSE41);
BitVector_Bit_On(cpu, CPU_SSE42);
}
static void
x86_cpu_clear_sse4(wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data)
{
BitVector_Bit_Off(cpu, CPU_SSE41);
BitVector_Bit_Off(cpu, CPU_SSE42);
}
static void
x86_nop(wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data)
{
arch_x86->nop = data;
}
%}
%ignore-case
%language=ANSI-C
%compare-strncmp
%readonly-tables
%enum
%struct-type
%define hash-function-name cpu_hash
%define lookup-function-name cpu_find
struct cpu_parse_data {
const char *name;
void (*handler) (wordptr cpu, yasm_arch_x86 *arch_x86, unsigned int data);
unsigned int data;
};
%%
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
k8, x86_cpu_amd, PROC_hammer
hammer, x86_cpu_amd, PROC_hammer
clawhammer, x86_cpu_amd, PROC_hammer
opteron, x86_cpu_amd, PROC_hammer
athlon64, x86_cpu_amd, PROC_hammer
athlon-64, x86_cpu_amd, PROC_hammer
venice, x86_cpu_amd, PROC_venice
k10, x86_cpu_amd, PROC_k10
phenom, x86_cpu_amd, PROC_k10
family10h, x86_cpu_amd, PROC_k10
bulldozer, x86_cpu_amd, PROC_bulldozer
prescott, x86_cpu_intel, PROC_prescott
conroe, x86_cpu_intel, PROC_conroe
core2, x86_cpu_intel, PROC_conroe
penryn, x86_cpu_intel, PROC_penryn
nehalem, x86_cpu_intel, PROC_nehalem
corei7, x86_cpu_intel, PROC_nehalem
westmere, x86_cpu_intel, PROC_westmere
sandybridge, x86_cpu_intel, PROC_sandybridge
#
# Features have "no" versions to disable them, and only set/reset the
# specific feature being changed. All other bits are left alone.
#
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
sse41, x86_cpu_set, CPU_SSE41
nosse41, x86_cpu_clear, CPU_SSE41
sse4.2, x86_cpu_set, CPU_SSE42
nosse4.2, x86_cpu_clear, CPU_SSE42
sse42, x86_cpu_set, CPU_SSE42
nosse42, x86_cpu_clear, CPU_SSE42
sse4a, x86_cpu_set, CPU_SSE4a
nosse4a, x86_cpu_clear, CPU_SSE4a
sse4, x86_cpu_set_sse4, 0
nosse4, x86_cpu_clear_sse4, 0
xsave, x86_cpu_set, CPU_XSAVE
noxsave, x86_cpu_clear, CPU_XSAVE
avx, x86_cpu_set, CPU_AVX
noavx, x86_cpu_clear, CPU_AVX
fma, x86_cpu_set, CPU_FMA
nofma, x86_cpu_clear, CPU_FMA
aes, x86_cpu_set, CPU_AES
noaes, x86_cpu_clear, CPU_AES
clmul, x86_cpu_set, CPU_CLMUL
noclmul, x86_cpu_clear, CPU_CLMUL
pclmulqdq, x86_cpu_set, CPU_CLMUL
nopclmulqdq, x86_cpu_clear, CPU_CLMUL
movbe, x86_cpu_set, CPU_MOVBE
nomovbe, x86_cpu_clear, CPU_MOVBE
xop, x86_cpu_set, CPU_XOP
noxop, x86_cpu_clear, CPU_XOP
fma4, x86_cpu_set, CPU_FMA4
nofma4, x86_cpu_clear, CPU_FMA4
f16c, x86_cpu_set, CPU_F16C
nof16c, x86_cpu_clear, CPU_F16C
fsgsbase, x86_cpu_set, CPU_FSGSBASE
nofsgsbase, x86_cpu_clear, CPU_FSGSBASE
rdrand, x86_cpu_set, CPU_RDRAND
nordrand, x86_cpu_clear, CPU_RDRAND
xsaveopt, x86_cpu_set, CPU_XSAVEOPT
noxsaveopt, x86_cpu_clear, CPU_XSAVEOPT
eptvpid, x86_cpu_set, CPU_EPTVPID
noeptvpid, x86_cpu_clear, CPU_EPTVPID
smx, x86_cpu_set, CPU_SMX
nosmx, x86_cpu_clear, CPU_SMX
# Change NOP patterns
basicnop, x86_nop, X86_NOP_BASIC
intelnop, x86_nop, X86_NOP_INTEL
amdnop, x86_nop, X86_NOP_AMD
%%
void
yasm_x86__parse_cpu(yasm_arch_x86 *arch_x86, const char *cpuid,
size_t cpuid_len)
{
/*@null@*/ const struct cpu_parse_data *pdata;
wordptr new_cpu;
size_t i;
static char lcaseid[16];
if (cpuid_len > 15)
return;
for (i=0; i<cpuid_len; i++)
lcaseid[i] = tolower(cpuid[i]);
lcaseid[cpuid_len] = '\0';
pdata = cpu_find(lcaseid, cpuid_len);
if (!pdata) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized CPU identifier `%s'"), cpuid);
return;
}
new_cpu = BitVector_Clone(arch_x86->cpu_enables[arch_x86->active_cpu]);
pdata->handler(new_cpu, arch_x86, 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;
}