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
);
187 sim_io_printf (sd
, "Simulator Cache Statistics\n\n");
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");