1 /* Simulator cache routines for CGEN simulators (and maybe others).
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #define SCACHE_DEFINE_INLINE
25 #include "libiberty.h"
26 #include "cgen-scache.h"
27 #include "sim-options.h"
31 #define UNUSED_ADDR 0xffffffff
33 static MODULE_INIT_FN scache_init;
34 static MODULE_UNINSTALL_FN scache_uninstall;
36 static DECLARE_OPTION_HANDLER (scache_option_handler);
38 #define OPTION_PROFILE_SCACHE (OPTION_START + 0)
40 static const OPTION scache_options[] = {
41 { {"scache-size", optional_argument, NULL, 'c'},
42 'c', "[SIZE]", "Specify size of simulator execution cache",
43 scache_option_handler },
44 { {"profile-scache", no_argument, NULL, OPTION_PROFILE_SCACHE},
45 '\0', NULL, "Perform simulator execution cache profiling",
46 scache_option_handler },
47 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
51 scache_option_handler (sd, opt, arg)
65 int n = strtol (arg, NULL, 0);
66 /* The m32r port assumes a cache size of at least 2 so it
67 can decode both 16 bit insns. */
70 sim_io_eprintf (sd, "invalid scache size `%d'", n);
73 /* Ensure it's a multiple of 2. */
74 if ((n & (n - 1)) != 0)
76 sim_io_eprintf (sd, "scache size `%d' not a multiple of 2\n", n);
78 /* round up to nearest multiple of 2 */
80 for (i = 1; i < n; i <<= 1)
85 sim_io_eprintf (sd, "rounding scache size up to %d\n", n);
87 STATE_SCACHE_SIZE (sd) = n;
90 STATE_SCACHE_SIZE (sd) = SCACHE_DEFAULT_CACHE_SIZE;
93 sim_io_eprintf (sd, "Simulator execution cache not enabled, `--scache-size' ignored\n");
96 case OPTION_PROFILE_SCACHE :
97 if (WITH_SCACHE && WITH_PROFILE_SCACHE_P)
98 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
99 CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_SCACHE_IDX] = 1;
101 sim_io_eprintf (sd, "Simulator cache profiling not compiled in, `--profile-scache' ignored\n");
110 scache_install (SIM_DESC sd)
112 sim_add_option_table (sd, scache_options);
113 sim_module_add_init_fn (sd, scache_init);
114 sim_module_add_uninstall_fn (sd, scache_uninstall);
116 /* This is the default, it may be overridden on the command line. */
117 STATE_SCACHE_SIZE (sd) = WITH_SCACHE;
123 scache_init (SIM_DESC sd)
127 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
129 SIM_CPU *cpu = STATE_CPU (sd, c);
131 CPU_SCACHE_SIZE (cpu) = STATE_SCACHE_SIZE (sd);
132 CPU_SCACHE_CACHE (cpu) = (SCACHE *)
133 xmalloc (CPU_SCACHE_SIZE (cpu) * sizeof (SCACHE));
142 scache_uninstall (SIM_DESC sd)
146 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
148 SIM_CPU *cpu = STATE_CPU (sd, c);
150 if (CPU_SCACHE_CACHE (cpu) != NULL)
151 free (CPU_SCACHE_CACHE (cpu));
156 scache_flush (SIM_DESC sd)
161 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
163 SIM_CPU *cpu = STATE_CPU (sd, c);
165 /* Technically, this may not be necessary, but it helps debugging. */
166 memset (CPU_SCACHE_CACHE (cpu), 0,
167 CPU_SCACHE_SIZE (cpu) * sizeof (SCACHE));
169 for (i = 0, sc = CPU_SCACHE_CACHE (cpu); i < CPU_SCACHE_SIZE (cpu);
172 sc->argbuf.addr = UNUSED_ADDR;
177 /* Print cache access statics for CPU. */
180 scache_print_profile (SIM_CPU *cpu, int verbose)
182 SIM_DESC sd = CPU_STATE (cpu);
183 unsigned long hits = CPU_SCACHE_HITS (cpu);
184 unsigned long misses = CPU_SCACHE_MISSES (cpu);
186 sim_io_printf (sd, "Simulator Cache Statistics\n\n");
188 /* One could use PROFILE_LABEL_WIDTH here. I chose not to. */
189 sim_io_printf (sd, " Cache size: %d\n", CPU_SCACHE_SIZE (cpu));
190 sim_io_printf (sd, " Hits: %d\n", hits);
191 sim_io_printf (sd, " Misses: %d\n", misses);
192 if (hits + misses != 0)
193 sim_io_printf (sd, " Hit rate: %.2f%%\n",
194 ((double) hits / ((double) hits + (double) misses)) * 100);
195 sim_io_printf (sd, "\n");