]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-scache.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / sim / common / cgen-scache.c
CommitLineData
b9c8cd10
DE
1/* Simulator cache routines for CGEN simulators (and maybe others).
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#define SCACHE_P
22#define SCACHE_DEFINE_INLINE
23
24#include "sim-main.h"
25#include "libiberty.h"
26#include "cgen-scache.h"
27#include "sim-options.h"
28#include "sim-io.h"
29
30/* Unused address. */
31#define UNUSED_ADDR 0xffffffff
32
33static MODULE_INIT_FN scache_init;
34static MODULE_UNINSTALL_FN scache_uninstall;
35
36static DECLARE_OPTION_HANDLER (scache_option_handler);
37
38#define OPTION_PROFILE_SCACHE (OPTION_START + 0)
39
40static 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 }
48};
49
50static SIM_RC
51scache_option_handler (sd, opt, arg)
52 SIM_DESC sd;
53 int opt;
54 char *arg;
55{
56 int n;
57
58 switch (opt)
59 {
60 case 'c' :
61 if (WITH_SCACHE)
62 {
63 if (arg != NULL)
64 {
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. */
68 if (n < 2)
69 {
70 sim_io_eprintf (sd, "invalid scache size `%d'", n);
71 return SIM_RC_FAIL;
72 }
73 /* Ensure it's a multiple of 2. */
74 if ((n & (n - 1)) != 0)
75 {
76 sim_io_eprintf (sd, "scache size `%d' not a multiple of 2\n", n);
77 {
78 /* round up to nearest multiple of 2 */
79 int i;
80 for (i = 1; i < n; i <<= 1)
81 continue;
82 n = i;
83
84 }
85 sim_io_eprintf (sd, "rounding scache size up to %d\n", n);
86 }
87 STATE_SCACHE_SIZE (sd) = n;
88 }
89 else
90 STATE_SCACHE_SIZE (sd) = SCACHE_DEFAULT_CACHE_SIZE;
91 }
92 else
93 sim_io_eprintf (sd, "Simulator execution cache not enabled, `--scache-size' ignored\n");
94 break;
95
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;
100 else
101 sim_io_eprintf (sd, "Simulator cache profiling not compiled in, `--profile-scache' ignored\n");
102 break;
103
104 }
105
106 return SIM_RC_OK;
107}
108
109SIM_RC
110scache_install (SIM_DESC sd)
111{
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);
115
116 /* This is the default, it may be overridden on the command line. */
117 STATE_SCACHE_SIZE (sd) = WITH_SCACHE;
118
119 return SIM_RC_OK;
120}
121
122static SIM_RC
123scache_init (SIM_DESC sd)
124{
125 int c;
126
127 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
128 {
129 SIM_CPU *cpu = STATE_CPU (sd, c);
130
131 CPU_SCACHE_SIZE (cpu) = STATE_SCACHE_SIZE (sd);
132 CPU_SCACHE_CACHE (cpu) = (SCACHE *)
133 xmalloc (CPU_SCACHE_SIZE (cpu) * sizeof (SCACHE));
134 }
135
136 scache_flush (sd);
137
138 return SIM_RC_OK;
139}
140
141static void
142scache_uninstall (SIM_DESC sd)
143{
144 int c;
145
146 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
147 {
148 SIM_CPU *cpu = STATE_CPU (sd, c);
149
150 if (CPU_SCACHE_CACHE (cpu) != NULL)
151 free (CPU_SCACHE_CACHE (cpu));
152 }
153}
154
155void
156scache_flush (SIM_DESC sd)
157{
158 int i,c;
159 SCACHE *sc;
160
161 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
162 {
163 SIM_CPU *cpu = STATE_CPU (sd, c);
164
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));
168
169 for (i = 0, sc = CPU_SCACHE_CACHE (cpu); i < CPU_SCACHE_SIZE (cpu);
170 ++i, ++sc)
171 {
172 sc->argbuf.addr = UNUSED_ADDR;
173 }
174 }
175}
176
c967f187
DE
177/* Print cache access statics for CPU. */
178
b9c8cd10 179void
c967f187 180scache_print_profile (SIM_CPU *cpu, int verbose)
b9c8cd10 181{
c967f187 182 SIM_DESC sd = CPU_STATE (cpu);
b9c8cd10
DE
183 unsigned long hits = CPU_SCACHE_HITS (cpu);
184 unsigned long misses = CPU_SCACHE_MISSES (cpu);
2317a499 185 char buf[20];
b9c8cd10
DE
186
187 sim_io_printf (sd, "Simulator Cache Statistics\n\n");
188
c967f187 189 /* One could use PROFILE_LABEL_WIDTH here. I chose not to. */
2317a499
DE
190 sim_io_printf (sd, " Cache size: %d\n",
191 sim_add_commas (buf, sizeof (buf), CPU_SCACHE_SIZE (cpu)));
192 sim_io_printf (sd, " Hits: %s\n",
193 sim_add_commas (buf, sizeof (buf), hits));
194 sim_io_printf (sd, " Misses: %s\n",
195 sim_add_commas (buf, sizeof (buf), misses));
b9c8cd10 196 if (hits + misses != 0)
c967f187 197 sim_io_printf (sd, " Hit rate: %.2f%%\n",
b9c8cd10
DE
198 ((double) hits / ((double) hits + (double) misses)) * 100);
199 sim_io_printf (sd, "\n");
200}