Removed the need for the user to generate a cache simulation -- now do
automatic cache configuration detection using the CPUID instruction.
This can be overridden from the command-line if necessary.

vg_include.h:
    - added the cache_t type and UNDEFINED_CACHE macro

    - added command line args (of type cache_t) allowing manual override of
      I1/D1/L2 configuration

    - added log2(), which is generally useful

vg_main.c, valgrind.in, cachegrind.in:
    - added handling of the new --{I1,D1,L2}=<size>,<assoc>,<line_size>
      options

vg_cachesim.c:
    - lots of stuff for auto-detecting cache configuration with CPUID.
      Only handles Intel and AMD chips at the moment, and possibly not all of
      them.  Falls back onto defaults if anything goes wrong, and the configs
      can be manually overridden from the command line anyway.

    - now not printing cache summary stats if verbosity == 0.  Still writing
      cachegrind.out, though.

vg_cachesim_gen.c:
    - new file containing stuff shared by the I1/D1/L2 simulations

vg_cachesim_{I1,D1,L2}:
    - removed most of it;  each now just calls a macro defined in
      vg_cachesim_gen.c

vg_cachegen:
    - has been cvs removed as it is no longer needed.

Makefile.am:
    - added vg_cachesim_gen.c

    - removed vg_cachegen

configure.in:
    - removed vg_cachegen


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@400 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 8784499..29cd3d6 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -420,6 +420,9 @@
 Bool   VG_(clo_instrument);
 Bool   VG_(clo_cleanup);
 Bool   VG_(clo_cachesim);
+cache_t VG_(clo_I1_cache);
+cache_t VG_(clo_D1_cache);
+cache_t VG_(clo_L2_cache);
 Int    VG_(clo_smc_check);
 Bool   VG_(clo_trace_syscalls);
 Bool   VG_(clo_trace_signals);
@@ -482,6 +485,39 @@
    config_error("couldn't find client's argc/argc/envp");
 }   
 
+static void parse_cache_opt ( cache_t* cache, char* orig_opt, int opt_len )
+{
+   int   i1, i2, i3;
+   int   i;
+   char *opt = VG_(strdup)(VG_AR_PRIVATE, orig_opt);
+
+   i = i1 = opt_len;
+
+   /* Option looks like "--I1=65536,2,64".
+    * Find commas, replace with NULs to make three independent 
+    * strings, then extract numbers.  Yuck. */
+   while (VG_(isdigit)(opt[i])) i++;
+   if (',' == opt[i]) {
+      opt[i++] = '\0';
+      i2 = i;
+   } else goto bad;
+   while (VG_(isdigit)(opt[i])) i++;
+   if (',' == opt[i]) {
+      opt[i++] = '\0';
+      i3 = i;
+   } else goto bad;
+   while (VG_(isdigit)(opt[i])) i++;
+   if ('\0' != opt[i]) goto bad;
+
+   cache->size      = (Int)VG_(atoll)(opt + i1);
+   cache->assoc     = (Int)VG_(atoll)(opt + i2);
+   cache->line_size = (Int)VG_(atoll)(opt + i3);
+
+   return;
+
+bad:    
+   bad_option(orig_opt);
+}
 
 static void process_cmd_line_options ( void )
 {
@@ -514,6 +550,10 @@
    VG_(clo_single_step)      = False;
    VG_(clo_optimise)         = True;
    VG_(clo_instrument)       = True;
+   VG_(clo_cachesim)         = False;
+   VG_(clo_I1_cache)         = UNDEFINED_CACHE;
+   VG_(clo_D1_cache)         = UNDEFINED_CACHE;
+   VG_(clo_L2_cache)         = UNDEFINED_CACHE;
    VG_(clo_cleanup)          = True;
    VG_(clo_smc_check)        = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
    VG_(clo_trace_syscalls)   = False;
@@ -541,7 +581,7 @@
 
    /* (Suggested by Fabrice Bellard ... )
       We look for the Linux ELF table and go down until we find the
-      envc & envp. It is not full proof, but these structures should
+      envc & envp. It is not fool-proof, but these structures should
       change less often than the libc ones. */
    {
        UInt* sp = 0; /* bogus init to keep gcc -O happy */
@@ -766,6 +806,14 @@
       else if (STREQ(argv[i], "--cachesim=no"))
          VG_(clo_cachesim) = False;
 
+      /* 5 is length of "--I1=" */
+      else if (0 == VG_(strncmp)(argv[i], "--I1=",    5))
+         parse_cache_opt(&VG_(clo_I1_cache), argv[i], 5);
+      else if (0 == VG_(strncmp)(argv[i], "--D1=",    5))
+         parse_cache_opt(&VG_(clo_D1_cache), argv[i], 5);
+      else if (0 == VG_(strncmp)(argv[i], "--L2=",    5))
+         parse_cache_opt(&VG_(clo_L2_cache), argv[i], 5);
+
       else if (STREQ(argv[i], "--smc-check=none"))
          VG_(clo_smc_check) = VG_CLO_SMC_NONE;
       else if (STREQ(argv[i], "--smc-check=some"))
@@ -1087,7 +1135,7 @@
    VG_(running_on_simd_CPU) = False;
 
    if (VG_(clo_cachesim))
-      VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
+      VG_(do_cachesim_results)(VG_(client_argc), VG_(client_argv));
 
    VG_(do_sanity_checks)( True /*include expensive checks*/ );