};
static void
-detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2)
+detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
+ struct cache_desc *level3)
{
struct cache_desc *cache;
case 2:
cache = level2;
break;
+ case 3:
+ cache = level3;
+ break;
default:
cache = NULL;
}
cache->sizekb = (cache->assoc * part
* cache->line * sets) / 1024;
- }
+ }
}
default:
break;
/* Returns the description of caches for an Intel processor. */
static const char *
-detect_caches_intel (bool xeon_mp, unsigned max_level, unsigned max_ext_level)
+detect_caches_intel (bool xeon_mp, unsigned max_level,
+ unsigned max_ext_level, unsigned *l2sizekb)
{
- struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0};
+ struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
if (max_level >= 4)
- detect_caches_cpuid4 (&level1, &level2);
+ detect_caches_cpuid4 (&level1, &level2, &level3);
else if (max_level >= 2)
detect_caches_cpuid2 (xeon_mp, &level1, &level2);
else
if (level1.sizekb == 0)
return "";
+ /* Let the L3 replace the L2. This assumes inclusive caches
+ and single threaded program for now. */
+ if (level3.sizekb)
+ level2 = level3;
+
/* Intel CPUs are equipped with AMD style L2 cache info. Try this
method if other methods fail to provide L2 cache parameters. */
if (level2.sizekb == 0 && max_ext_level >= 0x80000006)
detect_l2_cache (&level2);
+ *l2sizekb = level2.sizekb;
+
return describe_cache (level1, level2);
}
bool arch;
+ unsigned int l2sizekb = 0;
+
if (argc < 1)
return NULL;
else if (vendor == SIG_INTEL)
{
bool xeon_mp = (family == 15 && model == 6);
- cache = detect_caches_intel (xeon_mp, max_level, ext_level);
+ cache = detect_caches_intel (xeon_mp, max_level,
+ ext_level, &l2sizekb);
}
}
cpu = "pentium";
break;
case PROCESSOR_PENTIUMPRO:
- if (has_longmode)
- /* It is Core 2 or Atom. */
- cpu = (model == 28) ? "atom" : "core2";
- else if (arch)
+ switch (model)
{
- if (has_sse3)
- /* It is Core Duo. */
- cpu = "prescott";
- else if (has_sse2)
- /* It is Pentium M. */
- cpu = "pentium-m";
- else if (has_sse)
- /* It is Pentium III. */
- cpu = "pentium3";
- else if (has_mmx)
- /* It is Pentium II. */
- cpu = "pentium2";
+ case 0x1c:
+ case 0x26:
+ /* Atom. */
+ cpu = "atom";
+ break;
+ case 0x1a:
+ case 0x1e:
+ case 0x1f:
+ case 0x2e:
+ /* FIXME: Optimize for Nehalem. */
+ cpu = "core2";
+ break;
+ case 0x25:
+ case 0x2f:
+ /* FIXME: Optimize for Westmere. */
+ cpu = "core2";
+ break;
+ case 0x17:
+ case 0x1d:
+ /* Penryn. FIXME: -mtune=core2 is slower than -mtune=generic */
+ cpu = "core2";
+ break;
+ case 0x0f:
+ /* Merom. FIXME: -mtune=core2 is slower than -mtune=generic */
+ cpu = "core2";
+ break;
+ default:
+ if (arch)
+ {
+ if (has_ssse3)
+ /* If it is an unknown CPU with SSSE3, assume Core 2. */
+ cpu = "core2";
+ else if (has_sse3)
+ /* It is Core Duo. */
+ cpu = "pentium-m";
+ else if (has_sse2)
+ /* It is Pentium M. */
+ cpu = "pentium-m";
+ else if (has_sse)
+ /* It is Pentium III. */
+ cpu = "pentium3";
+ else if (has_mmx)
+ /* It is Pentium II. */
+ cpu = "pentium2";
+ else
+ /* Default to Pentium Pro. */
+ cpu = "pentiumpro";
+ }
else
- /* Default to Pentium Pro. */
- cpu = "pentiumpro";
+ /* For -mtune, we default to -mtune=generic. */
+ cpu = "generic";
+ break;
}
- else
- /* For -mtune, we default to -mtune=generic. */
- cpu = "generic";
break;
case PROCESSOR_PENTIUM4:
if (has_sse3)