URL
https://opencores.org/ocsvn/scarts/scarts/trunk
Subversion Repositories scarts
[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [sid-decode.scm] - Rev 6
Compare with Previous | Blame | View Log
; Decoder generation. ; Copyright (C) 2000, 2002, 2003, 2009 Red Hat, Inc. ; This file is part of CGEN. ; Return decode entries for each insn. ; ??? At one point we generated one variable per instruction rather than one ; big array. It doesn't matter too much (yet). Generating one big array is ; simpler. ; Print the higher detailed stuff at higher verbosity. "Processing decode insn globals ...\n"" // The instruction descriptor array. \n""\ // Have label pointers been initialized? // XXX: Note that this is also needed by when semantics are implemented as // functions to handle machine variants. bool @prefix@_idesc::idesc_table_initialized_p = false;\n\n""""\ @prefix@_idesc @prefix@_idesc::idesc_table[@PREFIX@_INSN_"" + 1] = {\n"" { ""0, """"0, "", """"\"""\", "", "" },\n""\n};\n\n"; Return a function that lookups up virtual insns. "\ // Given a canonical virtual insn id, return the target specific one. @prefix@_insn_type @prefix@_idesc::lookup_virtual (virtual_insn_type vit) { switch (vit) { case VIRTUAL_INSN_INVALID: return @PREFIX@_INSN_X_INVALID; ""\ case VIRTUAL_INSN_BEGIN: return @PREFIX@_INSN_X_BEGIN; case VIRTUAL_INSN_CHAIN: return @PREFIX@_INSN_X_CHAIN; case VIRTUAL_INSN_CTI_CHAIN: return @PREFIX@_INSN_X_CTI_CHAIN; case VIRTUAL_INSN_BEFORE: return @PREFIX@_INSN_X_BEFORE; case VIRTUAL_INSN_AFTER: return @PREFIX@_INSN_X_AFTER; """"\ case VIRTUAL_INSN_COND: return @PREFIX@_INSN_X_COND; "; Unused, but may still be requested. Just return X_INVALID. "\ case VIRTUAL_INSN_COND: return @PREFIX@_INSN_X_INVALID; ""\ } abort (); }\n\n"; Return enum name of format FMT. ; Return names of semantic fns for INSN. ; ??? Make global, call from gen-semantic-fn, blah blah blah. "@prefix@_sem_"; Return decls of each semantic fn. "// Decls of each semantic fn.\n\n""using @cpu@::@prefix@_sem_fn;\n""extern @prefix@_sem_fn "";\n""\n"; idesc, argbuf, and scache types ; Generate decls for the insn descriptor table type IDESC. " // Forward decls. struct @cpu@_cpu; struct @prefix@_scache; ""typedef void (@prefix@_sem_fn) (@cpu@_cpu* cpu, @prefix@_scache* sem, int tick, @prefix@::write_stacks &buf);""typedef sem_status (@prefix@_sem_fn) (@cpu@_cpu* cpu, @prefix@_scache* sem);""\n""\n"" // Instruction descriptor. struct @prefix@_idesc { \n""\ // computed-goto label pointer (pbb engine) // FIXME: frag case to be redone (should instead point to usage table). cgoto_label cgoto;\n\n""""\ // scache engine executor for this insn @prefix@_sem_fn* execute;\n\n""""\ const char* insn_name; enum @prefix@_insn_type sem_index; @arch@_insn_attr attrs; // idesc table: indexed by sem_index static @prefix@_idesc idesc_table[]; ""\ // semantic label pointers filled_in? static bool idesc_table_initialized_p;\n""""\ static @prefix@_insn_type lookup_virtual (virtual_insn_type vit); }; "; Utility of -gen-argbuf-fields-union to generate the definition for ; <sformat-abuf> SBUF. "Processing sbuf format "" ...\n"" struct { /* "" */\n"" int empty;\n"" "" "";\n"" } "";\n"; Utility of -gen-scache-decls to generate the union of extracted ifields. "\ // Instruction argument buffer. union @prefix@_sem_fields {\n""\ // This one is for chain/cti-chain virtual insns. struct { // Number of insns in pbb. unsigned insn_count; // This is used by chain insns and by untaken conditional branches. @prefix@_scache* next; @prefix@_scache* branch_target; } chain; // This one is for `before' virtual insns. struct { // The cache entry of the real insn. @prefix@_scache* insn; } before; };\n\n""\ // Simulator instruction cache. struct @prefix@_scache { // executor union { cgoto_label cgoto; @prefix@_sem_fn* fn; } execute; \n""\ // condition UINT cond; \n""""\ // PC of this instruction. PCADDR addr; // instruction class @prefix@_idesc* idesc; // argument buffer @prefix@_sem_fields fields; "" // writeback flags // Only used if profiling or parallel execution support enabled during // file generation. unsigned long long written; """" // decode given instruction void decode (@cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn); }; "; Instruction field extraction support. ; Two implementations are provided, one for !with-scache and one for ; with-scache. ; ; Extracting ifields is a three phase process. First the ifields are ; extracted and stored in local variables. Then any ifields requiring ; additional processing for operands are handled. Then in the with-scache ; case the results are stored in a struct for later retrieval by the semantic ; code. ; ; The !with-scache case does this processing in the semantic function, ; except it doesn't need the last step (it doesn't need to store the results ; in a struct for later use). ; ; The with-scache case extracts the ifields in the decode function. ; Furthermore, we use <sformat-argbuf> to reduce the quantity of structures ; created (this helps semantic-fragment pbb engines). ; Return C code to record <ifield> F for the semantic handler ; in a local variable rather than an ARGBUF struct. " "" = "";\n"; Return three of arguments to TRACE: ; string argument to fprintf, character indicating type of third arg, value. ; The type is one of: x. ; FIXME: Add method to return fprintf format string. ", \""" 0x%x\""", 'x'"", "; Instruction field extraction support cont'd. ; Hardware support. ; gen-extract method. ; For the default case we use the ifield as is, which is output elsewhere. ""; gen-trace-extract method. ; Return appropriate arguments for TRACE_EXTRACT. ""; Extract the necessary fields into ARGBUF. " "" = & "";\n"""; Return appropriate arguments for TRACE_EXTRACT. ; FIXME: Add method to return fprintf format string. ", \""" 0x%x\""", 'x'"", """; Extract the necessary fields into ARGBUF. " "" = "";\n"; Return appropriate arguments for TRACE_EXTRACT. ; FIXME: Add method to return fprintf format string. ", \""" 0x%x\""", 'x'"", "; Instruction field extraction support cont'd. ; Operand support. ; Return C code to record the field for the semantic handler. ; In the case of a register, this is usually the address of the register's ; value (if CACHE-ADDR). ; LOCAL? indicates whether to record the value in a local variable or in ; the ARGBUF struct. ; ??? Later allow target to provide an `extract' expression. ; Return three of arguments to TRACE_EXTRACT: ; string argument to fprintf, character indicating type of third arg, value. ; The type is one of: x. ; Return C code to define local vars to hold processed ifield data for ; <sformat> SFMT. ; This is used when !with-scache. ; Definitions of the extracted ifields is handled elsewhere. "sfmt = "" operands="" "" "";\n"""; Return C code to assign values to the local vars that hold processed ifield ; data for <sformat> SFMT. ; This is used when !with-scache. ; Assignment of the extracted ifields is handled elsewhere. ; Instruction field extraction support cont'd. ; Emit extraction section of decode function. ; Return C code to record insn field data for <sformat> SFMT. ; This is used when with-scache. " /* Record the fields for the semantic handler. */\n"" if (UNLIKELY(current_cpu->trace_extract_p))\n"" {\n"" current_cpu->trace_stream \n"" << \"0x\" << hex << pc << dec << \" ("")\\t\"\n"; NB: The following is not necessary any more, as the ifield list ; is a subset of the operand list. ; (string-list-map (lambda (f) ; (string-list ; " << \" " (gen-sym f) ":0x\" << hex << " (gen-sym f) " << dec\n")) ; iflds) " << \" "":0x\" << hex << "; Add (SI) or (USI) cast for byte-wide data, to prevent C++ iostreams ; from printing byte as plain raw char. """(SI) ""(USI) """" << dec\n"" << endl;\n"" }\n"; Return C code to record insn field data for profiling. ; Also recorded are operands not mentioned in the fields but mentioned ; in the semantic code. ; ; FIXME: Register usage may need to be tracked as an array of longs. ; If there are more than 32 regs, we can't know which until build time. ; ??? For now we only handle reg sets of 32 or less. ; ; ??? The other way to obtain register numbers is to defer computing them ; until they're actually needed. It will speed up execution when not doing ; profiling, though the speed up is only for the extraction phase. ; On the other hand the current way has one memory reference per register ; number in the profiling routines. For RISC this can be a lose, though for ; more complicated instruction sets it could be a win as all the computation ; is kept to the extraction phase. If someone wants to put forth some real ; data, this might then be changed (or at least noted). """ /* Record the fields for profiling. */\n"" if (UNLIKELY (current_cpu->trace_counter_p || current_cpu->final_insn_count_p))\n"" {\n"" }\n"; Return C code that extracts the fields of <sformat> SFMT. ; ; Extraction is based on formats to reduce the amount of code generated. ; However, we also need to emit code which records the hardware elements used ; by the semantic code. This is currently done by recording this information ; with the format. "Processing extractor for \"""\" ...\n""void @prefix@_extract_"" (@prefix@_scache* abuf, @cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn)""{\n"" @prefix@_insn_word insn = ""entire_insn;\n""base_insn;\n"" ""\n"" ""\n""\n""}\n\n"; For each format, return its extraction function. "Processing extractor fn bodies ...\n""Processing extractor fn declarations ...\n"" static void @prefix@_extract_"" (@prefix@_scache* abuf, @cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn);"; Generate top level decoder. ; INITIAL-BITNUMS is a target supplied list of bit numbers to use to ; build the first decode table. If nil, we compute 8 bits of it (FIXME) ; ourselves. ; LSB0? is non-#f if bit number 0 is the least significant bit. ; Compute the initial DECODE-BITSIZE as the minimum of all insn lengths. ; The caller of @prefix@_decode must fetch and pass exactly this number of bits ; of the instruction. ; ??? Make this a parameter later but only if necessary. ; Compute INITIAL-BITNUMS if not supplied. ; 0 is passed for the start bit (it is independent of lsb0?) ; dummy value ; startbit ; max ; All set. gen-decoder does the hard part, we just print out the result. " "" // Declare extractor functions "" // Fetch & decode instruction void @prefix@_scache::decode (@cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn) { /* Result of decoder. */ @PREFIX@_INSN_TYPE itype; { @prefix@_insn_word insn = base_insn; \n"" } /* The instruction has been decoded and fields extracted. */ done: "" {\n"" "" ""base_insn"" this->cond = "";\n"" }\n"""" this->addr = pc; // FIXME: To be redone (to handle ISA variants). this->idesc = & @prefix@_idesc::idesc_table[itype]; // ??? record semantic handler? assert(this->idesc->sem_index == itype); } "; Entry point. Generate decode.h. "Generating ""-decode.h ...\n"; Turn parallel execution support on if cpu needs it. "Decode header for @prefix@.""\ #ifndef @PREFIX@_DECODE_H #define @PREFIX@_DECODE_H ""\ namespace @prefix@ { // forward declaration of struct in -defs.h struct write_stacks; } """"\ namespace @cpu@ { using namespace cgen; using namespace @arch@; typedef UINT @prefix@_insn_word; ""\ } // end @cpu@ namespace \n"; ??? The semantic functions could go in the cpu's namespace. ; There's no pressing need for it though. """\ #endif /* @PREFIX@_DECODE_H */\n"; Entry point. Generate decode.cxx. "Generating ""-decode.cxx ...\n"; Turn parallel execution support on if cpu needs it. ; Tell the rtx->c translator we are the simulator. "Simulator instruction decoder for @prefix@.""\ #if HAVE_CONFIG_H #include \"config.h\" #endif #include \"@cpu@.h\" using namespace @cpu@; // FIXME: namespace organization still wip \n"