diff options
author | weidendo <weidendo@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2011-09-06 19:08:31 +0000 |
---|---|---|
committer | weidendo <weidendo@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2011-09-06 19:08:31 +0000 |
commit | 23642271f41ad858fa0935b8b870290b45bd5eeb (patch) | |
tree | 8e11a051e1410ad5cdc5ae942f13f64dd57d30ba | |
parent | 55cade6e311b5ae4bdc757f69fc6a11f7414a536 (diff) |
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
-rw-r--r-- | cachegrind/Makefile.am | 3 | ||||
-rw-r--r-- | cachegrind/cg-arch.c | 208 | ||||
-rw-r--r-- | cachegrind/cg_arch.h | 37 | ||||
-rw-r--r-- | cachegrind/cg_main.c | 144 | ||||
-rw-r--r-- | callgrind/Makefile.am | 3 | ||||
-rw-r--r-- | callgrind/sim.c | 156 |
6 files changed, 268 insertions, 283 deletions
diff --git a/cachegrind/Makefile.am b/cachegrind/Makefile.am index 12636537..0b6879c9 100644 --- a/cachegrind/Makefile.am +++ b/cachegrind/Makefile.am @@ -41,10 +41,11 @@ endif CACHEGRIND_SOURCES_COMMON = \ cg_main.c \ + cg-arch.c \ cg-x86-amd64.c \ cg-ppc32.c \ cg-ppc64.c \ - cg-arm.c \ + cg-arm.c \ cg-s390x.c cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \ diff --git a/cachegrind/cg-arch.c b/cachegrind/cg-arch.c new file mode 100644 index 00000000..77adfc29 --- /dev/null +++ b/cachegrind/cg-arch.c @@ -0,0 +1,208 @@ +/*--------------------------------------------------------------------*/ +/*--- Cachegrind: cache configuration. ---*/ +/*--- The architecture specific void VG_(configure_caches) are ---*/ +/*--- located in the cg-<architecture>.c files. ---*/ +/*--- cg-arch.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Cachegrind, a Valgrind tool for cache + profiling programs. + + Copyright (C) 2011-2011 Nicholas Nethercote + njn@valgrind.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "pub_tool_basics.h" +#include "pub_tool_libcassert.h" +#include "pub_tool_libcbase.h" +#include "pub_tool_libcprint.h" +#include "pub_tool_options.h" + +#include "cg_arch.h" + +// 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 set count to be a power 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 parse_cache_opt ( cache_t* cache, Char* opt, Char* optval ) +{ + 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"); +} + + +Bool VG_(str_clo_cache_opt)(Char *arg, + cache_t* clo_I1c, + cache_t* clo_D1c, + cache_t* clo_LLc) +{ + Char* tmp_str; + + if VG_STR_CLO(arg, "--I1", tmp_str) { + parse_cache_opt(clo_I1c, arg, tmp_str); + return True; + } else if VG_STR_CLO(arg, "--D1", tmp_str) { + parse_cache_opt(clo_D1c, arg, tmp_str); + return True; + } else if (VG_STR_CLO(arg, "--L2", tmp_str) || // for backwards compatibility + VG_STR_CLO(arg, "--LL", tmp_str)) { + parse_cache_opt(clo_LLc, arg, tmp_str); + return True; + } else + return False; +} + +static void umsg_cache_img(Char* desc, cache_t* c) +{ + VG_(umsg)(" %s: %'d B, %d-way, %d B lines\n", desc, + c->size, c->assoc, c->line_size); +} + +// Verifies if c is a valid cache. +// An invalid value causes an assert, unless clo_redefined is True. +static void check_cache_or_override(Char* desc, cache_t* c, Bool clo_redefined) +{ + Char* checkRes; + + checkRes = check_cache(c); + if (checkRes) { + VG_(umsg)("Auto-detected %s cache configuration not supported: %s", + desc, checkRes); + umsg_cache_img(desc, c); + if (!clo_redefined) { + VG_(umsg)("As it probably should be supported, please report a bug!\n"); + VG_(umsg)("Bypass this message by using option --%s=...\n", desc); + tl_assert(0); + } + } +} + +void VG_(post_clo_init_configure_caches)(cache_t* I1c, + cache_t* D1c, + cache_t* LLc, + cache_t* clo_I1c, + cache_t* clo_D1c, + cache_t* clo_LLc) +{ +#define DEFINED(L) (-1 != L->size || -1 != L->assoc || -1 != L->line_size) + + // Count how many were defined on the command line. + Bool all_caches_clo_defined = + (DEFINED(clo_I1c) && + DEFINED(clo_D1c) && + DEFINED(clo_LLc)); + + // Set the cache config (using auto-detection, if supported by the + // architecture). + VG_(configure_caches)( I1c, D1c, LLc, all_caches_clo_defined ); + + // Check the default/auto-detected values. + // Allow the user to override invalid auto-detected caches + // with command line. + check_cache_or_override ("I1", I1c, DEFINED(clo_I1c)); + check_cache_or_override ("D1", D1c, DEFINED(clo_D1c)); + check_cache_or_override ("LL", LLc, DEFINED(clo_LLc)); + + // Then replace with any defined on the command line. (Already checked in + // VG(parse_clo_cache_opt)().) + if (DEFINED(clo_I1c)) { *I1c = *clo_I1c; } + if (DEFINED(clo_D1c)) { *D1c = *clo_D1c; } + if (DEFINED(clo_LLc)) { *LLc = *clo_LLc; } + + if (VG_(clo_verbosity) >= 2) { + VG_(umsg)("Cache configuration used:\n"); + umsg_cache_img ("I1", I1c); + umsg_cache_img ("D1", D1c); + umsg_cache_img ("LL", LLc); + } +#undef DEFINED +} + +void VG_(print_cache_clo_opts)() +{ + VG_(printf)( +" --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" + ); +} diff --git a/cachegrind/cg_arch.h b/cachegrind/cg_arch.h index 23f1a2cd..68f9ab3f 100644 --- a/cachegrind/cg_arch.h +++ b/cachegrind/cg_arch.h @@ -1,13 +1,13 @@ /*--------------------------------------------------------------------*/ -/*--- Arch-specific declarations. cg_arch.h ---*/ +/*--- Arch-specific declarations, cache configuration. cg_arch.h ---*/ /*--------------------------------------------------------------------*/ /* This file is part of Cachegrind, a Valgrind tool for cache profiling programs. - Copyright (C) 2002-2010 Nicholas Nethercote + Copyright (C) 2002-2011 Nicholas Nethercote njn@valgrind.org This program is free software; you can redistribute it and/or @@ -38,11 +38,40 @@ typedef struct { Int line_size; // bytes } cache_t; -// Gives the configuration of I1, D1 and LL caches. They get overridden -// by any cache configurations specified on the command line. +#define MIN_LINE_SIZE 16 + +// clo_*c used in the call to VG_(str_clo_cache_opt) should be statically +// initialized to UNDEFINED_CACHE. +#define UNDEFINED_CACHE { -1, -1, -1 } + +// Gives the auto-detected configuration of I1, D1 and LL caches. They get +// overridden by any cache configurations specified on the command line. void VG_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* LLc, Bool all_caches_clo_defined); +// If arg is a command line option configuring I1 or D1 or LL cache, +// then parses arg to set the relevant cache_t elements. +// Returns True if arg is a cache command line option, False otherwise. +Bool VG_(str_clo_cache_opt)(Char *arg, + cache_t* clo_I1c, + cache_t* clo_D1c, + cache_t* clo_LLc); + +// Checks the correctness of the auto-detected caches. +// If a cache has been configured by command line options, it +// replaces the equivalent auto-detected cache. +// Note that an invalid auto-detected cache will make Valgrind exit +// with an fatal error, except if the invalid auto-detected cache +// will be replaced by a command line defined cache. +void VG_(post_clo_init_configure_caches)(cache_t* I1c, + cache_t* D1c, + cache_t* LLc, + cache_t* clo_I1c, + cache_t* clo_D1c, + cache_t* clo_LLc); + +void VG_(print_cache_clo_opts)(void); + #endif // __CG_ARCH_H /*--------------------------------------------------------------------*/ diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 5772520f..8e439365 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -1236,92 +1236,6 @@ 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 set count to be a power 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; - - // Count how many were defined on the command line. - 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. (Already checked in - // parse_cache_opt().) - 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) >= 2) { - 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 -} - /*------------------------------------------------------------*/ /*--- cg_fini() and related function ---*/ /*------------------------------------------------------------*/ @@ -1726,53 +1640,12 @@ void cg_discard_superblock_info ( Addr64 orig_addr64, VexGuestExtents vge ) /*--- Command line processing ---*/ /*--------------------------------------------------------------------*/ -static void parse_cache_opt ( cache_t* cache, Char* opt, Char* optval ) -{ - 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"); -} - static Bool cg_process_cmd_line_option(Char* arg) { - Char* tmp_str; - - // 5 is length of "--I1=" - if VG_STR_CLO(arg, "--I1", tmp_str) - parse_cache_opt(&clo_I1_cache, arg, tmp_str); - else if VG_STR_CLO(arg, "--D1", tmp_str) - parse_cache_opt(&clo_D1_cache, arg, tmp_str); - else if (VG_STR_CLO(arg, "--L2", tmp_str) || // for backwards compatibility - VG_STR_CLO(arg, "--LL", tmp_str)) - parse_cache_opt(&clo_LL_cache, arg, tmp_str); + if (VG_(str_clo_cache_opt)(arg, + &clo_I1_cache, + &clo_D1_cache, + &clo_LL_cache)) {} else if VG_STR_CLO( arg, "--cachegrind-out-file", clo_cachegrind_out_file) {} else if VG_BOOL_CLO(arg, "--cache-sim", clo_cache_sim) {} @@ -1785,10 +1658,8 @@ static Bool cg_process_cmd_line_option(Char* arg) static void cg_print_usage(void) { + VG_(print_cache_clo_opts)(); VG_(printf)( -" --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" " --cache-sim=yes|no [yes] collect cache stats?\n" " --branch-sim=yes|no [no] collect branch prediction stats?\n" " --cachegrind-out-file=<file> output file name [cachegrind.out.%%p]\n" @@ -1848,7 +1719,10 @@ static void cg_post_clo_init(void) VG_(malloc), "cg.main.cpci.3", VG_(free)); - configure_caches(&I1c, &D1c, &LLc); + VG_(post_clo_init_configure_caches)(&I1c, &D1c, &LLc, + &clo_I1_cache, + &clo_D1_cache, + &clo_LL_cache); cachesim_I1_initcache(I1c); cachesim_D1_initcache(D1c); diff --git a/callgrind/Makefile.am b/callgrind/Makefile.am index 86e93133..0a8a2d3b 100644 --- a/callgrind/Makefile.am +++ b/callgrind/Makefile.am @@ -46,10 +46,11 @@ CALLGRIND_SOURCES_COMMON = \ main.c \ sim.c \ threads.c \ + ../cachegrind/cg-arch.c \ ../cachegrind/cg-x86-amd64.c \ ../cachegrind/cg-ppc32.c \ ../cachegrind/cg-ppc64.c \ - ../cachegrind/cg-arm.c \ + ../cachegrind/cg-arm.c \ ../cachegrind/cg-s390x.c CALLGRIND_CFLAGS_COMMON = -I$(top_srcdir)/cachegrind diff --git a/callgrind/sim.c b/callgrind/sim.c index 49d719ef..17785d9e 100644 --- a/callgrind/sim.c +++ b/callgrind/sim.c @@ -1266,98 +1266,10 @@ static void log_0I1Dw(InstrInfo* ii, Addr data_addr, Word data_size) /*--- 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 @@ static void cachesim_post_clo_init(void) } /* 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 @@ void cachesim_print_opts(void) #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 void parse_opt ( cache_t* cache, */ 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 @@ static Bool cachesim_parse_opt(Char* arg) } } - 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; } |