]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - 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
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
5 This file is part of GDB, the GNU debugger.
6
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)
10 any later version.
11
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.
16
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. */
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
33 static MODULE_INIT_FN scache_init;
34 static MODULE_UNINSTALL_FN scache_uninstall;
35
36 static DECLARE_OPTION_HANDLER (scache_option_handler);
37
38 #define OPTION_PROFILE_SCACHE (OPTION_START + 0)
39
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 }
48 };
49
50 static SIM_RC
51 scache_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
109 SIM_RC
110 scache_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
122 static SIM_RC
123 scache_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
141 static void
142 scache_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
155 void
156 scache_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
177 /* Print cache access statics for CPU. */
178
179 void
180 scache_print_profile (SIM_CPU *cpu, int verbose)
181 {
182 SIM_DESC sd = CPU_STATE (cpu);
183 unsigned long hits = CPU_SCACHE_HITS (cpu);
184 unsigned long misses = CPU_SCACHE_MISSES (cpu);
185 char buf[20];
186
187 sim_io_printf (sd, "Simulator Cache Statistics\n\n");
188
189 /* One could use PROFILE_LABEL_WIDTH here. I chose not to. */
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));
196 if (hits + misses != 0)
197 sim_io_printf (sd, " Hit rate: %.2f%%\n",
198 ((double) hits / ((double) hits + (double) misses)) * 100);
199 sim_io_printf (sd, "\n");
200 }