Don't add IMAGE_FILE_RELOCS_STRIPPED for PIE.
[deliverable/binutils-gdb.git] / sim / common / cgen-engine.h
CommitLineData
c906108c 1/* Engine header for Cpu tools GENerated simulators.
dc3cf14f
JB
2 Copyright (C) 1998, 1999, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
c906108c
SS
4 Contributed by Cygnus Support.
5
6This file is part of GDB, the GNU debugger.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
4744ac1b
JB
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
c906108c
SS
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
4744ac1b
JB
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 20
197fa1aa
DE
21/* This file is included by ${cpu}.h.
22 It needs CGEN_INSN_WORD which is defined by ${cpu}.h.
917317f4 23 ??? A lot of this could be moved to genmloop.sh to be put in eng.h
197fa1aa
DE
24 and thus remove some conditional compilation. We'd still need
25 CGEN_INSN_WORD though. */
c906108c
SS
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
62836bf4 55#define EXTRACT_MSB0_SINT(val, total, start, length) \
c906108c
SS
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
62836bf4 62#define EXTRACT_LSB0_SINT(val, total, start, length) \
c906108c
SS
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)))
197fa1aa
DE
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)))
c906108c
SS
82\f
83/* Semantic routines. */
84
85/* Type of the machine generated extraction fns. */
86/* ??? No longer used. */
197fa1aa 87typedef void (EXTRACT_FN) (SIM_CPU *, IADDR, CGEN_INSN_WORD, ARGBUF *);
c906108c
SS
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. */
53a5351d 95#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
c906108c
SS
96typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *);
97#else
98typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG);
99#endif
100
101#else
102
103/* Result of semantic routines is a status indicator (wip). */
104typedef unsigned int SEM_STATUS;
105
106/* Instruction fields are extracted by the semantic routine.
107 ??? TODO: multi word insns. */
53a5351d 108#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
197fa1aa 109typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *, CGEN_INSN_WORD);
c906108c 110#else
197fa1aa 111typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, CGEN_INSN_WORD);
c906108c
SS
112#endif
113
114#endif
115
116/* In the ARGBUF struct, a pointer to the semantic routine for the insn. */
117
118union 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) \
163do { \
164 if (fast_p) \
165 SEM_SET_FAST_CODE ((abuf), (idesc)); \
166 else \
167 SEM_SET_FULL_CODE ((abuf), (idesc)); \
168} while (0)
169\f
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
c906108c
SS
185/* Return pointer to ARGBUF given ptr to SCACHE. */
186#define SEM_ARGBUF(sem_arg) (& (sem_arg) -> argbuf)
187
c906108c
SS
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
c906108c 205/* Do not append a `;' to invocations of this.
96baa820 206 npc,br_type are for communication between the cti insn and cti-chain. */
c906108c
SS
207#define SEM_BRANCH_INIT \
208 IADDR npc = 0; /* assign a value for -Wall */ \
96baa820 209 SEM_BRANCH_TYPE br_type = SEM_BRANCH_UNTAKEN;
c906108c
SS
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) \
216do { \
217 pbb_br_npc = npc; \
96baa820 218 pbb_br_type = br_type; \
c906108c
SS
219} while (0)
220#else /* 1 semantic function per instruction */
221#define SEM_BRANCH_FINI(pcvar) \
222do { \
223 CPU_PBB_BR_NPC (current_cpu) = npc; \
96baa820 224 CPU_PBB_BR_TYPE (current_cpu) = br_type; \
c906108c
SS
225} while (0)
226#endif
227
96baa820 228#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
c906108c
SS
229do { \
230 npc = (newval); \
96baa820 231 br_type = SEM_BRANCH_CACHEABLE; \
c906108c
SS
232} while (0)
233
234#define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
235do { \
236 npc = (newval); \
96baa820
JM
237 br_type = SEM_BRANCH_UNCACHEABLE; \
238} while (0)
239
240#define SEM_SKIP_COMPILE(cpu, sc, skip) \
241do { \
242 SEM_ARGBUF (sc) -> skip_count = (skip); \
243} while (0)
244
245#define SEM_SKIP_INSN(cpu, sc, vpcvar) \
246do { \
247 (vpcvar) += SEM_ARGBUF (sc) -> skip_count; \
c906108c
SS
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
c906108c
SS
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
085dd6e6 260#ifndef TARGET_SEM_BRANCH_FINI
c906108c
SS
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
96baa820 266#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
c906108c
SS
267do { \
268 (pcvar) = (newval); \
269 taken_p = 1; \
270} while (0)
271
272#define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
273do { \
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
96baa820 293#define SEM_BRANCH_VIA_CACHE(cpu, abuf, newval, pcvar) \
c906108c
SS
294do { \
295 (pcvar) = (newval); \
296 taken_p = 1; \
297} while (0)
298
299#define SEM_BRANCH_VIA_ADDR(cpu, abuf, newval, pcvar) \
300do { \
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\f
319/* Instruction information. */
320
96baa820 321/* Sanity check, at most one of these may be true. */
53a5351d
JM
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."
96baa820 324#endif
c906108c 325
96baa820 326/* Compile time computable instruction data. */
c906108c
SS
327
328struct 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
96baa820
JM
336 /* Semantic format number. */
337 int sfmt;
c906108c 338
53a5351d 339#if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_ONLY
c906108c
SS
340 /* Index in IDESC table of parallel handler. */
341 int par_index;
342#endif
343
344#if WITH_PARALLEL_READ
96baa820
JM
345 /* Index in IDESC table of read handler. */
346 int read_index;
c906108c
SS
347#endif
348
349#if WITH_PARALLEL_WRITE
96baa820 350 /* Index in IDESC table of writeback handler. */
c906108c
SS
351 int write_index;
352#endif
96baa820 353};
c906108c 354
96baa820
JM
355/* Entry in semantic function table.
356 This information is copied to the insn descriptor table at run-time. */
357
358struct 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;
c906108c
SS
364};
365
366/* Run-time computed instruction descriptor. */
367
368struct idesc {
96baa820 369#if WITH_SEM_SWITCH_FAST
c906108c 370#ifdef __GNUC__
96baa820 371 void *sem_fast_lab;
c906108c 372#else
96baa820 373 /* nothing needed, switch's on `num' member */
c906108c 374#endif
96baa820
JM
375#else
376 SEMANTIC_FN *sem_fast;
c906108c
SS
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
96baa820 389 /* Parallel support. */
53a5351d 390#if HAVE_PARALLEL_INSNS && (! WITH_PARALLEL_ONLY || (WITH_PARALLEL_ONLY && ! WITH_PARALLEL_GENWRITE))
96baa820
JM
391 /* Pointer to parallel handler if serial insn.
392 Pointer to readahead/writeback handler if parallel insn. */
393 struct idesc *par_idesc;
c906108c
SS
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
96baa820
JM
400 /* Semantic format id. */
401 int sfmt;
402
c906108c
SS
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\f
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 */
This page took 0.477748 seconds and 4 git commands to generate.