summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorweidendo <weidendo@a5019735-40e9-0310-863c-91ae7b9d1cf9>2011-09-06 19:08:31 +0000
committerweidendo <weidendo@a5019735-40e9-0310-863c-91ae7b9d1cf9>2011-09-06 19:08:31 +0000
commit23642271f41ad858fa0935b8b870290b45bd5eeb (patch)
tree8e11a051e1410ad5cdc5ae942f13f64dd57d30ba
parent55cade6e311b5ae4bdc757f69fc6a11f7414a536 (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.am3
-rw-r--r--cachegrind/cg-arch.c208
-rw-r--r--cachegrind/cg_arch.h37
-rw-r--r--cachegrind/cg_main.c144
-rw-r--r--callgrind/Makefile.am3
-rw-r--r--callgrind/sim.c156
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;
}