Call CPUID to more reliably detect level of SSE/AVX that the host supports.
Fixes, I hope, issue #205.
This commit is contained in:
55
ispc.cpp
55
ispc.cpp
@@ -70,6 +70,49 @@ Module *m;
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Target
|
// Target
|
||||||
|
|
||||||
|
#ifndef ISPC_IS_WINDOWS
|
||||||
|
static void __cpuid(int info[4], int infoType) {
|
||||||
|
__asm__ __volatile__ ("cpuid"
|
||||||
|
: "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
|
||||||
|
: "0" (infoType));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save %ebx in case it's the PIC register */
|
||||||
|
static void __cpuidex(int info[4], int level, int count) {
|
||||||
|
__asm__ __volatile__ ("xchg{l}\t{%%}ebx, %1\n\t"
|
||||||
|
"cpuid\n\t"
|
||||||
|
"xchg{l}\t{%%}ebx, %1\n\t"
|
||||||
|
: "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3])
|
||||||
|
: "0" (level), "2" (count));
|
||||||
|
}
|
||||||
|
#endif // ISPC_IS_WINDOWS
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
lGetSystemISA() {
|
||||||
|
int info[4];
|
||||||
|
__cpuid(info, 1);
|
||||||
|
|
||||||
|
if ((info[2] & (1 << 28)) != 0) {
|
||||||
|
// AVX1 for sure. Do we have AVX2?
|
||||||
|
// Call cpuid with eax=7, ecx=0
|
||||||
|
__cpuidex(info, 7, 0);
|
||||||
|
if ((info[1] & (1 << 5)) != 0)
|
||||||
|
return "avx2";
|
||||||
|
else
|
||||||
|
return "avx";
|
||||||
|
}
|
||||||
|
else if ((info[2] & (1 << 19)) != 0)
|
||||||
|
return "sse4";
|
||||||
|
else if ((info[3] & (1 << 26)) != 0)
|
||||||
|
return "sse2";
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Unable to detect supported SSE/AVX ISA. Exiting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
||||||
bool pic, Target *t) {
|
bool pic, Target *t) {
|
||||||
@@ -85,15 +128,9 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
|||||||
t->cpu = cpu;
|
t->cpu = cpu;
|
||||||
|
|
||||||
if (isa == NULL) {
|
if (isa == NULL) {
|
||||||
if (!strcasecmp(cpu, "atom"))
|
isa = lGetSystemISA();
|
||||||
isa = "sse2";
|
fprintf(stderr, "Notice: no --target specified on command-line. Using "
|
||||||
#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn)
|
"system ISA \"%s\".\n", isa);
|
||||||
else if (!strcasecmp(cpu, "sandybridge") ||
|
|
||||||
!strcasecmp(cpu, "corei7-avx"))
|
|
||||||
isa = "avx";
|
|
||||||
#endif // LLVM_3_0
|
|
||||||
else
|
|
||||||
isa = "sse4";
|
|
||||||
}
|
}
|
||||||
if (arch == NULL)
|
if (arch == NULL)
|
||||||
arch = "x86-64";
|
arch = "x86-64";
|
||||||
|
|||||||
Reference in New Issue
Block a user