This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / common / cgen-sim.h
1 /* Simulator header for Cpu tools GENerated simulators.
2    Copyright (C) 1996, 1997, 1998 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 #ifndef CGEN_SIM_H
22 #define CGEN_SIM_H
23
24 #define PC CPU (h_pc)
25 \f
26 /* Instruction field support macros.  */
27
28 #define EXTRACT_SIGNED(val, total, start, length) \
29 (((((val) >> ((total) - ((start) + (length)))) & ((1 << (length)) - 1)) \
30   ^ (1 << ((length) - 1))) \
31  - (1 << ((length) - 1)))
32
33 #define EXTRACT_UNSIGNED(val, total, start, length) \
34 (((val) >> ((total) - ((start) + (length)))) & ((1 << (length)) - 1))
35
36 /* Compute number of longs required to hold N bits.  */
37 #define HOST_LONGS_FOR_BITS(n) \
38   (((n) + sizeof (long) * 8 - 1) / sizeof (long) * 8)
39 \f
40 /* Execution support.  */
41
42 /* Forward decls.  Defined in the machine generated arch.h and cpu.h files.  */
43 typedef struct argbuf ARGBUF;
44 typedef struct scache SCACHE;
45 typedef struct parexec PAREXEC;
46
47 #ifdef SCACHE_P
48
49 /* instruction address */
50 typedef PCADDR IADDR;
51 /* current instruction address */
52 typedef PCADDR CIA;
53 /* argument to semantic functions */
54 typedef SCACHE *SEM_ARG;
55
56 #else /* ! SCACHE_P */
57
58 /* instruction address */
59 typedef PCADDR IADDR;
60 /* current instruction address */
61 typedef PCADDR CIA;
62 /* argument to semantic functions */
63 typedef ARGBUF *SEM_ARG;
64
65 #endif /* ! SCACHE_P */
66
67 /* Semantic functions come in two versions on two axis:
68    fast and full (featured), and using or not using scache.
69    A full featured simulator is always provided.  --enable-sim-fast includes
70    support for fast execution by duplicating the semantic code but leaving
71    out all features like tracing and profiling.
72    Using the scache is selected with --enable-sim-scache.  */
73 /* FIXME: --enable-sim-fast not implemented yet.  */
74
75 /* Types of the machine generated extract and semantic fns.  */
76 /* FIXME: Eventually conditionalize EXTRACT_FN on WITH_SCACHE.  */
77 typedef void (EXTRACT_FN) (SIM_CPU *, PCADDR, insn_t, ARGBUF *);
78 #if WITH_SCACHE
79 #ifdef HAVE_PARALLEL_EXEC
80 typedef CIA (SEMANTIC_FN) (SIM_CPU *, SCACHE *, PAREXEC *);
81 #else
82 typedef CIA (SEMANTIC_FN) (SIM_CPU *, SCACHE *);
83 #endif
84 #else /* ! WITH_SCACHE */
85 #ifdef HAVE_PARALLEL_EXEC
86 typedef CIA (SEMANTIC_FN) (SIM_CPU *, ARGBUF *, PAREXEC *);
87 #else
88 typedef CIA (SEMANTIC_FN) (SIM_CPU *, ARGBUF *);
89 #endif
90 #endif
91
92 /* DECODE struct, there is one per instruction.  */
93
94 typedef struct {
95   /* Using cgen_insn_type requires <cpu>-opc.h.  */
96   int /*enum cgen_insn_type*/ insn_type;
97   const struct cgen_insn *opcode;
98   EXTRACT_FN *extract;
99 #ifdef HAVE_PARALLEL_EXEC
100 #ifdef __GNUC__
101   void *read;
102 #else
103   int read;
104 #endif
105 #endif
106   SEMANTIC_FN *semantic;
107   SEMANTIC_FN *semantic_fast;
108 #if WITH_SEM_SWITCH_FULL && defined (__GNUC__)
109   /* Set at runtime.  */
110   void *sem_full_lab;
111 #endif
112 #if WITH_SEM_SWITCH_FAST && defined (__GNUC__)
113   /* Set at runtime.  */
114   void *semantic_lab; /* FIXME: Rename to sem_fast_lab.  */
115 #endif
116 } DECODE;
117
118 /* Scache data for each cpu.  */
119
120 typedef struct cpu_scache {
121   /* Simulator cache size.  */
122   int size;
123 #define CPU_SCACHE_SIZE(cpu) ((cpu) -> cgen_cpu.scache.size)
124   /* Cache.  */
125   SCACHE *cache;
126 #define CPU_SCACHE_CACHE(cpu) ((cpu) -> cgen_cpu.scache.cache)
127 #if 0 /* FIXME: wip */
128   /* Free list.  */
129   SCACHE *free;
130 #define CPU_SCACHE_FREE(cpu) ((cpu) -> cgen_cpu.scache.free)
131   /* Hash table.  */
132   SCACHE **hash_table;
133 #define CPU_SCACHE_HASH_TABLE(cpu) ((cpu) -> cgen_cpu.scache.hash_table)
134 #endif
135
136 #if WITH_PROFILE_SCACHE_P
137   /* Cache hits, misses.  */
138   unsigned long hits, misses;
139 #define CPU_SCACHE_HITS(cpu) ((cpu) -> cgen_cpu.scache.hits)
140 #define CPU_SCACHE_MISSES(cpu) ((cpu) -> cgen_cpu.scache.misses)
141 #endif
142 } CPU_SCACHE;
143
144 /* Default number of cached blocks.  */
145 #ifdef CONFIG_SIM_CACHE_SIZE
146 #define SCACHE_DEFAULT_CACHE_SIZE CONFIG_SIM_CACHE_SIZE
147 #else
148 #define SCACHE_DEFAULT_CACHE_SIZE 1024
149 #endif
150
151 /* Hash a PC value.  */
152 /* FIXME: cpu specific */
153 #define SCACHE_HASH_PC(state, pc) \
154 (((pc) >> 1) & (STATE_SCACHE_SIZE (sd) - 1))
155
156 /* Non-zero if cache is in use.  */
157 #define USING_SCACHE_P(sd) (STATE_SCACHE_SIZE (sd) > 0)
158
159 /* Install the simulator cache into the simulator.  */
160 MODULE_INSTALL_FN scache_install;
161
162 /* Flush all cpu's caches.  */
163 void scache_flush (SIM_DESC);
164 \f
165 /* Scache profiling support.  */
166
167 /* Print summary scache usage information.  */
168 void scache_print_profile (SIM_CPU *cpu, int verbose);
169
170 #if WITH_PROFILE_SCACHE_P
171 #define PROFILE_COUNT_SCACHE_HIT(cpu) \
172 do { \
173   if (CPU_PROFILE_FLAGS (cpu) [PROFILE_SCACHE_IDX]) \
174     ++ CPU_SCACHE_HITS (cpu); \
175 } while (0)
176 #define PROFILE_COUNT_SCACHE_MISS(cpu) \
177 do { \
178   if (CPU_PROFILE_FLAGS (cpu) [PROFILE_SCACHE_IDX]) \
179     ++ CPU_SCACHE_MISSES (cpu); \
180 } while (0)
181 #else
182 #define PROFILE_COUNT_SCACHE_HIT(cpu)
183 #define PROFILE_COUNT_SCACHE_MISS(cpu)
184 #endif
185 \f
186 /* Engine support.  */
187
188 /* Values to denote parallel/sequential execution.  */
189 #define EXEC_SEQUENCE 0
190 #define EXEC_PARALLEL 1
191
192 /* These are used so that we can compile two copies of the semantic code,
193    one with full feature support and one without.  */
194 /* FIXME: Eventually delete extraction if not using scache.  */
195 #define EX_FN_NAME(cpu,fn) XCONCAT3 (cpu,_ex_,fn)
196 #define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_sem_,fn)
197
198 #ifdef SCACHE_P
199
200 #define CIA_ADDR(cia) (cia)
201
202 /* extract.c support */
203 /* scache_unset is a cache entry that is never used.
204    It's raison d'etre is so BRANCH_VIA_CACHE doesn't have to test for
205    newval.cache == NULL.  */
206 extern struct scache scache_unset;
207 #define RECORD_IADDR(fld, val) \
208 do { (fld) = (val); } while (0)
209
210 /* semantics.c support */
211 #define SEM_ARGBUF(sem_arg) (&(sem_arg) -> argbuf)
212 #define SEM_INSN(sem_arg) shouldnt_be_used
213 #define SEM_NEXT_PC(sc) ((sc) -> next)
214 #define SEM_BRANCH_VIA_CACHE(sc, newval) (newval)
215 #define SEM_BRANCH_VIA_ADDR(sc, newval) (newval)
216 /* Return address a branch insn will branch to.
217    This is only used during tracing.  */
218 #define SEM_NEW_PC_ADDR(new_pc) (new_pc)
219
220 #else /* ! SCACHE_P */
221
222 #define CIA_ADDR(cia) (cia)
223
224 /* extract.c support */
225 #define RECORD_IADDR(fld, val) \
226 do { (fld) = (val); } while (0)
227
228 /* semantics.c support */
229 #define SEM_ARGBUF(sem_arg) (sem_arg)
230 #define SEM_INSN(sem_arg) (SEM_ARGBUF (sem_arg) -> insn)
231 #define SEM_NEXT_PC(abuf) (abuf -> addr + abuf -> length)
232 #define SEM_BRANCH_VIA_CACHE(abuf, newval) (newval)
233 #define SEM_BRANCH_VIA_ADDR(abuf, newval) (newval)
234 #define SEM_NEW_PC_ADDR(new_pc) (new_pc)
235
236 #endif /* ! SCACHE_P */
237
238 /* GNU C's "computed goto" facility is used to speed things up where
239    possible.  These macros provide a portable way to use them.
240    Nesting of these switch statements is done by providing an extra argument
241    that distinguishes them.  `N' can be a number or symbol.
242    Variable `labels_##N' must be initialized with the labels of each case.  */
243 #ifdef __GNUC__
244 #define SWITCH(N, X) goto *X;
245 #define CASE(N, X) case_##N##_##X
246 #define BREAK(N) goto end_switch_##N
247 #define DEFAULT(N) default_##N
248 #define ENDSWITCH(N) end_switch_##N:
249 #else
250 #define SWITCH(N, X) switch (X)
251 #define CASE(N, X) case X /* FIXME: old sem-switch had (@arch@_,X) here */
252 #define BREAK(N) break
253 #define DEFAULT(N) default
254 #define ENDSWITCH(N)
255 #endif
256
257 /* Engine control (FIXME).  */
258 int engine_stop (SIM_DESC);
259 void engine_run (SIM_DESC, int, int);
260 /*void engine_resume (SIM_DESC, int, int);*/
261 \f
262 /* Simulator state.  */
263
264 /* Records simulator descriptor so utilities like @cpu@_dump_regs can be
265    called from gdb.  */
266 extern SIM_DESC current_state;
267
268 /* Simulator state.  */
269
270 /* CGEN_STATE contains additional state information not present in
271    sim_state_base.  */
272
273 typedef struct cgen_state {
274   /* FIXME: Moved to sim_state_base.  */
275   /* argv, env */
276   char **argv;
277 #define STATE_ARGV(s) ((s) -> cgen_state.argv)
278   /* FIXME: Move to sim_state_base.  */
279   char **envp;
280 #define STATE_ENVP(s) ((s) -> cgen_state.envp)
281
282   /* Non-zero if no tracing or profiling is selected.  */
283   int run_fast_p;
284 #define STATE_RUN_FAST_P(sd) ((sd) -> cgen_state.run_fast_p)
285 } CGEN_STATE;
286
287 /* Additional non-machine generated per-cpu data to go in SIM_CPU.
288    The member's name must be `cgen_cpu'.  */
289
290 typedef struct {
291   /* Simulator's execution cache.  */
292 #if WITH_SCACHE
293   CPU_SCACHE scache;
294 #endif /* WITH_SCACHE */
295
296   /* Allow slop in size calcs for case where multiple cpu types are supported
297      and space for the specified cpu is malloc'd at run time.  */
298   double slop;
299 } CGEN_CPU;
300 \f
301 /* Various utilities.  */
302
303 /* Called after sim_post_argv_init to do any cgen initialization.  */
304 void cgen_init (SIM_DESC);
305
306 void
307 sim_disassemble_insn (SIM_CPU *, const struct cgen_insn *,
308                       const struct argbuf *, PCADDR, char *);
309
310 #endif /* CGEN_SIM_H */