OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [common/] [cgen-engine.h] - Blame information for rev 835

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Engine header for Cpu tools GENerated simulators.
2
   Copyright (C) 1998, 1999, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Cygnus Support.
5
 
6
This file is part of GDB, the GNU debugger.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
/* This file is included by ${cpu}.h.
22
   It needs CGEN_INSN_WORD which is defined by ${cpu}.h.
23
   ??? A lot of this could be moved to genmloop.sh to be put in eng.h
24
   and thus remove some conditional compilation.  We'd still need
25
   CGEN_INSN_WORD though.  */
26
 
27
/* Semantic functions come in six versions on two axes:
28
   fast/full-featured, and using one of the simple/scache/compilation engines.
29
   A full featured simulator is always provided.  --enable-sim-fast includes
30
   support for fast execution by duplicating the semantic code but leaving
31
   out all features like tracing and profiling.
32
   Using the scache is selected with --enable-sim-scache.  */
33
/* FIXME: --enable-sim-fast not implemented yet.  */
34
/* FIXME: undecided how to handle WITH_SCACHE_PBB.  */
35
 
36
/* There are several styles of engines, all generally supported by the
37
   same code:
38
 
39
   WITH_SCACHE && WITH_SCACHE_PBB - pseudo-basic-block scaching
40
   WITH_SCACHE && !WITH_SCACHE_PBB - scaching on an insn by insn basis
41
   !WITH_SCACHE - simple engine: fetch an insn, execute an insn
42
 
43
   The !WITH_SCACHE case can also be broken up into two flavours:
44
   extract the fields of the insn into an ARGBUF struct, or defer the
45
   extraction to the semantic handler.  The former can be viewed as the
46
   WITH_SCACHE case with a cache size of 1 (thus there's no need for a
47
   WITH_EXTRACTION macro).  The WITH_SCACHE case always extracts the fields
48
   into an ARGBUF struct.  */
49
 
50
#ifndef CGEN_ENGINE_H
51
#define CGEN_ENGINE_H
52
 
53
/* Instruction field support macros.  */
54
 
55
#define EXTRACT_MSB0_SINT(val, total, start, length) \
56
(((INT) (val) << ((sizeof (INT) * 8) - (total) + (start))) \
57
 >> ((sizeof (INT) * 8) - (length)))
58
#define EXTRACT_MSB0_UINT(val, total, start, length) \
59
(((UINT) (val) << ((sizeof (UINT) * 8) - (total) + (start))) \
60
 >> ((sizeof (UINT) * 8) - (length)))
61
 
62
#define EXTRACT_LSB0_SINT(val, total, start, length) \
63
(((INT) (val) << ((sizeof (INT) * 8) - (start) - 1)) \
64
 >> ((sizeof (INT) * 8) - (length)))
65
#define EXTRACT_LSB0_UINT(val, total, start, length) \
66
(((UINT) (val) << ((sizeof (UINT) * 8) - (start) - 1)) \
67
 >> ((sizeof (UINT) * 8) - (length)))
68
 
69
#define EXTRACT_MSB0_LGSINT(val, total, start, length) \
70
(((CGEN_INSN_LGSINT) (val) << ((sizeof (CGEN_INSN_LGSINT) * 8) - (total) + (start))) \
71
 >> ((sizeof (CGEN_INSN_LGSINT) * 8) - (length)))
72
#define EXTRACT_MSB0_LGUINT(val, total, start, length) \
73
(((CGEN_INSN_UINT) (val) << ((sizeof (CGEN_INSN_LGUINT) * 8) - (total) + (start))) \
74
 >> ((sizeof (CGEN_INSN_LGUINT) * 8) - (length)))
75
 
76
#define EXTRACT_LSB0_LGSINT(val, total, start, length) \
77
(((CGEN_INSN_LGSINT) (val) << ((sizeof (CGEN_INSN_LGSINT) * 8) - (start) - 1)) \
78
 >> ((sizeof (CGEN_INSN_LGSINT) * 8) - (length)))
79
#define EXTRACT_LSB0_LGUINT(val, total, start, length) \
80
(((CGEN_INSN_LGUINT) (val) << ((sizeof (CGEN_INSN_LGUINT) * 8) - (start) - 1)) \
81
 >> ((sizeof (CGEN_INSN_LGUINT) * 8) - (length)))
82
 
83
/* Semantic routines.  */
84
 
85
/* Type of the machine generated extraction fns.  */
86
/* ??? No longer used.  */
87
typedef void (EXTRACT_FN) (SIM_CPU *, IADDR, CGEN_INSN_WORD, ARGBUF *);
88
 
89
/* Type of the machine generated semantic fns.  */
90
 
91
#if WITH_SCACHE
92
 
93
/* Instruction fields are extracted into ARGBUF before calling the
94
   semantic routine.  */
95
#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
96
typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *);
97
#else
98
typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG);
99
#endif
100
 
101
#else
102
 
103
/* Result of semantic routines is a status indicator (wip).  */
104
typedef unsigned int SEM_STATUS;
105
 
106
/* Instruction fields are extracted by the semantic routine.
107
   ??? TODO: multi word insns.  */
108
#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
109
typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *, CGEN_INSN_WORD);
110
#else
111
typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, CGEN_INSN_WORD);
112
#endif
113
 
114
#endif
115
 
116
/* In the ARGBUF struct, a pointer to the semantic routine for the insn.  */
117
 
118
union sem {
119
#if ! WITH_SEM_SWITCH_FULL
120
  SEMANTIC_FN *sem_full;
121
#endif
122
#if ! WITH_SEM_SWITCH_FAST
123
  SEMANTIC_FN *sem_fast;
124
#endif
125
#if WITH_SEM_SWITCH_FULL || WITH_SEM_SWITCH_FAST
126
#ifdef __GNUC__
127
  void *sem_case;
128
#else
129
  int sem_case;
130
#endif
131
#endif
132
};
133
 
134
/* Set the appropriate semantic handler in ABUF.  */
135
 
136
#if WITH_SEM_SWITCH_FULL
137
#ifdef __GNUC__
138
#define SEM_SET_FULL_CODE(abuf, idesc) \
139
  do { (abuf)->semantic.sem_case = (idesc)->sem_full_lab; } while (0)
140
#else 
141
#define SEM_SET_FULL_CODE(abuf, idesc) \
142
  do { (abuf)->semantic.sem_case = (idesc)->num; } while (0)
143
#endif
144
#else
145
#define SEM_SET_FULL_CODE(abuf, idesc) \
146
  do { (abuf)->semantic.sem_full = (idesc)->sem_full; } while (0)
147
#endif
148
 
149
#if WITH_SEM_SWITCH_FAST
150
#ifdef __GNUC__
151
#define SEM_SET_FAST_CODE(abuf, idesc) \
152
  do { (abuf)->semantic.sem_case = (idesc)->sem_fast_lab; } while (0)
153
#else 
154
#define SEM_SET_FAST_CODE(abuf, idesc) \
155
  do { (abuf)->semantic.sem_case = (idesc)->num; } while (0)
156
#endif
157
#else
158
#define SEM_SET_FAST_CODE(abuf, idesc) \
159
  do { (abuf)->semantic.sem_fast = (idesc)->sem_fast; } while (0)
160
#endif
161
 
162
#define SEM_SET_CODE(abuf, idesc, fast_p) \
163
do { \
164
  if (fast_p) \
165
    SEM_SET_FAST_CODE ((abuf), (idesc)); \
166
  else \
167
    SEM_SET_FULL_CODE ((abuf), (idesc)); \
168
} while (0)
169
 
170
/* Return non-zero if IDESC is a conditional or unconditional CTI.  */
171
 
172
#define IDESC_CTI_P(idesc) \
173
     ((CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) \
174
       & (CGEN_ATTR_MASK (CGEN_INSN_COND_CTI) \
175
          | CGEN_ATTR_MASK (CGEN_INSN_UNCOND_CTI))) \
176
      != 0)
177
 
178
/* Return non-zero if IDESC is a skip insn.  */
179
 
180
#define IDESC_SKIP_P(idesc) \
181
     ((CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) \
182
       & CGEN_ATTR_MASK (CGEN_INSN_SKIP_CTI)) \
183
      != 0)
184
 
185
/* Return pointer to ARGBUF given ptr to SCACHE.  */
186
#define SEM_ARGBUF(sem_arg) (& (sem_arg) -> argbuf)
187
 
188
#if WITH_SCACHE
189
 
190
#define CIA_ADDR(cia) (cia)
191
 
192
#if WITH_SCACHE_PBB
193
 
194
/* Return the scache pointer of the current insn.  */
195
#define SEM_SEM_ARG(vpc, sc) (vpc)
196
 
197
/* Return the virtual pc of the next insn to execute
198
   (assuming this isn't a cti or the branch isn't taken).  */
199
#define SEM_NEXT_VPC(sem_arg, pc, len) ((sem_arg) + 1)
200
 
201
/* Update the instruction counter.  */
202
#define PBB_UPDATE_INSN_COUNT(cpu,sc) \
203
  (CPU_INSN_COUNT (cpu) += SEM_ARGBUF (sc) -> fields.chain.insn_count)
204
 
205
/* Do not append a `;' to invocations of this.
206
   npc,br_type are for communication between the cti insn and cti-chain.  */
207
#define SEM_BRANCH_INIT \
208
  IADDR npc = 0; /* assign a value for -Wall */ \
209
  SEM_BRANCH_TYPE br_type = SEM_BRANCH_UNTAKEN;
210
 
211
/* SEM_IN_SWITCH is defined at the top of the mainloop.c files
212
   generated by genmloop.sh.  It exists so generated semantic code needn't
213
   care whether it's being put in a switch or in a function.  */
214
#ifdef SEM_IN_SWITCH
215
#define SEM_BRANCH_FINI(pcvar) \
216
do { \
217
  pbb_br_npc = npc; \
218
  pbb_br_type = br_type; \
219
} while (0)
220
#else /* 1 semantic function per instruction */
221
#define SEM_BRANCH_FINI(pcvar) \
222
do { \
223
  CPU_PBB_BR_NPC (current_cpu) = npc; \
224
  CPU_PBB_BR_TYPE (current_cpu) = br_type; \
225
} while (0)
226
#endif
227
 
228
#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
229
do { \
230
  npc = (newval); \
231
  br_type = SEM_BRANCH_CACHEABLE; \
232
} while (0)
233
 
234
#define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
235
do { \
236
  npc = (newval); \
237
  br_type = SEM_BRANCH_UNCACHEABLE; \
238
} while (0)
239
 
240
#define SEM_SKIP_COMPILE(cpu, sc, skip) \
241
do { \
242
  SEM_ARGBUF (sc) -> skip_count = (skip); \
243
} while (0)
244
 
245
#define SEM_SKIP_INSN(cpu, sc, vpcvar) \
246
do { \
247
  (vpcvar) += SEM_ARGBUF (sc) -> skip_count; \
248
} while (0)
249
 
250
#else /* ! WITH_SCACHE_PBB */
251
 
252
#define SEM_SEM_ARG(vpc, sc) (sc)
253
 
254
#define SEM_NEXT_VPC(sem_arg, pc, len) ((pc) + (len))
255
 
256
/* ??? May wish to move taken_p out of here and make it explicit.  */
257
#define SEM_BRANCH_INIT \
258
  int taken_p = 0;
259
 
260
#ifndef TARGET_SEM_BRANCH_FINI
261
#define TARGET_SEM_BRANCH_FINI(pcvar, taken_p)
262
#endif
263
#define SEM_BRANCH_FINI(pcvar) \
264
  do { TARGET_SEM_BRANCH_FINI (pcvar, taken_p); } while (0)
265
 
266
#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
267
do { \
268
  (pcvar) = (newval); \
269
  taken_p = 1; \
270
} while (0)
271
 
272
#define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
273
do { \
274
  (pcvar) = (newval); \
275
  taken_p = 1; \
276
} while (0)
277
 
278
#endif /* ! WITH_SCACHE_PBB */
279
 
280
#else /* ! WITH_SCACHE */
281
 
282
/* This is the "simple" engine case.  */
283
 
284
#define CIA_ADDR(cia) (cia)
285
 
286
#define SEM_SEM_ARG(vpc, sc) (sc)
287
 
288
#define SEM_NEXT_VPC(sem_arg, pc, len) ((pc) + (len))
289
 
290
#define SEM_BRANCH_INIT \
291
  int taken_p = 0;
292
 
293
#define SEM_BRANCH_VIA_CACHE(cpu, abuf, newval, pcvar) \
294
do { \
295
  (pcvar) = (newval); \
296
  taken_p = 1; \
297
} while (0)
298
 
299
#define SEM_BRANCH_VIA_ADDR(cpu, abuf, newval, pcvar) \
300
do { \
301
  (pcvar) = (newval); \
302
  taken_p = 1; \
303
} while (0)
304
 
305
/* Finish off branch insns.
306
   The target must define TARGET_SEM_BRANCH_FINI.
307
   ??? This can probably go away when define-execute is finished.  */
308
#define SEM_BRANCH_FINI(pcvar, bool_attrs) \
309
  do { TARGET_SEM_BRANCH_FINI ((pcvar), (bool_attrs), taken_p); } while (0)
310
 
311
/* Finish off non-branch insns.
312
   The target must define TARGET_SEM_NBRANCH_FINI.
313
   ??? This can probably go away when define-execute is finished.  */
314
#define SEM_NBRANCH_FINI(pcvar, bool_attrs) \
315
  do { TARGET_SEM_NBRANCH_FINI ((pcvar), (bool_attrs)); } while (0)
316
 
317
#endif /* ! WITH_SCACHE */
318
 
319
/* Instruction information.  */
320
 
321
/* Sanity check, at most one of these may be true.  */
322
#if WITH_PARALLEL_READ + WITH_PARALLEL_WRITE + WITH_PARALLEL_GENWRITE > 1
323
#error "At most one of WITH_PARALLEL_{READ,WRITE,GENWRITE} can be true."
324
#endif
325
 
326
/* Compile time computable instruction data.  */
327
 
328
struct insn_sem {
329
  /* The instruction type (a number that identifies each insn over the
330
     entire architecture).  */
331
  CGEN_INSN_TYPE type;
332
 
333
  /* Index in IDESC table.  */
334
  int index;
335
 
336
  /* Semantic format number.  */
337
  int sfmt;
338
 
339
#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_ONLY
340
  /* Index in IDESC table of parallel handler.  */
341
  int par_index;
342
#endif
343
 
344
#if WITH_PARALLEL_READ
345
  /* Index in IDESC table of read handler.  */
346
  int read_index;
347
#endif
348
 
349
#if WITH_PARALLEL_WRITE
350
  /* Index in IDESC table of writeback handler.  */
351
  int write_index;
352
#endif
353
};
354
 
355
/* Entry in semantic function table.
356
   This information is copied to the insn descriptor table at run-time.  */
357
 
358
struct sem_fn_desc {
359
  /* Index in IDESC table.  */
360
  int index;
361
 
362
  /* Function to perform the semantics of the insn.  */
363
  SEMANTIC_FN *fn;
364
};
365
 
366
/* Run-time computed instruction descriptor.  */
367
 
368
struct idesc {
369
#if WITH_SEM_SWITCH_FAST
370
#ifdef __GNUC__
371
  void *sem_fast_lab;
372
#else
373
  /* nothing needed, switch's on `num' member */
374
#endif
375
#else
376
  SEMANTIC_FN *sem_fast;
377
#endif
378
 
379
#if WITH_SEM_SWITCH_FULL
380
#ifdef __GNUC__
381
  void *sem_full_lab;
382
#else
383
  /* nothing needed, switch's on `num' member */
384
#endif
385
#else
386
  SEMANTIC_FN *sem_full;
387
#endif
388
 
389
  /* Parallel support.  */
390
#if HAVE_PARALLEL_INSNS && (! WITH_PARALLEL_ONLY || (WITH_PARALLEL_ONLY && ! WITH_PARALLEL_GENWRITE))
391
  /* Pointer to parallel handler if serial insn.
392
     Pointer to readahead/writeback handler if parallel insn.  */
393
  struct idesc *par_idesc;
394
#endif
395
 
396
  /* Instruction number (index in IDESC table, profile table).
397
     Also used to switch on in non-gcc semantic switches.  */
398
  int num;
399
 
400
  /* Semantic format id.  */
401
  int sfmt;
402
 
403
  /* instruction data (name, attributes, size, etc.) */
404
  const CGEN_INSN *idata;
405
 
406
  /* instruction attributes, copied from `idata' for speed */
407
  const CGEN_INSN_ATTR_TYPE *attrs;
408
 
409
  /* instruction length in bytes, copied from `idata' for speed */
410
  int length;
411
 
412
  /* profiling/modelling support */
413
  const INSN_TIMING *timing;
414
};
415
 
416
/* Tracing/profiling.  */
417
 
418
/* Return non-zero if a before/after handler is needed.
419
   When tracing/profiling a selected range there's no need to slow
420
   down simulation of the other insns (except to get more accurate data!).
421
 
422
   ??? May wish to profile all insns if doing insn tracing, or to
423
   get more accurate cycle data.
424
 
425
   First test ANY_P so we avoid a potentially expensive HIT_P call
426
   [if there are lots of address ranges].  */
427
 
428
#define PC_IN_TRACE_RANGE_P(cpu, pc) \
429
  (TRACE_ANY_P (cpu) \
430
   && ADDR_RANGE_HIT_P (TRACE_RANGE (CPU_TRACE_DATA (cpu)), (pc)))
431
#define PC_IN_PROFILE_RANGE_P(cpu, pc) \
432
  (PROFILE_ANY_P (cpu) \
433
   && ADDR_RANGE_HIT_P (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)), (pc)))
434
 
435
#endif /* CGEN_ENGINE_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.