xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/cgen-engine.h (revision 88241920d21b339bf319c0e979ffda80c49a2936)
198b9484cSchristos /* Engine header for Cpu tools GENerated simulators.
2*88241920Schristos    Copyright (C) 1998-2024 Free Software Foundation, Inc.
398b9484cSchristos    Contributed by Cygnus Support.
498b9484cSchristos 
598b9484cSchristos This file is part of GDB, the GNU debugger.
698b9484cSchristos 
798b9484cSchristos This program is free software; you can redistribute it and/or modify
898b9484cSchristos it under the terms of the GNU General Public License as published by
998b9484cSchristos the Free Software Foundation; either version 3 of the License, or
1098b9484cSchristos (at your option) any later version.
1198b9484cSchristos 
1298b9484cSchristos This program is distributed in the hope that it will be useful,
1398b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1498b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598b9484cSchristos GNU General Public License for more details.
1698b9484cSchristos 
1798b9484cSchristos You should have received a copy of the GNU General Public License
1898b9484cSchristos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1998b9484cSchristos 
2098b9484cSchristos /* This file is included by ${cpu}.h.
2198b9484cSchristos    It needs CGEN_INSN_WORD which is defined by ${cpu}.h.
2298b9484cSchristos    ??? A lot of this could be moved to genmloop.sh to be put in eng.h
2398b9484cSchristos    and thus remove some conditional compilation.  We'd still need
2498b9484cSchristos    CGEN_INSN_WORD though.  */
2598b9484cSchristos 
2698b9484cSchristos /* Semantic functions come in six versions on two axes:
2798b9484cSchristos    fast/full-featured, and using one of the simple/scache/compilation engines.
2898b9484cSchristos    A full featured simulator is always provided.  --enable-sim-fast includes
2998b9484cSchristos    support for fast execution by duplicating the semantic code but leaving
3098b9484cSchristos    out all features like tracing and profiling.
3198b9484cSchristos    Using the scache is selected with --enable-sim-scache.  */
3298b9484cSchristos /* FIXME: --enable-sim-fast not implemented yet.  */
3398b9484cSchristos /* FIXME: undecided how to handle WITH_SCACHE_PBB.  */
3498b9484cSchristos 
3598b9484cSchristos /* There are several styles of engines, all generally supported by the
3698b9484cSchristos    same code:
3798b9484cSchristos 
3898b9484cSchristos    WITH_SCACHE && WITH_SCACHE_PBB - pseudo-basic-block scaching
3998b9484cSchristos    WITH_SCACHE && !WITH_SCACHE_PBB - scaching on an insn by insn basis
4098b9484cSchristos    !WITH_SCACHE - simple engine: fetch an insn, execute an insn
4198b9484cSchristos 
4298b9484cSchristos    The !WITH_SCACHE case can also be broken up into two flavours:
4398b9484cSchristos    extract the fields of the insn into an ARGBUF struct, or defer the
4498b9484cSchristos    extraction to the semantic handler.  The former can be viewed as the
4598b9484cSchristos    WITH_SCACHE case with a cache size of 1 (thus there's no need for a
4698b9484cSchristos    WITH_EXTRACTION macro).  The WITH_SCACHE case always extracts the fields
4798b9484cSchristos    into an ARGBUF struct.  */
4898b9484cSchristos 
4998b9484cSchristos #ifndef CGEN_ENGINE_H
5098b9484cSchristos #define CGEN_ENGINE_H
5198b9484cSchristos 
5298b9484cSchristos /* Instruction field support macros.  */
5398b9484cSchristos 
5498b9484cSchristos #define EXTRACT_MSB0_SINT(val, total, start, length) \
5598b9484cSchristos (((INT) (val) << ((sizeof (INT) * 8) - (total) + (start))) \
5698b9484cSchristos  >> ((sizeof (INT) * 8) - (length)))
5798b9484cSchristos #define EXTRACT_MSB0_UINT(val, total, start, length) \
5898b9484cSchristos (((UINT) (val) << ((sizeof (UINT) * 8) - (total) + (start))) \
5998b9484cSchristos  >> ((sizeof (UINT) * 8) - (length)))
6098b9484cSchristos 
6198b9484cSchristos #define EXTRACT_LSB0_SINT(val, total, start, length) \
6298b9484cSchristos (((INT) (val) << ((sizeof (INT) * 8) - (start) - 1)) \
6398b9484cSchristos  >> ((sizeof (INT) * 8) - (length)))
6498b9484cSchristos #define EXTRACT_LSB0_UINT(val, total, start, length) \
6598b9484cSchristos (((UINT) (val) << ((sizeof (UINT) * 8) - (start) - 1)) \
6698b9484cSchristos  >> ((sizeof (UINT) * 8) - (length)))
6798b9484cSchristos 
6898b9484cSchristos #define EXTRACT_MSB0_LGSINT(val, total, start, length) \
6998b9484cSchristos (((CGEN_INSN_LGSINT) (val) << ((sizeof (CGEN_INSN_LGSINT) * 8) - (total) + (start))) \
7098b9484cSchristos  >> ((sizeof (CGEN_INSN_LGSINT) * 8) - (length)))
7198b9484cSchristos #define EXTRACT_MSB0_LGUINT(val, total, start, length) \
7298b9484cSchristos (((CGEN_INSN_UINT) (val) << ((sizeof (CGEN_INSN_LGUINT) * 8) - (total) + (start))) \
7398b9484cSchristos  >> ((sizeof (CGEN_INSN_LGUINT) * 8) - (length)))
7498b9484cSchristos 
7598b9484cSchristos #define EXTRACT_LSB0_LGSINT(val, total, start, length) \
7698b9484cSchristos (((CGEN_INSN_LGSINT) (val) << ((sizeof (CGEN_INSN_LGSINT) * 8) - (start) - 1)) \
7798b9484cSchristos  >> ((sizeof (CGEN_INSN_LGSINT) * 8) - (length)))
7898b9484cSchristos #define EXTRACT_LSB0_LGUINT(val, total, start, length) \
7998b9484cSchristos (((CGEN_INSN_LGUINT) (val) << ((sizeof (CGEN_INSN_LGUINT) * 8) - (start) - 1)) \
8098b9484cSchristos  >> ((sizeof (CGEN_INSN_LGUINT) * 8) - (length)))
8198b9484cSchristos 
8298b9484cSchristos /* Semantic routines.  */
8398b9484cSchristos 
8498b9484cSchristos /* Type of the machine generated extraction fns.  */
8598b9484cSchristos /* ??? No longer used.  */
8698b9484cSchristos typedef void (EXTRACT_FN) (SIM_CPU *, IADDR, CGEN_INSN_WORD, ARGBUF *);
8798b9484cSchristos 
8898b9484cSchristos /* Type of the machine generated semantic fns.  */
8998b9484cSchristos 
9098b9484cSchristos #if WITH_SCACHE
9198b9484cSchristos 
9298b9484cSchristos /* Instruction fields are extracted into ARGBUF before calling the
9398b9484cSchristos    semantic routine.  */
9498b9484cSchristos #if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
9598b9484cSchristos typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *);
9698b9484cSchristos #else
9798b9484cSchristos typedef SEM_PC (SEMANTIC_FN) (SIM_CPU *, SEM_ARG);
9898b9484cSchristos #endif
9998b9484cSchristos 
10098b9484cSchristos #else
10198b9484cSchristos 
10298b9484cSchristos /* Result of semantic routines is a status indicator (wip).  */
10398b9484cSchristos typedef unsigned int SEM_STATUS;
10498b9484cSchristos 
10598b9484cSchristos /* Instruction fields are extracted by the semantic routine.
10698b9484cSchristos    ??? TODO: multi word insns.  */
10798b9484cSchristos #if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_GENWRITE
10898b9484cSchristos typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, PAREXEC *, CGEN_INSN_WORD);
10998b9484cSchristos #else
11098b9484cSchristos typedef SEM_STATUS (SEMANTIC_FN) (SIM_CPU *, SEM_ARG, CGEN_INSN_WORD);
11198b9484cSchristos #endif
11298b9484cSchristos 
11398b9484cSchristos #endif
11498b9484cSchristos 
11598b9484cSchristos /* In the ARGBUF struct, a pointer to the semantic routine for the insn.  */
11698b9484cSchristos 
11798b9484cSchristos union sem {
11898b9484cSchristos #if ! WITH_SEM_SWITCH_FULL
11998b9484cSchristos   SEMANTIC_FN *sem_full;
12098b9484cSchristos #endif
12198b9484cSchristos #if ! WITH_SEM_SWITCH_FAST
12298b9484cSchristos   SEMANTIC_FN *sem_fast;
12398b9484cSchristos #endif
12498b9484cSchristos #if WITH_SEM_SWITCH_FULL || WITH_SEM_SWITCH_FAST
12598b9484cSchristos #ifdef __GNUC__
12698b9484cSchristos   void *sem_case;
12798b9484cSchristos #else
12898b9484cSchristos   int sem_case;
12998b9484cSchristos #endif
13098b9484cSchristos #endif
13198b9484cSchristos };
13298b9484cSchristos 
13398b9484cSchristos /* Set the appropriate semantic handler in ABUF.  */
13498b9484cSchristos 
13598b9484cSchristos #if WITH_SEM_SWITCH_FULL
13698b9484cSchristos #ifdef __GNUC__
13798b9484cSchristos #define SEM_SET_FULL_CODE(abuf, idesc) \
13898b9484cSchristos   do { (abuf)->semantic.sem_case = (idesc)->sem_full_lab; } while (0)
13998b9484cSchristos #else
14098b9484cSchristos #define SEM_SET_FULL_CODE(abuf, idesc) \
14198b9484cSchristos   do { (abuf)->semantic.sem_case = (idesc)->num; } while (0)
14298b9484cSchristos #endif
14398b9484cSchristos #else
14498b9484cSchristos #define SEM_SET_FULL_CODE(abuf, idesc) \
14598b9484cSchristos   do { (abuf)->semantic.sem_full = (idesc)->sem_full; } while (0)
14698b9484cSchristos #endif
14798b9484cSchristos 
14898b9484cSchristos #if WITH_SEM_SWITCH_FAST
14998b9484cSchristos #ifdef __GNUC__
15098b9484cSchristos #define SEM_SET_FAST_CODE(abuf, idesc) \
15198b9484cSchristos   do { (abuf)->semantic.sem_case = (idesc)->sem_fast_lab; } while (0)
15298b9484cSchristos #else
15398b9484cSchristos #define SEM_SET_FAST_CODE(abuf, idesc) \
15498b9484cSchristos   do { (abuf)->semantic.sem_case = (idesc)->num; } while (0)
15598b9484cSchristos #endif
15698b9484cSchristos #else
15798b9484cSchristos #define SEM_SET_FAST_CODE(abuf, idesc) \
15898b9484cSchristos   do { (abuf)->semantic.sem_fast = (idesc)->sem_fast; } while (0)
15998b9484cSchristos #endif
16098b9484cSchristos 
16198b9484cSchristos #define SEM_SET_CODE(abuf, idesc, fast_p) \
16298b9484cSchristos do { \
16398b9484cSchristos   if (fast_p) \
16498b9484cSchristos     SEM_SET_FAST_CODE ((abuf), (idesc)); \
16598b9484cSchristos   else \
16698b9484cSchristos     SEM_SET_FULL_CODE ((abuf), (idesc)); \
16798b9484cSchristos } while (0)
16898b9484cSchristos 
16998b9484cSchristos /* Return non-zero if IDESC is a conditional or unconditional CTI.  */
17098b9484cSchristos 
17198b9484cSchristos #define IDESC_CTI_P(idesc) \
17298b9484cSchristos      ((CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) \
17398b9484cSchristos        & (CGEN_ATTR_MASK (CGEN_INSN_COND_CTI) \
17498b9484cSchristos 	  | CGEN_ATTR_MASK (CGEN_INSN_UNCOND_CTI))) \
17598b9484cSchristos       != 0)
17698b9484cSchristos 
17798b9484cSchristos /* Return non-zero if IDESC is a skip insn.  */
17898b9484cSchristos 
17998b9484cSchristos #define IDESC_SKIP_P(idesc) \
18098b9484cSchristos      ((CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) \
18198b9484cSchristos        & CGEN_ATTR_MASK (CGEN_INSN_SKIP_CTI)) \
18298b9484cSchristos       != 0)
18398b9484cSchristos 
18498b9484cSchristos /* Return pointer to ARGBUF given ptr to SCACHE.  */
18598b9484cSchristos #define SEM_ARGBUF(sem_arg) (& (sem_arg) -> argbuf)
18698b9484cSchristos 
18798b9484cSchristos #if WITH_SCACHE
18898b9484cSchristos 
18998b9484cSchristos #if WITH_SCACHE_PBB
19098b9484cSchristos 
19198b9484cSchristos /* Return the scache pointer of the current insn.  */
19298b9484cSchristos #define SEM_SEM_ARG(vpc, sc) (vpc)
19398b9484cSchristos 
19498b9484cSchristos /* Return the virtual pc of the next insn to execute
19598b9484cSchristos    (assuming this isn't a cti or the branch isn't taken).  */
19698b9484cSchristos #define SEM_NEXT_VPC(sem_arg, pc, len) ((sem_arg) + 1)
19798b9484cSchristos 
19898b9484cSchristos /* Update the instruction counter.  */
19998b9484cSchristos #define PBB_UPDATE_INSN_COUNT(cpu,sc) \
20098b9484cSchristos   (CPU_INSN_COUNT (cpu) += SEM_ARGBUF (sc) -> fields.chain.insn_count)
20198b9484cSchristos 
20298b9484cSchristos /* Do not append a `;' to invocations of this.
20398b9484cSchristos    npc,br_type are for communication between the cti insn and cti-chain.  */
20498b9484cSchristos #define SEM_BRANCH_INIT \
20598b9484cSchristos   IADDR npc = 0; /* assign a value for -Wall */ \
20698b9484cSchristos   SEM_BRANCH_TYPE br_type = SEM_BRANCH_UNTAKEN;
20798b9484cSchristos 
20898b9484cSchristos /* SEM_IN_SWITCH is defined at the top of the mainloop.c files
20998b9484cSchristos    generated by genmloop.sh.  It exists so generated semantic code needn't
21098b9484cSchristos    care whether it's being put in a switch or in a function.  */
21198b9484cSchristos #ifdef SEM_IN_SWITCH
21298b9484cSchristos #define SEM_BRANCH_FINI(pcvar) \
21398b9484cSchristos do { \
21498b9484cSchristos   pbb_br_npc = npc; \
21598b9484cSchristos   pbb_br_type = br_type; \
21698b9484cSchristos } while (0)
21798b9484cSchristos #else /* 1 semantic function per instruction */
21898b9484cSchristos #define SEM_BRANCH_FINI(pcvar) \
21998b9484cSchristos do { \
22098b9484cSchristos   CPU_PBB_BR_NPC (current_cpu) = npc; \
22198b9484cSchristos   CPU_PBB_BR_TYPE (current_cpu) = br_type; \
22298b9484cSchristos } while (0)
22398b9484cSchristos #endif
22498b9484cSchristos 
22598b9484cSchristos #define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
22698b9484cSchristos do { \
22798b9484cSchristos   npc = (newval); \
22898b9484cSchristos   br_type = SEM_BRANCH_CACHEABLE; \
22998b9484cSchristos } while (0)
23098b9484cSchristos 
23198b9484cSchristos #define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
23298b9484cSchristos do { \
23398b9484cSchristos   npc = (newval); \
23498b9484cSchristos   br_type = SEM_BRANCH_UNCACHEABLE; \
23598b9484cSchristos } while (0)
23698b9484cSchristos 
23798b9484cSchristos #define SEM_SKIP_COMPILE(cpu, sc, skip) \
23898b9484cSchristos do { \
23998b9484cSchristos   SEM_ARGBUF (sc) -> skip_count = (skip); \
24098b9484cSchristos } while (0)
24198b9484cSchristos 
24298b9484cSchristos #define SEM_SKIP_INSN(cpu, sc, vpcvar) \
24398b9484cSchristos do { \
24498b9484cSchristos   (vpcvar) += SEM_ARGBUF (sc) -> skip_count; \
24598b9484cSchristos } while (0)
24698b9484cSchristos 
24798b9484cSchristos #else /* ! WITH_SCACHE_PBB */
24898b9484cSchristos 
24998b9484cSchristos #define SEM_SEM_ARG(vpc, sc) (sc)
25098b9484cSchristos 
25198b9484cSchristos #define SEM_NEXT_VPC(sem_arg, pc, len) ((pc) + (len))
25298b9484cSchristos 
25398b9484cSchristos /* ??? May wish to move taken_p out of here and make it explicit.  */
25498b9484cSchristos #define SEM_BRANCH_INIT \
25598b9484cSchristos   int taken_p = 0;
25698b9484cSchristos 
25798b9484cSchristos #ifndef TARGET_SEM_BRANCH_FINI
25898b9484cSchristos #define TARGET_SEM_BRANCH_FINI(pcvar, taken_p)
25998b9484cSchristos #endif
26098b9484cSchristos #define SEM_BRANCH_FINI(pcvar) \
26198b9484cSchristos   do { TARGET_SEM_BRANCH_FINI (pcvar, taken_p); } while (0)
26298b9484cSchristos 
26398b9484cSchristos #define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \
26498b9484cSchristos do { \
26598b9484cSchristos   (pcvar) = (newval); \
26698b9484cSchristos   taken_p = 1; \
26798b9484cSchristos } while (0)
26898b9484cSchristos 
26998b9484cSchristos #define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \
27098b9484cSchristos do { \
27198b9484cSchristos   (pcvar) = (newval); \
27298b9484cSchristos   taken_p = 1; \
27398b9484cSchristos } while (0)
27498b9484cSchristos 
27598b9484cSchristos #endif /* ! WITH_SCACHE_PBB */
27698b9484cSchristos 
27798b9484cSchristos #else /* ! WITH_SCACHE */
27898b9484cSchristos 
27998b9484cSchristos /* This is the "simple" engine case.  */
28098b9484cSchristos 
28198b9484cSchristos #define SEM_SEM_ARG(vpc, sc) (sc)
28298b9484cSchristos 
28398b9484cSchristos #define SEM_NEXT_VPC(sem_arg, pc, len) ((pc) + (len))
28498b9484cSchristos 
28598b9484cSchristos #define SEM_BRANCH_INIT \
28698b9484cSchristos   int taken_p = 0;
28798b9484cSchristos 
28898b9484cSchristos #define SEM_BRANCH_VIA_CACHE(cpu, abuf, newval, pcvar) \
28998b9484cSchristos do { \
29098b9484cSchristos   (pcvar) = (newval); \
29198b9484cSchristos   taken_p = 1; \
29298b9484cSchristos } while (0)
29398b9484cSchristos 
29498b9484cSchristos #define SEM_BRANCH_VIA_ADDR(cpu, abuf, newval, pcvar) \
29598b9484cSchristos do { \
29698b9484cSchristos   (pcvar) = (newval); \
29798b9484cSchristos   taken_p = 1; \
29898b9484cSchristos } while (0)
29998b9484cSchristos 
30098b9484cSchristos /* Finish off branch insns.
30198b9484cSchristos    The target must define TARGET_SEM_BRANCH_FINI.
30298b9484cSchristos    ??? This can probably go away when define-execute is finished.  */
30398b9484cSchristos #define SEM_BRANCH_FINI(pcvar, bool_attrs) \
30498b9484cSchristos   do { TARGET_SEM_BRANCH_FINI ((pcvar), (bool_attrs), taken_p); } while (0)
30598b9484cSchristos 
30698b9484cSchristos /* Finish off non-branch insns.
30798b9484cSchristos    The target must define TARGET_SEM_NBRANCH_FINI.
30898b9484cSchristos    ??? This can probably go away when define-execute is finished.  */
30998b9484cSchristos #define SEM_NBRANCH_FINI(pcvar, bool_attrs) \
31098b9484cSchristos   do { TARGET_SEM_NBRANCH_FINI ((pcvar), (bool_attrs)); } while (0)
31198b9484cSchristos 
31298b9484cSchristos #endif /* ! WITH_SCACHE */
31398b9484cSchristos 
31498b9484cSchristos /* Instruction information.  */
31598b9484cSchristos 
31698b9484cSchristos /* Sanity check, at most one of these may be true.  */
31798b9484cSchristos #if WITH_PARALLEL_READ + WITH_PARALLEL_WRITE + WITH_PARALLEL_GENWRITE > 1
31898b9484cSchristos #error "At most one of WITH_PARALLEL_{READ,WRITE,GENWRITE} can be true."
31998b9484cSchristos #endif
32098b9484cSchristos 
32198b9484cSchristos /* Compile time computable instruction data.  */
32298b9484cSchristos 
32398b9484cSchristos struct insn_sem {
32498b9484cSchristos   /* The instruction type (a number that identifies each insn over the
32598b9484cSchristos      entire architecture).  */
32698b9484cSchristos   CGEN_INSN_TYPE type;
32798b9484cSchristos 
32898b9484cSchristos   /* Index in IDESC table.  */
32998b9484cSchristos   int index;
33098b9484cSchristos 
33198b9484cSchristos   /* Semantic format number.  */
33298b9484cSchristos   int sfmt;
33398b9484cSchristos 
33498b9484cSchristos #if HAVE_PARALLEL_INSNS && ! WITH_PARALLEL_ONLY
33598b9484cSchristos   /* Index in IDESC table of parallel handler.  */
33698b9484cSchristos   int par_index;
33798b9484cSchristos #endif
33898b9484cSchristos 
33998b9484cSchristos #if WITH_PARALLEL_READ
34098b9484cSchristos   /* Index in IDESC table of read handler.  */
34198b9484cSchristos   int read_index;
34298b9484cSchristos #endif
34398b9484cSchristos 
34498b9484cSchristos #if WITH_PARALLEL_WRITE
34598b9484cSchristos   /* Index in IDESC table of writeback handler.  */
34698b9484cSchristos   int write_index;
34798b9484cSchristos #endif
34898b9484cSchristos };
34998b9484cSchristos 
35098b9484cSchristos /* Entry in semantic function table.
35198b9484cSchristos    This information is copied to the insn descriptor table at run-time.  */
35298b9484cSchristos 
35398b9484cSchristos struct sem_fn_desc {
35498b9484cSchristos   /* Index in IDESC table.  */
35598b9484cSchristos   int index;
35698b9484cSchristos 
35798b9484cSchristos   /* Function to perform the semantics of the insn.  */
35898b9484cSchristos   SEMANTIC_FN *fn;
35998b9484cSchristos };
36098b9484cSchristos 
36198b9484cSchristos /* Run-time computed instruction descriptor.  */
36298b9484cSchristos 
36398b9484cSchristos struct idesc {
36498b9484cSchristos #if WITH_SEM_SWITCH_FAST
36598b9484cSchristos #ifdef __GNUC__
36698b9484cSchristos   void *sem_fast_lab;
36798b9484cSchristos #else
36898b9484cSchristos   /* nothing needed, switch's on `num' member */
36998b9484cSchristos #endif
37098b9484cSchristos #else
37198b9484cSchristos   SEMANTIC_FN *sem_fast;
37298b9484cSchristos #endif
37398b9484cSchristos 
37498b9484cSchristos #if WITH_SEM_SWITCH_FULL
37598b9484cSchristos #ifdef __GNUC__
37698b9484cSchristos   void *sem_full_lab;
37798b9484cSchristos #else
37898b9484cSchristos   /* nothing needed, switch's on `num' member */
37998b9484cSchristos #endif
38098b9484cSchristos #else
38198b9484cSchristos   SEMANTIC_FN *sem_full;
38298b9484cSchristos #endif
38398b9484cSchristos 
38498b9484cSchristos   /* Parallel support.  */
38598b9484cSchristos #if HAVE_PARALLEL_INSNS && (! WITH_PARALLEL_ONLY || (WITH_PARALLEL_ONLY && ! WITH_PARALLEL_GENWRITE))
38698b9484cSchristos   /* Pointer to parallel handler if serial insn.
38798b9484cSchristos      Pointer to readahead/writeback handler if parallel insn.  */
38898b9484cSchristos   struct idesc *par_idesc;
38998b9484cSchristos #endif
39098b9484cSchristos 
39198b9484cSchristos   /* Instruction number (index in IDESC table, profile table).
39298b9484cSchristos      Also used to switch on in non-gcc semantic switches.  */
39398b9484cSchristos   int num;
39498b9484cSchristos 
39598b9484cSchristos   /* Semantic format id.  */
39698b9484cSchristos   int sfmt;
39798b9484cSchristos 
39898b9484cSchristos   /* instruction data (name, attributes, size, etc.) */
39998b9484cSchristos   const CGEN_INSN *idata;
40098b9484cSchristos 
40198b9484cSchristos   /* instruction attributes, copied from `idata' for speed */
40298b9484cSchristos   const CGEN_INSN_ATTR_TYPE *attrs;
40398b9484cSchristos 
40498b9484cSchristos   /* instruction length in bytes, copied from `idata' for speed */
40598b9484cSchristos   int length;
40698b9484cSchristos 
40798b9484cSchristos   /* profiling/modelling support */
40898b9484cSchristos   const INSN_TIMING *timing;
40998b9484cSchristos };
41098b9484cSchristos 
41198b9484cSchristos /* Tracing/profiling.  */
41298b9484cSchristos 
41398b9484cSchristos /* Return non-zero if a before/after handler is needed.
41498b9484cSchristos    When tracing/profiling a selected range there's no need to slow
41598b9484cSchristos    down simulation of the other insns (except to get more accurate data!).
41698b9484cSchristos 
41798b9484cSchristos    ??? May wish to profile all insns if doing insn tracing, or to
41898b9484cSchristos    get more accurate cycle data.
41998b9484cSchristos 
42098b9484cSchristos    First test ANY_P so we avoid a potentially expensive HIT_P call
42198b9484cSchristos    [if there are lots of address ranges].  */
42298b9484cSchristos 
42398b9484cSchristos #define PC_IN_TRACE_RANGE_P(cpu, pc) \
42498b9484cSchristos   (TRACE_ANY_P (cpu) \
42598b9484cSchristos    && ADDR_RANGE_HIT_P (TRACE_RANGE (CPU_TRACE_DATA (cpu)), (pc)))
42698b9484cSchristos #define PC_IN_PROFILE_RANGE_P(cpu, pc) \
42798b9484cSchristos   (PROFILE_ANY_P (cpu) \
42898b9484cSchristos    && ADDR_RANGE_HIT_P (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)), (pc)))
42998b9484cSchristos 
43098b9484cSchristos #endif /* CGEN_ENGINE_H */
431