From: uros Date: Fri, 4 Apr 2008 07:39:12 +0000 (+0000) Subject: * config/i386/driver-i386.c (describe_cache): Add l2_sizekb argument. X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=4c8b808dcf1f80b19d374d11f11376674e1e3393 * config/i386/driver-i386.c (describe_cache): Add l2_sizekb argument. Pass L2 size as "--param l2-cache-size" to the compiler. (decode_l2_cache): New function to decode L2 cache parameters using 0x8000006 extended cpuid function. (detect_caches_amd): Determine parameters of L2 cache using decode_l2_caches function. (decode_caches_intel): Decode L2 cache parameters. (detect_caches_intel): Determine L2 cache parameters using decode_caches_intel and decode_l2_caches functions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133890 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5bbc0381f2..edda2659b28 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2008-04-04 Zuxy Meng + + * config/i386/driver-i386.c (describe_cache): Add l2_sizekb argument. + Pass L2 size as "--param l2-cache-size" to the compiler. + (decode_l2_cache): New function to decode L2 cache parameters using + 0x8000006 extended cpuid function. + (detect_caches_amd): Determine parameters of L2 cache using + decode_l2_caches function. + (decode_caches_intel): Decode L2 cache parameters. + (detect_caches_intel): Determine L2 cache parameters using + decode_caches_intel and decode_l2_caches functions. + 2008-04-03 Bob Wilson * config/xtensa/xtensa.c (xtensa_secondary_reload_class): Use a diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 30a436bde25..b823d435c6d 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -33,17 +33,39 @@ const char *host_detect_local_cpu (int argc, const char **argv); static char * describe_cache (unsigned l1_sizekb, unsigned l1_line, - unsigned l1_assoc ATTRIBUTE_UNUSED) + unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb) { - char size[100], line[100]; + char size[100], line[100], size2[100]; /* At the moment, gcc middle-end does not use the information about the associativity of the cache. */ sprintf (size, "--param l1-cache-size=%u", l1_sizekb); sprintf (line, "--param l1-cache-line-size=%u", l1_line); + sprintf (size2, "--param l2-cache-size=%u", l2_sizekb); - return concat (size, " ", line, " ", NULL); + return concat (size, " ", line, " ", size2, " ", NULL); +} + +static void +decode_l2_cache (unsigned *l2_size, unsigned *l2_line, unsigned *l2_assoc) +{ + unsigned eax, ebx, ecx, edx, assoc; + + __cpuid (0x80000006, eax, ebx, ecx, edx); + + *l2_size = (ecx >> 16) & 0xffff; + *l2_line = ecx & 0xff; + assoc = (ecx >> 12) & 0xf; + if (assoc == 6) + assoc = 8; + else if (assoc == 8) + assoc = 16; + else if (assoc >= 0xa && assoc <= 0xc) + assoc = 32 + (assoc - 0xa) * 16; + else if (assoc >= 0xd && assoc <= 0xe) + assoc = 96 + (assoc - 0xd) * 32; + *l2_assoc = assoc; } /* Returns the description of caches for an AMD processor. */ @@ -53,6 +75,7 @@ detect_caches_amd (unsigned max_ext_level) { unsigned eax, ebx, ecx, edx; unsigned l1_sizekb, l1_line, l1_assoc; + unsigned l2_sizekb, l2_line, l2_assoc; if (max_ext_level < 0x80000005) return (char *) ""; @@ -63,15 +86,20 @@ detect_caches_amd (unsigned max_ext_level) l1_sizekb = (ecx >> 24) & 0xff; l1_assoc = (ecx >> 16) & 0xff; - return describe_cache (l1_sizekb, l1_line, l1_assoc); + if (max_ext_level >= 0x80000006) + decode_l2_cache (&l2_sizekb, &l2_line, &l2_assoc); + + return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); } -/* Stores the size of the L1 cache and cache line, and the associativity - of the cache according to REG to L1_SIZEKB, L1_LINE and L1_ASSOC. */ +/* Stores the size of the L1/2 cache and cache line, and the associativity + of the cache according to REG to L1_SIZEKB, L1_LINE, L1_ASSOC and + L2_SIZEKB. */ static void decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line, - unsigned *l1_assoc) + unsigned *l1_assoc, unsigned *l2_sizekb, + unsigned *l2_line, unsigned *l2_assoc) { unsigned i, val; @@ -100,6 +128,66 @@ decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line, *l1_line = 64; *l1_assoc = 8; break; + case 0x39: + *l2_sizekb = 128; + *l2_line = 64; + *l2_assoc = 4; + break; + case 0x3a: + *l2_sizekb = 192; + *l2_line = 64; + *l2_assoc = 6; + break; + case 0x3b: + *l2_sizekb = 128; + *l2_line = 64; + *l2_assoc = 2; + break; + case 0x3c: + *l2_sizekb = 256; + *l2_line = 64; + *l2_assoc = 4; + break; + case 0x3d: + *l2_sizekb = 384; + *l2_line = 64; + *l2_assoc = 6; + break; + case 0x3e: + *l2_sizekb = 512; + *l2_line = 64; + *l2_assoc = 4; + break; + case 0x41: + *l2_sizekb = 128; + *l2_line = 32; + *l2_assoc = 4; + break; + case 0x42: + *l2_sizekb = 256; + *l2_line = 32; + *l2_assoc = 4; + break; + case 0x43: + *l2_sizekb = 512; + *l2_line = 32; + *l2_assoc = 4; + break; + case 0x44: + *l2_sizekb = 1024; + *l2_line = 32; + *l2_assoc = 4; + break; + case 0x45: + *l2_sizekb = 2048; + *l2_line = 32; + *l2_assoc = 4; + break; + case 0x49: + *l2_sizekb = 4096; + *l2_line = 64; + *l2_assoc = 16; + break; case 0x60: *l1_sizekb = 16; *l1_line = 64; @@ -120,6 +208,71 @@ decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line, *l1_line = 64; *l1_assoc = 4; break; + case 0x78: + *l2_sizekb = 1024; + *l2_line = 64; + *l2_assoc = 4; + break; + case 0x79: + *l2_sizekb = 128; + *l2_line = 64; + *l2_assoc = 8; + break; + case 0x7a: + *l2_sizekb = 256; + *l2_line = 64; + *l2_assoc = 8; + break; + case 0x7b: + *l2_sizekb = 512; + *l2_line = 64; + *l2_assoc = 8; + break; + case 0x7c: + *l2_sizekb = 1024; + *l2_line = 64; + *l2_assoc = 8; + break; + case 0x7d: + *l2_sizekb = 2048; + *l2_line = 64; + *l2_assoc = 8; + break; + case 0x7f: + *l2_sizekb = 512; + *l2_line = 64; + *l2_assoc = 2; + break; + case 0x82: + *l2_sizekb = 256; + *l2_line = 32; + *l2_assoc = 8; + break; + case 0x83: + *l2_sizekb = 512; + *l2_line = 32; + *l2_assoc = 8; + break; + case 0x84: + *l2_sizekb = 1024; + *l2_line = 32; + *l2_assoc = 8; + break; + case 0x85: + *l2_sizekb = 2048; + *l2_line = 32; + *l2_assoc = 8; + break; + case 0x86: + *l2_sizekb = 512; + *l2_line = 64; + *l2_assoc = 4; + break; + case 0x87: + *l2_sizekb = 1024; + *l2_line = 64; + *l2_assoc = 8; + break; default: break; @@ -130,25 +283,34 @@ decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line, /* Returns the description of caches for an intel processor. */ static char * -detect_caches_intel (unsigned max_level) +detect_caches_intel (unsigned max_level, unsigned max_ext_level) { unsigned eax, ebx, ecx, edx; unsigned l1_sizekb = 0, l1_line = 0, assoc = 0; + unsigned l2_sizekb = 0, l2_line = 0, l2_assoc = 0; if (max_level < 2) return (char *) ""; __cpuid (2, eax, ebx, ecx, edx); - decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc); - decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc); - decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc); - decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc); + decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc, + &l2_sizekb, &l2_line, &l2_assoc); + decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc, + &l2_sizekb, &l2_line, &l2_assoc); + decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc, + &l2_sizekb, &l2_line, &l2_assoc); + decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc, + &l2_sizekb, &l2_line, &l2_assoc); if (!l1_sizekb) return (char *) ""; - return describe_cache (l1_sizekb, l1_line, assoc); + /* Newer Intel CPUs are equipped with AMD style L2 cache info */ + if (max_ext_level >= 0x80000006) + decode_l2_cache (&l2_sizekb, &l2_line, &l2_assoc); + + return describe_cache (l1_sizekb, l1_line, assoc, l2_sizekb); } /* This will be called by the spec parser in gcc.c when it sees @@ -234,7 +396,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (vendor == *(unsigned int*) "Auth") cache = detect_caches_amd (ext_level); else if (vendor == *(unsigned int*) "Genu") - cache = detect_caches_intel (max_level); + cache = detect_caches_intel (max_level, ext_level); } if (vendor == *(unsigned int*) "Auth")