Allow overriding not-supported auto-detected cache configs
Patch by Philippe Waroquiers, slightly changed.
This actually was a regression from 3.6.1, but the patch
also improves on printed messages, and refactors common
code between cachegrind and callgrind.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12013 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/callgrind/sim.c b/callgrind/sim.c
index 49d719e..17785d9 100644
--- a/callgrind/sim.c
+++ b/callgrind/sim.c
@@ -1266,98 +1266,10 @@
/*--- Cache configuration ---*/
/*------------------------------------------------------------*/
-#define UNDEFINED_CACHE ((cache_t) { -1, -1, -1 })
-
static cache_t clo_I1_cache = UNDEFINED_CACHE;
static cache_t clo_D1_cache = UNDEFINED_CACHE;
static cache_t clo_LL_cache = UNDEFINED_CACHE;
-
-// Checks cache config is ok. Returns NULL if ok, or a pointer to an error
-// string otherwise.
-static Char* check_cache(cache_t* cache)
-{
- // Simulator requires line size and set count to be powers of two.
- if (( cache->size % (cache->line_size * cache->assoc) != 0) ||
- (-1 == VG_(log2)(cache->size/cache->line_size/cache->assoc)))
- {
- return "Cache set count is not a power of two.\n";
- }
-
- // Simulator requires line size to be a power of two.
- if (-1 == VG_(log2)(cache->line_size)) {
- return "Cache line size is not a power of two.\n";
- }
-
- // Then check line size >= 16 -- any smaller and a single instruction could
- // straddle three cache lines, which breaks a simulation assertion and is
- // stupid anyway.
- if (cache->line_size < MIN_LINE_SIZE) {
- return "Cache line size is too small.\n";
- }
-
- /* Then check cache size > line size (causes seg faults if not). */
- if (cache->size <= cache->line_size) {
- return "Cache size <= line size.\n";
- }
-
- /* Then check assoc <= (size / line size) (seg faults otherwise). */
- if (cache->assoc > (cache->size / cache->line_size)) {
- return "Cache associativity > (size / line size).\n";
- }
-
- return NULL;
-}
-
-static
-void configure_caches(cache_t* I1c, cache_t* D1c, cache_t* LLc)
-{
-#define DEFINED(L) (-1 != L.size || -1 != L.assoc || -1 != L.line_size)
-
- Char* checkRes;
-
- Bool all_caches_clo_defined =
- (DEFINED(clo_I1_cache) &&
- DEFINED(clo_D1_cache) &&
- DEFINED(clo_LL_cache));
-
- // Set the cache config (using auto-detection, if supported by the
- // architecture).
- VG_(configure_caches)( I1c, D1c, LLc, all_caches_clo_defined );
-
- if (VG_(clo_verbosity) > 2) {
- VG_(umsg)("Cache configuration detected:\n");
- VG_(umsg)(" I1: %dB, %d-way, %dB lines\n",
- I1c->size, I1c->assoc, I1c->line_size);
- VG_(umsg)(" D1: %dB, %d-way, %dB lines\n",
- D1c->size, D1c->assoc, D1c->line_size);
- VG_(umsg)(" LL: %dB, %d-way, %dB lines\n",
- LLc->size, LLc->assoc, LLc->line_size);
- }
-
- // Check the default/auto-detected values.
- checkRes = check_cache(I1c); tl_assert(!checkRes);
- checkRes = check_cache(D1c); tl_assert(!checkRes);
- checkRes = check_cache(LLc); tl_assert(!checkRes);
-
- // Then replace with any defined on the command line.
- if (DEFINED(clo_I1_cache)) { *I1c = clo_I1_cache; }
- if (DEFINED(clo_D1_cache)) { *D1c = clo_D1_cache; }
- if (DEFINED(clo_LL_cache)) { *LLc = clo_LL_cache; }
-
- if (VG_(clo_verbosity) > 1) {
- VG_(umsg)("Cache configuration used:\n");
- VG_(umsg)(" I1: %dB, %d-way, %dB lines\n",
- I1c->size, I1c->assoc, I1c->line_size);
- VG_(umsg)(" D1: %dB, %d-way, %dB lines\n",
- D1c->size, D1c->assoc, D1c->line_size);
- VG_(umsg)(" LL: %dB, %d-way, %dB lines\n",
- LLc->size, LLc->assoc, LLc->line_size);
- }
-#undef CMD_LINE_DEFINED
-}
-
-
/* Initialize and clear simulator state */
static void cachesim_post_clo_init(void)
{
@@ -1386,8 +1298,11 @@
}
/* Configuration of caches only needed with real cache simulation */
- configure_caches(&I1c, &D1c, &LLc);
-
+ VG_(post_clo_init_configure_caches)(&I1c, &D1c, &LLc,
+ &clo_I1_cache,
+ &clo_D1_cache,
+ &clo_LL_cache);
+
I1.name = "I1";
D1.name = "D1";
LL.name = "LL";
@@ -1499,47 +1414,8 @@
#if CLG_EXPERIMENTAL
" --simulate-sectors=no|yes Simulate sectored behaviour [no]\n"
#endif
-" --cacheuse=no|yes Collect cache block use [no]\n"
-" --I1=<size>,<assoc>,<line_size> set I1 cache manually\n"
-" --D1=<size>,<assoc>,<line_size> set D1 cache manually\n"
-" --LL=<size>,<assoc>,<line_size> set LL cache manually\n"
- );
-}
-
-static void parse_opt ( cache_t* cache,
- char* opt, Char* optval, UChar kind )
-{
- Long i1, i2, i3;
- Char* endptr;
- Char* checkRes;
-
- // Option argument looks like "65536,2,64". Extract them.
- i1 = VG_(strtoll10)(optval, &endptr); if (*endptr != ',') goto bad;
- i2 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != ',') goto bad;
- i3 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != '\0') goto bad;
-
- // Check for overflow.
- cache->size = (Int)i1;
- cache->assoc = (Int)i2;
- cache->line_size = (Int)i3;
- if (cache->size != i1) goto overflow;
- if (cache->assoc != i2) goto overflow;
- if (cache->line_size != i3) goto overflow;
-
- checkRes = check_cache(cache);
- if (checkRes) {
- VG_(fmsg)("%s", checkRes);
- goto bad;
- }
-
- return;
-
- bad:
- VG_(fmsg_bad_option)(opt, "");
-
- overflow:
- VG_(fmsg_bad_option)(opt,
- "One of the cache parameters was too large and overflowed.\n");
+" --cacheuse=no|yes Collect cache block use [no]\n");
+ VG_(print_cache_clo_opts)();
}
/* Check for command line option for cache configuration.
@@ -1549,8 +1425,6 @@
*/
static Bool cachesim_parse_opt(Char* arg)
{
- Char* tmp_str;
-
if VG_BOOL_CLO(arg, "--simulate-wb", clo_simulate_writeback) {}
else if VG_BOOL_CLO(arg, "--simulate-hwpref", clo_simulate_hwpref) {}
else if VG_BOOL_CLO(arg, "--simulate-sectors", clo_simulate_sectors) {}
@@ -1562,15 +1436,13 @@
}
}
- else if VG_STR_CLO(arg, "--I1", tmp_str)
- parse_opt(&clo_I1_cache, arg, tmp_str, 'i');
- else if VG_STR_CLO(arg, "--D1", tmp_str)
- parse_opt(&clo_D1_cache, arg, tmp_str, '1');
- else if (VG_STR_CLO(arg, "--L2", tmp_str) || // for backwards compatibility
- VG_STR_CLO(arg, "--LL", tmp_str))
- parse_opt(&clo_LL_cache, arg, tmp_str, '2');
- else
- return False;
+ else if (VG_(str_clo_cache_opt)(arg,
+ &clo_I1_cache,
+ &clo_D1_cache,
+ &clo_LL_cache)) {}
+
+ else
+ return False;
return True;
}