diff options
Diffstat (limited to 'sim/common/cgen-engine.h')
-rw-r--r-- | sim/common/cgen-engine.h | 132 |
1 files changed, 52 insertions, 80 deletions
diff --git a/sim/common/cgen-engine.h b/sim/common/cgen-engine.h index e7d27e03588..fbcf3e5fc1a 100644 --- a/sim/common/cgen-engine.h +++ b/sim/common/cgen-engine.h @@ -180,11 +180,6 @@ do { \ & CGEN_ATTR_MASK (CGEN_INSN_SKIP_CTI)) \ != 0) -/* These are used so that we can compile two copies of the semantic code, - one with full feature support and one without that runs fast(er). */ -#define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_sem_,fn) -#define SEMF_FN_NAME(cpu,fn) XCONCAT3 (cpu,_semf_,fn) - /* Return pointer to ARGBUF given ptr to SCACHE. */ #define SEM_ARGBUF(sem_arg) (& (sem_arg) -> argbuf) @@ -217,22 +212,11 @@ do { \ #define PBB_UPDATE_INSN_COUNT(cpu,sc) \ (CPU_INSN_COUNT (cpu) += SEM_ARGBUF (sc) -> fields.chain.insn_count) -/* Value for br_addr_ptr indicating branch wasn't taken. */ -#define SEM_BRANCH_UNTAKEN ((SEM_PC *) 0) - -/* Value for br_addr_ptr indicating branch was taken to uncacheable - address (e.g. j reg). */ -#define SEM_BRANCH_UNCACHEABLE ((SEM_PC *) 1) - -/* Initialize next-pbb link for SEM_BRANCH_VIA_CACHE. */ -#define SEM_BRANCH_INIT_EXTRACT(abuf) \ -do { (abuf)->fields.cti.addr_cache = 0; } while (0) - /* Do not append a `;' to invocations of this. - npc,npc_ptr are for communication between the cti insn and cti-chain. */ + npc,br_type are for communication between the cti insn and cti-chain. */ #define SEM_BRANCH_INIT \ IADDR npc = 0; /* assign a value for -Wall */ \ - SEM_PC *npc_ptr = SEM_BRANCH_UNTAKEN; + SEM_BRANCH_TYPE br_type = SEM_BRANCH_UNTAKEN; /* SEM_IN_SWITCH is defined at the top of the mainloop.c files generated by genmloop.sh. It exists so generated semantic code needn't @@ -241,30 +225,36 @@ do { (abuf)->fields.cti.addr_cache = 0; } while (0) #define SEM_BRANCH_FINI(pcvar) \ do { \ pbb_br_npc = npc; \ - pbb_br_npc_ptr = npc_ptr; \ + pbb_br_type = br_type; \ } while (0) #else /* 1 semantic function per instruction */ #define SEM_BRANCH_FINI(pcvar) \ do { \ CPU_PBB_BR_NPC (current_cpu) = npc; \ - CPU_PBB_BR_NPC_PTR (current_cpu) = npc_ptr; \ + CPU_PBB_BR_TYPE (current_cpu) = br_type; \ } while (0) #endif -/* Return address of cached branch address value. */ -#define SEM_BRANCH_ADDR_CACHE(sem_arg) \ - (& SEM_ARGBUF (sem_arg)->fields.cti.addr_cache) - -#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar, cachevarptr) \ +#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \ do { \ npc = (newval); \ - npc_ptr = (cachevarptr); \ + br_type = SEM_BRANCH_CACHEABLE; \ } while (0) #define SEM_BRANCH_VIA_ADDR(cpu, sc, newval, pcvar) \ do { \ npc = (newval); \ - npc_ptr = SEM_BRANCH_UNCACHEABLE; \ + br_type = SEM_BRANCH_UNCACHEABLE; \ +} while (0) + +#define SEM_SKIP_COMPILE(cpu, sc, skip) \ +do { \ + SEM_ARGBUF (sc) -> skip_count = (skip); \ +} while (0) + +#define SEM_SKIP_INSN(cpu, sc, vpcvar) \ +do { \ + (vpcvar) += SEM_ARGBUF (sc) -> skip_count; \ } while (0) #else /* ! WITH_SCACHE_PBB */ @@ -273,8 +263,6 @@ do { \ #define SEM_NEXT_VPC(sem_arg, pc, len) ((pc) + (len)) -#define SEM_BRANCH_INIT_EXTRACT(abuf) do { } while (0) - /* ??? May wish to move taken_p out of here and make it explicit. */ #define SEM_BRANCH_INIT \ int taken_p = 0; @@ -285,9 +273,7 @@ do { \ #define SEM_BRANCH_FINI(pcvar) \ do { TARGET_SEM_BRANCH_FINI (pcvar, taken_p); } while (0) -#define SEM_BRANCH_ADDR_CACHE(sem_arg) shouldnt_be_used - -#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar, cachevar) \ +#define SEM_BRANCH_VIA_CACHE(cpu, sc, newval, pcvar) \ do { \ (pcvar) = (newval); \ taken_p = 1; \ @@ -314,9 +300,7 @@ do { \ #define SEM_BRANCH_INIT \ int taken_p = 0; -#define SEM_BRANCH_ADDR_CACHE(sem_arg) shouldnt_be_used - -#define SEM_BRANCH_VIA_CACHE(cpu, abuf, newval, pcvar, cachevar) \ +#define SEM_BRANCH_VIA_CACHE(cpu, abuf, newval, pcvar) \ do { \ (pcvar) = (newval); \ taken_p = 1; \ @@ -344,10 +328,12 @@ do { \ /* Instruction information. */ -/* Compile time computable instruction data. +/* Sanity check, at most one of these may be true. */ +#if WITH_PARALLEL_READ && WITH_PARALLEL_WRITE +#error "Both WITH_PARALLEL_READ && WITH_PARALLEL_WRITE can't be true." +#endif - ??? May wish to move parallel execution support into its own struct. - It's a fair bit of "clutter" for the "normal" case. */ +/* Compile time computable instruction data. */ struct insn_sem { /* The instruction type (a number that identifies each insn over the @@ -357,10 +343,8 @@ struct insn_sem { /* Index in IDESC table. */ int index; - /* Sanity check, at most one of these may be true. */ -#if WITH_PARALLEL_READ && WITH_PARALLEL_WRITE -#error "Both WITH_PARALLEL_READ && WITH_PARALLEL_WRITE can't be true." -#endif + /* Semantic format number. */ + int sfmt; #if WITH_PARALLEL_READ || WITH_PARALLEL_WRITE /* Index in IDESC table of parallel handler. */ @@ -368,50 +352,38 @@ struct insn_sem { #endif #if WITH_PARALLEL_READ -#ifndef __GNUC__ - /* Semantic format number of pre-read handler. - Only used by chips that support parallel execution of several insns. - It is always implemented as a `switch'. In the case of GNUC we use - computed gotos. When not GNUC, this is the argument to `switch'. */ - int fmt; -#endif + /* Index in IDESC table of read handler. */ + int read_index; #endif #if WITH_PARALLEL_WRITE - /* Index in IDESC table of writeback handler. - Only used by chips that support parallel execution of several insns. */ + /* Index in IDESC table of writeback handler. */ int write_index; #endif +}; - /* Routines to execute the insn. - The full version has all features (profiling,tracing) compiled in. - The fast version has none of that. */ -#if ! WITH_SEM_SWITCH_FULL - SEMANTIC_FN *sem_full; -#endif -#if WITH_FAST && ! WITH_SEM_SWITCH_FAST - SEMANTIC_FN *sem_fast; -#endif +/* Entry in semantic function table. + This information is copied to the insn descriptor table at run-time. */ + +struct sem_fn_desc { + /* Index in IDESC table. */ + int index; + + /* Function to perform the semantics of the insn. */ + SEMANTIC_FN *fn; }; /* Run-time computed instruction descriptor. */ struct idesc { - /* Parallel read-before-exec support. */ -#if WITH_PARALLEL_READ - struct idesc *par_idesc; +#if WITH_SEM_SWITCH_FAST #ifdef __GNUC__ - void *read; + void *sem_fast_lab; #else - int fmt; -#endif + /* nothing needed, switch's on `num' member */ #endif - - /* Parallel write-after-exec support. */ -#if WITH_PARALLEL_WRITE - /* Pointer to parallel handler if serial insn. - Pointer to writeback handler if parallel insn. */ - struct idesc *par_idesc; +#else + SEMANTIC_FN *sem_fast; #endif #if WITH_SEM_SWITCH_FULL @@ -424,20 +396,20 @@ struct idesc { SEMANTIC_FN *sem_full; #endif -#if WITH_SEM_SWITCH_FAST -#ifdef __GNUC__ - void *sem_fast_lab; -#else - /* nothing needed, switch's on `num' member */ -#endif -#else - SEMANTIC_FN *sem_fast; + /* Parallel support. */ +#if WITH_PARALLEL_READ || WITH_PARALLEL_WRITE + /* Pointer to parallel handler if serial insn. + Pointer to readahead/writeback handler if parallel insn. */ + struct idesc *par_idesc; #endif /* Instruction number (index in IDESC table, profile table). Also used to switch on in non-gcc semantic switches. */ int num; + /* Semantic format id. */ + int sfmt; + /* instruction data (name, attributes, size, etc.) */ const CGEN_INSN *idata; |