133965Sjdp/* Header file for targets using CGEN: Cpu tools GENerator. 233965Sjdp 3218822SdimCopyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 4130561SobrienFree Software Foundation, Inc. 533965Sjdp 633965SjdpThis file is part of GDB, the GNU debugger, and the GNU Binutils. 733965Sjdp 833965SjdpThis program is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2 of the License, or 1133965Sjdp(at your option) any later version. 1233965Sjdp 1333965SjdpThis program is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1838889SjdpYou should have received a copy of the GNU General Public License along 1938889Sjdpwith this program; if not, write to the Free Software Foundation, Inc., 20218822Sdim51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2133965Sjdp 2233965Sjdp#ifndef CGEN_H 2333965Sjdp#define CGEN_H 2433965Sjdp 25218822Sdim#include "symcat.h" 26218822Sdim#include "cgen-bitset.h" 2760484Sobrien/* ??? This file requires bfd.h but only to get bfd_vma. 2860484Sobrien Seems like an awful lot to require just to get such a fundamental type. 2960484Sobrien Perhaps the definition of bfd_vma can be moved outside of bfd.h. 3060484Sobrien Or perhaps one could duplicate its definition in another file. 3160484Sobrien Until such time, this file conditionally compiles definitions that require 32130561Sobrien bfd_vma using __BFD_H_SEEN__. */ 3360484Sobrien 3460484Sobrien/* Enums must be defined before they can be used. 3560484Sobrien Allow them to be used in struct definitions, even though the enum must 3660484Sobrien be defined elsewhere. 3760484Sobrien If CGEN_ARCH isn't defined, this file is being included by something other 3860484Sobrien than <arch>-desc.h. */ 3960484Sobrien 4060484Sobrien/* Prepend the arch name, defined in <arch>-desc.h, and _cgen_ to symbol S. 4133965Sjdp The lack of spaces in the arg list is important for non-stdc systems. 4260484Sobrien This file is included by <arch>-desc.h. 4360484Sobrien It can be included independently of <arch>-desc.h, in which case the arch 4433965Sjdp dependent portions will be declared as "unknown_cgen_foo". */ 4533965Sjdp 4633965Sjdp#ifndef CGEN_SYM 4738889Sjdp#define CGEN_SYM(s) CONCAT3 (unknown,_cgen_,s) 4833965Sjdp#endif 4933965Sjdp 5033965Sjdp/* This file contains the static (unchanging) pieces and as much other stuff 5133965Sjdp as we can reasonably put here. It's generally cleaner to put stuff here 5233965Sjdp rather than having it machine generated if possible. */ 5333965Sjdp 5433965Sjdp/* The assembler syntax is made up of expressions (duh...). 5533965Sjdp At the lowest level the values are mnemonics, register names, numbers, etc. 5633965Sjdp Above that are subexpressions, if any (an example might be the 5760484Sobrien "effective address" in m68k cpus). Subexpressions are wip. 5860484Sobrien At the second highest level are the insns themselves. Above that are 5960484Sobrien pseudo-insns, synthetic insns, and macros, if any. */ 6033965Sjdp 6133965Sjdp/* Lots of cpu's have a fixed insn size, or one which rarely changes, 6233965Sjdp and it's generally easier to handle these by treating the insn as an 6333965Sjdp integer type, rather than an array of characters. So we allow targets 6460484Sobrien to control this. When an integer type the value is in host byte order, 6560484Sobrien when an array of characters the value is in target byte order. */ 6633965Sjdp 6760484Sobrientypedef unsigned int CGEN_INSN_INT; 6860484Sobrien#if CGEN_INT_INSN_P 6960484Sobrientypedef CGEN_INSN_INT CGEN_INSN_BYTES; 7060484Sobrientypedef CGEN_INSN_INT *CGEN_INSN_BYTES_PTR; 7133965Sjdp#else 7260484Sobrientypedef unsigned char *CGEN_INSN_BYTES; 7360484Sobrientypedef unsigned char *CGEN_INSN_BYTES_PTR; 7433965Sjdp#endif 7533965Sjdp 7633965Sjdp#ifdef __GNUC__ 7760484Sobrien#define CGEN_INLINE __inline__ 7833965Sjdp#else 7933965Sjdp#define CGEN_INLINE 8033965Sjdp#endif 8133965Sjdp 8238889Sjdpenum cgen_endian 8338889Sjdp{ 8433965Sjdp CGEN_ENDIAN_UNKNOWN, 8533965Sjdp CGEN_ENDIAN_LITTLE, 8633965Sjdp CGEN_ENDIAN_BIG 8733965Sjdp}; 8860484Sobrien 8960484Sobrien/* Forward decl. */ 9060484Sobrien 9160484Sobrientypedef struct cgen_insn CGEN_INSN; 9260484Sobrien 9360484Sobrien/* Opaque pointer version for use by external world. */ 9460484Sobrien 9560484Sobrientypedef struct cgen_cpu_desc *CGEN_CPU_DESC; 9633965Sjdp 9733965Sjdp/* Attributes. 9860484Sobrien Attributes are used to describe various random things associated with 9960484Sobrien an object (ifield, hardware, operand, insn, whatever) and are specified 10060484Sobrien as name/value pairs. 10160484Sobrien Integer attributes computed at compile time are currently all that's 10260484Sobrien supported, though adding string attributes and run-time computation is 10360484Sobrien straightforward. Integer attribute values are always host int's 10460484Sobrien (signed or unsigned). For portability, this means 32 bits. 10560484Sobrien Integer attributes are further categorized as boolean, bitset, integer, 10660484Sobrien and enum types. Boolean attributes appear frequently enough that they're 10760484Sobrien recorded in one host int. This limits the maximum number of boolean 10860484Sobrien attributes to 32, though that's a *lot* of attributes. */ 10933965Sjdp 11060484Sobrien/* Type of attribute values. */ 11160484Sobrien 112218822Sdimtypedef CGEN_BITSET CGEN_ATTR_VALUE_BITSET_TYPE; 113218822Sdimtypedef int CGEN_ATTR_VALUE_ENUM_TYPE; 114218822Sdimtypedef union 115218822Sdim{ 116218822Sdim CGEN_ATTR_VALUE_BITSET_TYPE bitset; 117218822Sdim CGEN_ATTR_VALUE_ENUM_TYPE nonbitset; 118218822Sdim} CGEN_ATTR_VALUE_TYPE; 11960484Sobrien 12033965Sjdp/* Struct to record attribute information. */ 12160484Sobrien 12238889Sjdptypedef struct 12338889Sjdp{ 12460484Sobrien /* Boolean attributes. */ 12533965Sjdp unsigned int bool; 12660484Sobrien /* Non-boolean integer attributes. */ 12760484Sobrien CGEN_ATTR_VALUE_TYPE nonbool[1]; 12833965Sjdp} CGEN_ATTR; 12933965Sjdp 13033965Sjdp/* Define a structure member for attributes with N non-boolean entries. 13160484Sobrien There is no maximum number of non-boolean attributes. 13260484Sobrien There is a maximum of 32 boolean attributes (since they are all recorded 13360484Sobrien in one host int). */ 13460484Sobrien 13533965Sjdp#define CGEN_ATTR_TYPE(n) \ 13660484Sobrienstruct { unsigned int bool; \ 13760484Sobrien CGEN_ATTR_VALUE_TYPE nonbool[(n) ? (n) : 1]; } 13833965Sjdp 13960484Sobrien/* Return the boolean attributes. */ 14060484Sobrien 14160484Sobrien#define CGEN_ATTR_BOOLS(a) ((a)->bool) 14260484Sobrien 14360484Sobrien/* Non-boolean attribute numbers are offset by this much. */ 14460484Sobrien 14560484Sobrien#define CGEN_ATTR_NBOOL_OFFSET 32 14660484Sobrien 14760484Sobrien/* Given a boolean attribute number, return its mask. */ 14860484Sobrien 14933965Sjdp#define CGEN_ATTR_MASK(attr) (1 << (attr)) 15033965Sjdp 15138889Sjdp/* Return the value of boolean attribute ATTR in ATTRS. */ 15238889Sjdp 15360484Sobrien#define CGEN_BOOL_ATTR(attrs, attr) ((CGEN_ATTR_MASK (attr) & (attrs)) != 0) 15460484Sobrien 15533965Sjdp/* Return value of attribute ATTR in ATTR_TABLE for OBJ. 15660484Sobrien OBJ is a pointer to the entity that has the attributes 15760484Sobrien (??? not used at present but is reserved for future purposes - eventually 15860484Sobrien the goal is to allow recording attributes in source form and computing 15960484Sobrien them lazily at runtime, not sure of the details yet). */ 16060484Sobrien 16133965Sjdp#define CGEN_ATTR_VALUE(obj, attr_table, attr) \ 16260484Sobrien((unsigned int) (attr) < CGEN_ATTR_NBOOL_OFFSET \ 16360484Sobrien ? ((CGEN_ATTR_BOOLS (attr_table) & CGEN_ATTR_MASK (attr)) != 0) \ 164218822Sdim : ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].nonbitset)) 165218822Sdim#define CGEN_BITSET_ATTR_VALUE(obj, attr_table, attr) \ 166218822Sdim ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].bitset) 16738889Sjdp 16838889Sjdp/* Attribute name/value tables. 16960484Sobrien These are used to assist parsing of descriptions at run-time. */ 17038889Sjdp 17138889Sjdptypedef struct 17238889Sjdp{ 17338889Sjdp const char * name; 174218822Sdim unsigned value; 17538889Sjdp} CGEN_ATTR_ENTRY; 17638889Sjdp 17760484Sobrien/* For each domain (ifld,hw,operand,insn), list of attributes. */ 17838889Sjdp 17938889Sjdptypedef struct 18038889Sjdp{ 18160484Sobrien const char * name; 18260484Sobrien const CGEN_ATTR_ENTRY * dfault; 18338889Sjdp const CGEN_ATTR_ENTRY * vals; 18438889Sjdp} CGEN_ATTR_TABLE; 18533965Sjdp 18660484Sobrien/* Instruction set variants. */ 18760484Sobrien 18860484Sobrientypedef struct { 18960484Sobrien const char *name; 19060484Sobrien 19160484Sobrien /* Default instruction size (in bits). 19260484Sobrien This is used by the assembler when it encounters an unknown insn. */ 19360484Sobrien unsigned int default_insn_bitsize; 19460484Sobrien 19560484Sobrien /* Base instruction size (in bits). 19660484Sobrien For non-LIW cpus this is generally the length of the smallest insn. 19760484Sobrien For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 19860484Sobrien unsigned int base_insn_bitsize; 19960484Sobrien 20060484Sobrien /* Minimum/maximum instruction size (in bits). */ 20160484Sobrien unsigned int min_insn_bitsize; 20260484Sobrien unsigned int max_insn_bitsize; 20360484Sobrien} CGEN_ISA; 20460484Sobrien 20560484Sobrien/* Machine variants. */ 20660484Sobrien 20760484Sobrientypedef struct { 20860484Sobrien const char *name; 20960484Sobrien /* The argument to bfd_arch_info->scan. */ 21060484Sobrien const char *bfd_name; 21160484Sobrien /* one of enum mach_attr */ 21260484Sobrien int num; 21389857Sobrien /* parameter from mach->cpu */ 21489857Sobrien unsigned int insn_chunk_bitsize; 21560484Sobrien} CGEN_MACH; 21660484Sobrien 21733965Sjdp/* Parse result (also extraction result). 21833965Sjdp 21933965Sjdp The result of parsing an insn is stored here. 22033965Sjdp To generate the actual insn, this is passed to the insert handler. 22133965Sjdp When printing an insn, the result of extraction is stored here. 22233965Sjdp To print the insn, this is passed to the print handler. 22333965Sjdp 22433965Sjdp It is machine generated so we don't define it here, 22533965Sjdp but we do need a forward decl for the handler fns. 22633965Sjdp 22733965Sjdp There is one member for each possible field in the insn. 22833965Sjdp The type depends on the field. 22933965Sjdp Also recorded here is the computed length of the insn for architectures 23033965Sjdp where it varies. 23133965Sjdp*/ 23233965Sjdp 23338889Sjdptypedef struct cgen_fields CGEN_FIELDS; 23433965Sjdp 23533965Sjdp/* Total length of the insn, as recorded in the `fields' struct. */ 23633965Sjdp/* ??? The field insert handler has lots of opportunities for optimization 23733965Sjdp if it ever gets inlined. On architectures where insns all have the same 23833965Sjdp size, may wish to detect that and make this macro a constant - to allow 23933965Sjdp further optimizations. */ 24060484Sobrien 24133965Sjdp#define CGEN_FIELDS_BITSIZE(fields) ((fields)->length) 24233965Sjdp 24360484Sobrien/* Extraction support for variable length insn sets. */ 24460484Sobrien 24560484Sobrien/* When disassembling we don't know the number of bytes to read at the start. 24660484Sobrien So the first CGEN_BASE_INSN_SIZE bytes are read at the start and the rest 24760484Sobrien are read when needed. This struct controls this. It is basically the 24860484Sobrien disassemble_info stuff, except that we provide a cache for values already 24960484Sobrien read (since bytes can typically be read several times to fetch multiple 25060484Sobrien operands that may be in them), and that extraction of fields is needed 25160484Sobrien in contexts other than disassembly. */ 25260484Sobrien 25360484Sobrientypedef struct { 25460484Sobrien /* A pointer to the disassemble_info struct. 255130561Sobrien We don't require dis-asm.h so we use void * for the type here. 25660484Sobrien If NULL, BYTES is full of valid data (VALID == -1). */ 257130561Sobrien void *dis_info; 25860484Sobrien /* Points to a working buffer of sufficient size. */ 25960484Sobrien unsigned char *insn_bytes; 26060484Sobrien /* Mask of bytes that are valid in INSN_BYTES. */ 26160484Sobrien unsigned int valid; 26260484Sobrien} CGEN_EXTRACT_INFO; 26360484Sobrien 26433965Sjdp/* Associated with each insn or expression is a set of "handlers" for 26560484Sobrien performing operations like parsing, printing, etc. These require a bfd_vma 26660484Sobrien value to be passed around but we don't want all applications to need bfd.h. 26760484Sobrien So this stuff is only provided if bfd.h has been included. */ 26833965Sjdp 26933965Sjdp/* Parse handler. 27060484Sobrien CD is a cpu table descriptor. 27160484Sobrien INSN is a pointer to a struct describing the insn being parsed. 27260484Sobrien STRP is a pointer to a pointer to the text being parsed. 27360484Sobrien FIELDS is a pointer to a cgen_fields struct in which the results are placed. 27460484Sobrien If the expression is successfully parsed, *STRP is updated. 27560484Sobrien If not it is left alone. 27633965Sjdp The result is NULL if success or an error message. */ 27760484Sobrientypedef const char * (cgen_parse_fn) 278130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN *insn_, 279130561Sobrien const char **strp_, CGEN_FIELDS *fields_); 28033965Sjdp 28160484Sobrien/* Insert handler. 28260484Sobrien CD is a cpu table descriptor. 28360484Sobrien INSN is a pointer to a struct describing the insn being parsed. 28460484Sobrien FIELDS is a pointer to a cgen_fields struct from which the values 28560484Sobrien are fetched. 28660484Sobrien INSNP is a pointer to a buffer in which to place the insn. 28760484Sobrien PC is the pc value of the insn. 28860484Sobrien The result is an error message or NULL if success. */ 28960484Sobrien 290130561Sobrien#ifdef __BFD_H_SEEN__ 29160484Sobrientypedef const char * (cgen_insert_fn) 292130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN *insn_, 293130561Sobrien CGEN_FIELDS *fields_, CGEN_INSN_BYTES_PTR insnp_, 294130561Sobrien bfd_vma pc_); 29533965Sjdp#else 29660484Sobrientypedef const char * (cgen_insert_fn) (); 29733965Sjdp#endif 29833965Sjdp 29933965Sjdp/* Extract handler. 30060484Sobrien CD is a cpu table descriptor. 30160484Sobrien INSN is a pointer to a struct describing the insn being parsed. 30233965Sjdp The second argument is a pointer to a struct controlling extraction 30333965Sjdp (only used for variable length insns). 30460484Sobrien EX_INFO is a pointer to a struct for controlling reading of further 30560484Sobrien bytes for the insn. 30660484Sobrien BASE_INSN is the first CGEN_BASE_INSN_SIZE bytes (host order). 30760484Sobrien FIELDS is a pointer to a cgen_fields struct in which the results are placed. 30860484Sobrien PC is the pc value of the insn. 30960484Sobrien The result is the length of the insn in bits or zero if not recognized. */ 31033965Sjdp 311130561Sobrien#ifdef __BFD_H_SEEN__ 31260484Sobrientypedef int (cgen_extract_fn) 313130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN *insn_, 314130561Sobrien CGEN_EXTRACT_INFO *ex_info_, CGEN_INSN_INT base_insn_, 315130561Sobrien CGEN_FIELDS *fields_, bfd_vma pc_); 31660484Sobrien#else 31760484Sobrientypedef int (cgen_extract_fn) (); 31860484Sobrien#endif 31933965Sjdp 32060484Sobrien/* Print handler. 32160484Sobrien CD is a cpu table descriptor. 32260484Sobrien INFO is a pointer to the disassembly info. 32360484Sobrien Eg: disassemble_info. It's defined as `PTR' so this file can be included 32460484Sobrien without dis-asm.h. 32560484Sobrien INSN is a pointer to a struct describing the insn being printed. 32660484Sobrien FIELDS is a pointer to a cgen_fields struct. 32760484Sobrien PC is the pc value of the insn. 32860484Sobrien LEN is the length of the insn, in bits. */ 32933965Sjdp 330130561Sobrien#ifdef __BFD_H_SEEN__ 33160484Sobrientypedef void (cgen_print_fn) 332130561Sobrien (CGEN_CPU_DESC, void * info_, const CGEN_INSN *insn_, 333130561Sobrien CGEN_FIELDS *fields_, bfd_vma pc_, int len_); 33460484Sobrien#else 33560484Sobrientypedef void (cgen_print_fn) (); 33660484Sobrien#endif 33733965Sjdp 33860484Sobrien/* Parse/insert/extract/print handlers. 33960484Sobrien 34060484Sobrien Indices into the handler tables. 34160484Sobrien We could use pointers here instead, but 90% of them are generally identical 34260484Sobrien and that's a lot of redundant data. Making these unsigned char indices 34360484Sobrien into tables of pointers saves a bit of space. 34460484Sobrien Using indices also keeps assembler code out of the disassembler and 34560484Sobrien vice versa. */ 34660484Sobrien 34760484Sobrienstruct cgen_opcode_handler 34838889Sjdp{ 34933965Sjdp unsigned char parse, insert, extract, print; 35033965Sjdp}; 35133965Sjdp 35238889Sjdp/* Assembler interface. 35333965Sjdp 35438889Sjdp The interface to the assembler is intended to be clean in the sense that 35538889Sjdp libopcodes.a is a standalone entity and could be used with any assembler. 35638889Sjdp Not that one would necessarily want to do that but rather that it helps 35738889Sjdp keep a clean interface. The interface will obviously be slanted towards 35838889Sjdp GAS, but at least it's a start. 35960484Sobrien ??? Note that one possible user of the assembler besides GAS is GDB. 36033965Sjdp 36138889Sjdp Parsing is controlled by the assembler which calls 36238889Sjdp CGEN_SYM (assemble_insn). If it can parse and build the entire insn 36338889Sjdp it doesn't call back to the assembler. If it needs/wants to call back 36460484Sobrien to the assembler, cgen_parse_operand_fn is called which can either 36533965Sjdp 36638889Sjdp - return a number to be inserted in the insn 36738889Sjdp - return a "register" value to be inserted 36838889Sjdp (the register might not be a register per pe) 36938889Sjdp - queue the argument and return a marker saying the expression has been 37038889Sjdp queued (eg: a fix-up) 37138889Sjdp - return an error message indicating the expression wasn't recognizable 37233965Sjdp 37338889Sjdp The result is an error message or NULL for success. 37438889Sjdp The parsed value is stored in the bfd_vma *. */ 37533965Sjdp 37638889Sjdp/* Values for indicating what the caller wants. */ 37760484Sobrien 37838889Sjdpenum cgen_parse_operand_type 37938889Sjdp{ 38038889Sjdp CGEN_PARSE_OPERAND_INIT, 38138889Sjdp CGEN_PARSE_OPERAND_INTEGER, 382218822Sdim CGEN_PARSE_OPERAND_ADDRESS, 383218822Sdim CGEN_PARSE_OPERAND_SYMBOLIC 38438889Sjdp}; 38533965Sjdp 38660484Sobrien/* Values for indicating what was parsed. */ 38760484Sobrien 38838889Sjdpenum cgen_parse_operand_result 38938889Sjdp{ 39038889Sjdp CGEN_PARSE_OPERAND_RESULT_NUMBER, 39138889Sjdp CGEN_PARSE_OPERAND_RESULT_REGISTER, 39238889Sjdp CGEN_PARSE_OPERAND_RESULT_QUEUED, 39338889Sjdp CGEN_PARSE_OPERAND_RESULT_ERROR 39438889Sjdp}; 39538889Sjdp 396130561Sobrien#ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 39760484Sobrientypedef const char * (cgen_parse_operand_fn) 398130561Sobrien (CGEN_CPU_DESC, 399130561Sobrien enum cgen_parse_operand_type, const char **, int, int, 400130561Sobrien enum cgen_parse_operand_result *, bfd_vma *); 40160484Sobrien#else 40260484Sobrientypedef const char * (cgen_parse_operand_fn) (); 40333965Sjdp#endif 40433965Sjdp 40560484Sobrien/* Set the cgen_parse_operand_fn callback. */ 40633965Sjdp 40760484Sobrienextern void cgen_set_parse_operand_fn 408130561Sobrien (CGEN_CPU_DESC, cgen_parse_operand_fn); 40938889Sjdp 41060484Sobrien/* Called before trying to match a table entry with the insn. */ 41138889Sjdp 412130561Sobrienextern void cgen_init_parse_operand (CGEN_CPU_DESC); 41333965Sjdp 41433965Sjdp/* Operand values (keywords, integers, symbols, etc.) */ 41533965Sjdp 41633965Sjdp/* Types of assembler elements. */ 41733965Sjdp 41838889Sjdpenum cgen_asm_type 41938889Sjdp{ 42060484Sobrien CGEN_ASM_NONE, CGEN_ASM_KEYWORD, CGEN_ASM_MAX 42133965Sjdp}; 42233965Sjdp 42360484Sobrien#ifndef CGEN_ARCH 42460484Sobrienenum cgen_hw_type { CGEN_HW_MAX }; 42560484Sobrien#endif 42660484Sobrien 42733965Sjdp/* List of hardware elements. */ 42833965Sjdp 42960484Sobrientypedef struct 43038889Sjdp{ 43160484Sobrien char *name; 43260484Sobrien enum cgen_hw_type type; 43360484Sobrien /* There is currently no example where both index specs and value specs 43460484Sobrien are required, so for now both are clumped under "asm_data". */ 43560484Sobrien enum cgen_asm_type asm_type; 436130561Sobrien void *asm_data; 43760484Sobrien#ifndef CGEN_HW_NBOOL_ATTRS 43860484Sobrien#define CGEN_HW_NBOOL_ATTRS 1 43960484Sobrien#endif 44060484Sobrien CGEN_ATTR_TYPE (CGEN_HW_NBOOL_ATTRS) attrs; 44160484Sobrien#define CGEN_HW_ATTRS(hw) (&(hw)->attrs) 44233965Sjdp} CGEN_HW_ENTRY; 44333965Sjdp 44460484Sobrien/* Return value of attribute ATTR in HW. */ 44533965Sjdp 44660484Sobrien#define CGEN_HW_ATTR_VALUE(hw, attr) \ 44760484SobrienCGEN_ATTR_VALUE ((hw), CGEN_HW_ATTRS (hw), (attr)) 44860484Sobrien 44960484Sobrien/* Table of hardware elements for selected mach, computed at runtime. 45060484Sobrien enum cgen_hw_type is an index into this table (specifically `entries'). */ 45160484Sobrien 45260484Sobrientypedef struct { 45360484Sobrien /* Pointer to null terminated table of all compiled in entries. */ 45460484Sobrien const CGEN_HW_ENTRY *init_entries; 45560484Sobrien unsigned int entry_size; /* since the attribute member is variable sized */ 45660484Sobrien /* Array of all entries, initial and run-time added. */ 45760484Sobrien const CGEN_HW_ENTRY **entries; 45860484Sobrien /* Number of elements in `entries'. */ 45960484Sobrien unsigned int num_entries; 46060484Sobrien /* For now, xrealloc is called each time a new entry is added at runtime. 46160484Sobrien ??? May wish to keep track of some slop to reduce the number of calls to 46260484Sobrien xrealloc, except that there's unlikely to be many and not expected to be 46360484Sobrien in speed critical code. */ 46460484Sobrien} CGEN_HW_TABLE; 46560484Sobrien 46660484Sobrienextern const CGEN_HW_ENTRY * cgen_hw_lookup_by_name 467130561Sobrien (CGEN_CPU_DESC, const char *); 46860484Sobrienextern const CGEN_HW_ENTRY * cgen_hw_lookup_by_num 469130561Sobrien (CGEN_CPU_DESC, unsigned int); 47060484Sobrien 47133965Sjdp/* This struct is used to describe things like register names, etc. */ 47233965Sjdp 47338889Sjdptypedef struct cgen_keyword_entry 47438889Sjdp{ 47533965Sjdp /* Name (as in register name). */ 47638889Sjdp char * name; 47733965Sjdp 47833965Sjdp /* Value (as in register number). 47933965Sjdp The value cannot be -1 as that is used to indicate "not found". 48033965Sjdp IDEA: Have "FUNCTION" attribute? [function is called to fetch value]. */ 48133965Sjdp int value; 48233965Sjdp 48338889Sjdp /* Attributes. 48438889Sjdp This should, but technically needn't, appear last. It is a variable sized 48538889Sjdp array in that one architecture may have 1 nonbool attribute and another 48638889Sjdp may have more. Having this last means the non-architecture specific code 48760484Sobrien needn't care. The goal is to eventually record 48860484Sobrien attributes in their raw form, evaluate them at run-time, and cache the 48960484Sobrien values, so this worry will go away anyway. */ 49038889Sjdp /* ??? Moving this last should be done by treating keywords like insn lists 49138889Sjdp and moving the `next' fields into a CGEN_KEYWORD_LIST struct. */ 49233965Sjdp /* FIXME: Not used yet. */ 49338889Sjdp#ifndef CGEN_KEYWORD_NBOOL_ATTRS 49438889Sjdp#define CGEN_KEYWORD_NBOOL_ATTRS 1 49538889Sjdp#endif 49638889Sjdp CGEN_ATTR_TYPE (CGEN_KEYWORD_NBOOL_ATTRS) attrs; 49733965Sjdp 49860484Sobrien /* ??? Putting these here means compiled in entries can't be const. 49960484Sobrien Not a really big deal, but something to consider. */ 50033965Sjdp /* Next name hash table entry. */ 50133965Sjdp struct cgen_keyword_entry *next_name; 50233965Sjdp /* Next value hash table entry. */ 50333965Sjdp struct cgen_keyword_entry *next_value; 50433965Sjdp} CGEN_KEYWORD_ENTRY; 50533965Sjdp 50633965Sjdp/* Top level struct for describing a set of related keywords 50733965Sjdp (e.g. register names). 50833965Sjdp 50960484Sobrien This struct supports run-time entry of new values, and hashed lookups. */ 51033965Sjdp 51138889Sjdptypedef struct cgen_keyword 51238889Sjdp{ 51333965Sjdp /* Pointer to initial [compiled in] values. */ 51460484Sobrien CGEN_KEYWORD_ENTRY *init_entries; 51538889Sjdp 51633965Sjdp /* Number of entries in `init_entries'. */ 51733965Sjdp unsigned int num_init_entries; 51838889Sjdp 51933965Sjdp /* Hash table used for name lookup. */ 52060484Sobrien CGEN_KEYWORD_ENTRY **name_hash_table; 52138889Sjdp 52233965Sjdp /* Hash table used for value lookup. */ 52360484Sobrien CGEN_KEYWORD_ENTRY **value_hash_table; 52438889Sjdp 52533965Sjdp /* Number of entries in the hash_tables. */ 52633965Sjdp unsigned int hash_table_size; 52738889Sjdp 52838889Sjdp /* Pointer to null keyword "" entry if present. */ 52960484Sobrien const CGEN_KEYWORD_ENTRY *null_entry; 53089857Sobrien 53189857Sobrien /* String containing non-alphanumeric characters used 53289857Sobrien in keywords. 53389857Sobrien At present, the highest number of entries used is 1. */ 53489857Sobrien char nonalpha_chars[8]; 53533965Sjdp} CGEN_KEYWORD; 53633965Sjdp 53733965Sjdp/* Structure used for searching. */ 53833965Sjdp 53938889Sjdptypedef struct 54038889Sjdp{ 54133965Sjdp /* Table being searched. */ 54260484Sobrien const CGEN_KEYWORD *table; 54338889Sjdp 54433965Sjdp /* Specification of what is being searched for. */ 54560484Sobrien const char *spec; 54638889Sjdp 54733965Sjdp /* Current index in hash table. */ 54833965Sjdp unsigned int current_hash; 54938889Sjdp 55033965Sjdp /* Current element in current hash chain. */ 55160484Sobrien CGEN_KEYWORD_ENTRY *current_entry; 55233965Sjdp} CGEN_KEYWORD_SEARCH; 55333965Sjdp 55433965Sjdp/* Lookup a keyword from its name. */ 55560484Sobrien 55660484Sobrienconst CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_name 557130561Sobrien (CGEN_KEYWORD *, const char *); 55860484Sobrien 55933965Sjdp/* Lookup a keyword from its value. */ 56060484Sobrien 56160484Sobrienconst CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_value 562130561Sobrien (CGEN_KEYWORD *, int); 56360484Sobrien 56433965Sjdp/* Add a keyword. */ 56560484Sobrien 566130561Sobrienvoid cgen_keyword_add (CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *); 56760484Sobrien 56833965Sjdp/* Keyword searching. 56933965Sjdp This can be used to retrieve every keyword, or a subset. */ 57060484Sobrien 57138889SjdpCGEN_KEYWORD_SEARCH cgen_keyword_search_init 572130561Sobrien (CGEN_KEYWORD *, const char *); 57338889Sjdpconst CGEN_KEYWORD_ENTRY *cgen_keyword_search_next 574130561Sobrien (CGEN_KEYWORD_SEARCH *); 57533965Sjdp 57633965Sjdp/* Operand value support routines. */ 57733965Sjdp 57860484Sobrienextern const char *cgen_parse_keyword 579130561Sobrien (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); 580130561Sobrien#ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 58160484Sobrienextern const char *cgen_parse_signed_integer 582130561Sobrien (CGEN_CPU_DESC, const char **, int, long *); 58360484Sobrienextern const char *cgen_parse_unsigned_integer 584130561Sobrien (CGEN_CPU_DESC, const char **, int, unsigned long *); 58560484Sobrienextern const char *cgen_parse_address 586130561Sobrien (CGEN_CPU_DESC, const char **, int, int, 587130561Sobrien enum cgen_parse_operand_result *, bfd_vma *); 58860484Sobrienextern const char *cgen_validate_signed_integer 589130561Sobrien (long, long, long); 59060484Sobrienextern const char *cgen_validate_unsigned_integer 591130561Sobrien (unsigned long, unsigned long, unsigned long); 59260484Sobrien#endif 59333965Sjdp 59438889Sjdp/* Operand modes. */ 59538889Sjdp 59638889Sjdp/* ??? This duplicates the values in arch.h. Revisit. 59738889Sjdp These however need the CGEN_ prefix [as does everything in this file]. */ 59838889Sjdp/* ??? Targets may need to add their own modes so we may wish to move this 59938889Sjdp to <arch>-opc.h, or add a hook. */ 60038889Sjdp 60138889Sjdpenum cgen_mode { 60260484Sobrien CGEN_MODE_VOID, /* ??? rename simulator's VM to VOID? */ 60338889Sjdp CGEN_MODE_BI, CGEN_MODE_QI, CGEN_MODE_HI, CGEN_MODE_SI, CGEN_MODE_DI, 60438889Sjdp CGEN_MODE_UBI, CGEN_MODE_UQI, CGEN_MODE_UHI, CGEN_MODE_USI, CGEN_MODE_UDI, 60538889Sjdp CGEN_MODE_SF, CGEN_MODE_DF, CGEN_MODE_XF, CGEN_MODE_TF, 60660484Sobrien CGEN_MODE_TARGET_MAX, 60760484Sobrien CGEN_MODE_INT, CGEN_MODE_UINT, 60838889Sjdp CGEN_MODE_MAX 60938889Sjdp}; 61038889Sjdp 61138889Sjdp/* FIXME: Until simulator is updated. */ 61260484Sobrien 61338889Sjdp#define CGEN_MODE_VM CGEN_MODE_VOID 61438889Sjdp 61560484Sobrien/* Operands. */ 61660484Sobrien 61760484Sobrien#ifndef CGEN_ARCH 61860484Sobrienenum cgen_operand_type { CGEN_OPERAND_MAX }; 61960484Sobrien#endif 62060484Sobrien 62160484Sobrien/* "nil" indicator for the operand instance table */ 62260484Sobrien#define CGEN_OPERAND_NIL CGEN_OPERAND_MAX 62360484Sobrien 62489857Sobrien/* A tree of these structs represents the multi-ifield 62589857Sobrien structure of an operand's hw-index value, if it exists. */ 62689857Sobrien 62789857Sobrienstruct cgen_ifld; 62889857Sobrien 62989857Sobrientypedef struct cgen_maybe_multi_ifield 63089857Sobrien{ 63189857Sobrien int count; /* 0: indexed by single cgen_ifld (possibly null: dead entry); 63289857Sobrien n: indexed by array of more cgen_maybe_multi_ifields. */ 63389857Sobrien union 63489857Sobrien { 635130561Sobrien const void *p; 636130561Sobrien const struct cgen_maybe_multi_ifield * multi; 637130561Sobrien const struct cgen_ifld * leaf; 63889857Sobrien } val; 63989857Sobrien} 64089857SobrienCGEN_MAYBE_MULTI_IFLD; 64189857Sobrien 64233965Sjdp/* This struct defines each entry in the operand table. */ 64333965Sjdp 64460484Sobrientypedef struct 64538889Sjdp{ 64638889Sjdp /* Name as it appears in the syntax string. */ 64760484Sobrien char *name; 64833965Sjdp 64960484Sobrien /* Operand type. */ 65060484Sobrien enum cgen_operand_type type; 65160484Sobrien 65238889Sjdp /* The hardware element associated with this operand. */ 65360484Sobrien enum cgen_hw_type hw_type; 65433965Sjdp 65538889Sjdp /* FIXME: We don't yet record ifield definitions, which we should. 65638889Sjdp When we do it might make sense to delete start/length (since they will 65738889Sjdp be duplicated in the ifield's definition) and replace them with a 65860484Sobrien pointer to the ifield entry. */ 65938889Sjdp 66060484Sobrien /* Bit position. 66138889Sjdp This is just a hint, and may be unused in more complex operands. 66233965Sjdp May be unused for a modifier. */ 66333965Sjdp unsigned char start; 66433965Sjdp 66533965Sjdp /* The number of bits in the operand. 66638889Sjdp This is just a hint, and may be unused in more complex operands. 66733965Sjdp May be unused for a modifier. */ 66833965Sjdp unsigned char length; 66933965Sjdp 67089857Sobrien /* The (possibly-multi) ifield used as an index for this operand, if it 67189857Sobrien is indexed by a field at all. This substitutes / extends the start and 67289857Sobrien length fields above, but unsure at this time whether they are used 67389857Sobrien anywhere. */ 67489857Sobrien CGEN_MAYBE_MULTI_IFLD index_fields; 67538889Sjdp#if 0 /* ??? Interesting idea but relocs tend to get too complicated, 67638889Sjdp and ABI dependent, for simple table lookups to work. */ 67733965Sjdp /* Ideally this would be the internal (external?) reloc type. */ 67833965Sjdp int reloc_type; 67933965Sjdp#endif 68038889Sjdp 68138889Sjdp /* Attributes. 68238889Sjdp This should, but technically needn't, appear last. It is a variable sized 68338889Sjdp array in that one architecture may have 1 nonbool attribute and another 68438889Sjdp may have more. Having this last means the non-architecture specific code 68560484Sobrien needn't care, now or tomorrow. The goal is to eventually record 68660484Sobrien attributes in their raw form, evaluate them at run-time, and cache the 68760484Sobrien values, so this worry will go away anyway. */ 68838889Sjdp#ifndef CGEN_OPERAND_NBOOL_ATTRS 68938889Sjdp#define CGEN_OPERAND_NBOOL_ATTRS 1 69038889Sjdp#endif 69138889Sjdp CGEN_ATTR_TYPE (CGEN_OPERAND_NBOOL_ATTRS) attrs; 69238889Sjdp#define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs) 69333965Sjdp} CGEN_OPERAND; 69433965Sjdp 69533965Sjdp/* Return value of attribute ATTR in OPERAND. */ 69633965Sjdp 69760484Sobrien#define CGEN_OPERAND_ATTR_VALUE(operand, attr) \ 69860484SobrienCGEN_ATTR_VALUE ((operand), CGEN_OPERAND_ATTRS (operand), (attr)) 69933965Sjdp 70060484Sobrien/* Table of operands for selected mach/isa, computed at runtime. 70160484Sobrien enum cgen_operand_type is an index into this table (specifically 70260484Sobrien `entries'). */ 70333965Sjdp 70460484Sobrientypedef struct { 70560484Sobrien /* Pointer to null terminated table of all compiled in entries. */ 70660484Sobrien const CGEN_OPERAND *init_entries; 70760484Sobrien unsigned int entry_size; /* since the attribute member is variable sized */ 70860484Sobrien /* Array of all entries, initial and run-time added. */ 70960484Sobrien const CGEN_OPERAND **entries; 71060484Sobrien /* Number of elements in `entries'. */ 71160484Sobrien unsigned int num_entries; 71260484Sobrien /* For now, xrealloc is called each time a new entry is added at runtime. 71360484Sobrien ??? May wish to keep track of some slop to reduce the number of calls to 71460484Sobrien xrealloc, except that there's unlikely to be many and not expected to be 71560484Sobrien in speed critical code. */ 71660484Sobrien} CGEN_OPERAND_TABLE; 71738889Sjdp 71860484Sobrienextern const CGEN_OPERAND * cgen_operand_lookup_by_name 719130561Sobrien (CGEN_CPU_DESC, const char *); 72060484Sobrienextern const CGEN_OPERAND * cgen_operand_lookup_by_num 721130561Sobrien (CGEN_CPU_DESC, int); 72233965Sjdp 72338889Sjdp/* Instruction operand instances. 72438889Sjdp 72538889Sjdp For each instruction, a list of the hardware elements that are read and 72638889Sjdp written are recorded. */ 72738889Sjdp 72838889Sjdp/* The type of the instance. */ 72960484Sobrien 73060484Sobrienenum cgen_opinst_type { 73138889Sjdp /* End of table marker. */ 73260484Sobrien CGEN_OPINST_END = 0, 73360484Sobrien CGEN_OPINST_INPUT, CGEN_OPINST_OUTPUT 73438889Sjdp}; 73538889Sjdp 73638889Sjdptypedef struct 73738889Sjdp{ 73860484Sobrien /* Input or output indicator. */ 73960484Sobrien enum cgen_opinst_type type; 74038889Sjdp 74160484Sobrien /* Name of operand. */ 74260484Sobrien const char *name; 74360484Sobrien 74438889Sjdp /* The hardware element referenced. */ 74560484Sobrien enum cgen_hw_type hw_type; 74638889Sjdp 74738889Sjdp /* The mode in which the operand is being used. */ 74838889Sjdp enum cgen_mode mode; 74938889Sjdp 75060484Sobrien /* The operand table entry CGEN_OPERAND_NIL if there is none 75160484Sobrien (i.e. an explicit hardware reference). */ 75260484Sobrien enum cgen_operand_type op_type; 75338889Sjdp 75460484Sobrien /* If `operand' is "nil", the index (e.g. into array of registers). */ 75538889Sjdp int index; 75660484Sobrien 75760484Sobrien /* Attributes. 75860484Sobrien ??? This perhaps should be a real attribute struct but there's 75960484Sobrien no current need, so we save a bit of space and just have a set of 76060484Sobrien flags. The interface is such that this can easily be made attributes 76160484Sobrien should it prove useful. */ 76260484Sobrien unsigned int attrs; 76360484Sobrien#define CGEN_OPINST_ATTRS(opinst) ((opinst)->attrs) 76460484Sobrien/* Return value of attribute ATTR in OPINST. */ 76560484Sobrien#define CGEN_OPINST_ATTR(opinst, attr) \ 76660484Sobrien((CGEN_OPINST_ATTRS (opinst) & (attr)) != 0) 76760484Sobrien/* Operand is conditionally referenced (read/written). */ 76860484Sobrien#define CGEN_OPINST_COND_REF 1 76960484Sobrien} CGEN_OPINST; 77038889Sjdp 77138889Sjdp/* Syntax string. 77238889Sjdp 77338889Sjdp Each insn format and subexpression has one of these. 77438889Sjdp 77538889Sjdp The syntax "string" consists of characters (n > 0 && n < 128), and operand 77638889Sjdp values (n >= 128), and is terminated by 0. Operand values are 128 + index 77738889Sjdp into the operand table. The operand table doesn't exist in C, per se, as 77838889Sjdp the data is recorded in the parse/insert/extract/print switch statements. */ 77938889Sjdp 78085815Sobrien/* This should be at least as large as necessary for any target. */ 78189857Sobrien#define CGEN_MAX_SYNTAX_ELEMENTS 48 78285815Sobrien 78385815Sobrien/* A target may know its own precise maximum. Assert that it falls below 78485815Sobrien the above limit. */ 78589857Sobrien#ifdef CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 78689857Sobrien#if CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS > CGEN_MAX_SYNTAX_ELEMENTS 78789857Sobrien#error "CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS too high - enlarge CGEN_MAX_SYNTAX_ELEMENTS" 78838889Sjdp#endif 78985815Sobrien#endif 79038889Sjdp 79185815Sobrientypedef unsigned short CGEN_SYNTAX_CHAR_TYPE; 79285815Sobrien 79338889Sjdptypedef struct 79438889Sjdp{ 79589857Sobrien CGEN_SYNTAX_CHAR_TYPE syntax[CGEN_MAX_SYNTAX_ELEMENTS]; 79638889Sjdp} CGEN_SYNTAX; 79738889Sjdp 79838889Sjdp#define CGEN_SYNTAX_STRING(syn) (syn->syntax) 79938889Sjdp#define CGEN_SYNTAX_CHAR_P(c) ((c) < 128) 80085815Sobrien#define CGEN_SYNTAX_CHAR(c) ((unsigned char)c) 80138889Sjdp#define CGEN_SYNTAX_FIELD(c) ((c) - 128) 80238889Sjdp#define CGEN_SYNTAX_MAKE_FIELD(c) ((c) + 128) 80338889Sjdp 80438889Sjdp/* ??? I can't currently think of any case where the mnemonic doesn't come 80538889Sjdp first [and if one ever doesn't building the hash tables will be tricky]. 80638889Sjdp However, we treat mnemonics as just another operand of the instruction. 80738889Sjdp A value of 1 means "this is where the mnemonic appears". 1 isn't 80838889Sjdp special other than it's a non-printable ASCII char. */ 80960484Sobrien 81038889Sjdp#define CGEN_SYNTAX_MNEMONIC 1 81138889Sjdp#define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == CGEN_SYNTAX_MNEMONIC) 81238889Sjdp 81360484Sobrien/* Instruction fields. 81460484Sobrien 81560484Sobrien ??? We currently don't allow adding fields at run-time. 81660484Sobrien Easy to fix when needed. */ 81760484Sobrien 81860484Sobrientypedef struct cgen_ifld { 81960484Sobrien /* Enum of ifield. */ 82060484Sobrien int num; 82160484Sobrien#define CGEN_IFLD_NUM(f) ((f)->num) 82260484Sobrien 82360484Sobrien /* Name of the field, distinguishes it from all other fields. */ 82460484Sobrien const char *name; 82560484Sobrien#define CGEN_IFLD_NAME(f) ((f)->name) 82660484Sobrien 82760484Sobrien /* Default offset, in bits, from the start of the insn to the word 82860484Sobrien containing the field. */ 82960484Sobrien int word_offset; 83060484Sobrien#define CGEN_IFLD_WORD_OFFSET(f) ((f)->word_offset) 83160484Sobrien 83260484Sobrien /* Default length of the word containing the field. */ 83360484Sobrien int word_size; 83460484Sobrien#define CGEN_IFLD_WORD_SIZE(f) ((f)->word_size) 83560484Sobrien 83660484Sobrien /* Default starting bit number. 83760484Sobrien Whether lsb=0 or msb=0 is determined by CGEN_INSN_LSB0_P. */ 83860484Sobrien int start; 83960484Sobrien#define CGEN_IFLD_START(f) ((f)->start) 84060484Sobrien 84160484Sobrien /* Length of the field, in bits. */ 84260484Sobrien int length; 84360484Sobrien#define CGEN_IFLD_LENGTH(f) ((f)->length) 84460484Sobrien 84560484Sobrien#ifndef CGEN_IFLD_NBOOL_ATTRS 84660484Sobrien#define CGEN_IFLD_NBOOL_ATTRS 1 84760484Sobrien#endif 84860484Sobrien CGEN_ATTR_TYPE (CGEN_IFLD_NBOOL_ATTRS) attrs; 84960484Sobrien#define CGEN_IFLD_ATTRS(f) (&(f)->attrs) 85060484Sobrien} CGEN_IFLD; 85160484Sobrien 85260484Sobrien/* Return value of attribute ATTR in IFLD. */ 85360484Sobrien#define CGEN_IFLD_ATTR_VALUE(ifld, attr) \ 85460484SobrienCGEN_ATTR_VALUE ((ifld), CGEN_IFLD_ATTRS (ifld), (attr)) 85560484Sobrien 85660484Sobrien/* Instruction data. */ 85760484Sobrien 85838889Sjdp/* Instruction formats. 85938889Sjdp 86038889Sjdp Instructions are grouped by format. Associated with an instruction is its 86160484Sobrien format. Each insn's opcode table entry contains a format table entry. 86238889Sjdp ??? There is usually very few formats compared with the number of insns, 86338889Sjdp so one can reduce the size of the opcode table by recording the format table 86438889Sjdp as a separate entity. Given that we currently don't, format table entries 86538889Sjdp are also distinguished by their operands. This increases the size of the 86638889Sjdp table, but reduces the number of tables. It's all minutiae anyway so it 86738889Sjdp doesn't really matter [at this point in time]. 86838889Sjdp 86938889Sjdp ??? Support for variable length ISA's is wip. */ 87038889Sjdp 87160484Sobrien/* Accompanying each iformat description is a list of its fields. */ 87260484Sobrien 87360484Sobrientypedef struct { 87460484Sobrien const CGEN_IFLD *ifld; 87560484Sobrien#define CGEN_IFMT_IFLD_IFLD(ii) ((ii)->ifld) 87660484Sobrien} CGEN_IFMT_IFLD; 87760484Sobrien 87885815Sobrien/* This should be at least as large as necessary for any target. */ 87985815Sobrien#define CGEN_MAX_IFMT_OPERANDS 16 88085815Sobrien 88185815Sobrien/* A target may know its own precise maximum. Assert that it falls below 88285815Sobrien the above limit. */ 88385815Sobrien#ifdef CGEN_ACTUAL_MAX_IFMT_OPERANDS 88485815Sobrien#if CGEN_ACTUAL_MAX_IFMT_OPERANDS > CGEN_MAX_IFMT_OPERANDS 88585815Sobrien#error "CGEN_ACTUAL_MAX_IFMT_OPERANDS too high - enlarge CGEN_MAX_IFMT_OPERANDS" 88660484Sobrien#endif 88785815Sobrien#endif 88860484Sobrien 88985815Sobrien 89038889Sjdptypedef struct 89138889Sjdp{ 89238889Sjdp /* Length that MASK and VALUE have been calculated to 89338889Sjdp [VALUE is recorded elsewhere]. 89460484Sobrien Normally it is base_insn_bitsize. On [V]LIW architectures where the base 89560484Sobrien insn size may be larger than the size of an insn, this field is less than 89660484Sobrien base_insn_bitsize. */ 89738889Sjdp unsigned char mask_length; 89860484Sobrien#define CGEN_IFMT_MASK_LENGTH(ifmt) ((ifmt)->mask_length) 89938889Sjdp 90038889Sjdp /* Total length of instruction, in bits. */ 90138889Sjdp unsigned char length; 90260484Sobrien#define CGEN_IFMT_LENGTH(ifmt) ((ifmt)->length) 90338889Sjdp 90438889Sjdp /* Mask to apply to the first MASK_LENGTH bits. 90538889Sjdp Each insn's value is stored with the insn. 90638889Sjdp The first step in recognizing an insn for disassembly is 90738889Sjdp (opcode & mask) == value. */ 90860484Sobrien CGEN_INSN_INT mask; 90960484Sobrien#define CGEN_IFMT_MASK(ifmt) ((ifmt)->mask) 91060484Sobrien 91160484Sobrien /* Instruction fields. 91260484Sobrien +1 for trailing NULL. */ 91360484Sobrien CGEN_IFMT_IFLD iflds[CGEN_MAX_IFMT_OPERANDS + 1]; 91460484Sobrien#define CGEN_IFMT_IFLDS(ifmt) ((ifmt)->iflds) 91560484Sobrien} CGEN_IFMT; 91660484Sobrien 91760484Sobrien/* Instruction values. */ 91860484Sobrien 91960484Sobrientypedef struct 92060484Sobrien{ 92160484Sobrien /* The opcode portion of the base insn. */ 92260484Sobrien CGEN_INSN_INT base_value; 92360484Sobrien 92460484Sobrien#ifdef CGEN_MAX_EXTRA_OPCODE_OPERANDS 92560484Sobrien /* Extra opcode values beyond base_value. */ 92660484Sobrien unsigned long ifield_values[CGEN_MAX_EXTRA_OPCODE_OPERANDS]; 92760484Sobrien#endif 92860484Sobrien} CGEN_IVALUE; 92960484Sobrien 93060484Sobrien/* Instruction opcode table. 93160484Sobrien This contains the syntax and format data of an instruction. */ 93260484Sobrien 93360484Sobrien/* ??? Some ports already have an opcode table yet still need to use the rest 93460484Sobrien of what cgen_insn has. Plus keeping the opcode data with the operand 93560484Sobrien instance data can create a pretty big file. So we keep them separately. 93660484Sobrien Not sure this is a good idea in the long run. */ 93760484Sobrien 93860484Sobrientypedef struct 93960484Sobrien{ 94060484Sobrien /* Indices into parse/insert/extract/print handler tables. */ 94160484Sobrien struct cgen_opcode_handler handlers; 94260484Sobrien#define CGEN_OPCODE_HANDLERS(opc) (& (opc)->handlers) 94360484Sobrien 94460484Sobrien /* Syntax string. */ 94560484Sobrien CGEN_SYNTAX syntax; 94660484Sobrien#define CGEN_OPCODE_SYNTAX(opc) (& (opc)->syntax) 94760484Sobrien 94860484Sobrien /* Format entry. */ 94960484Sobrien const CGEN_IFMT *format; 95060484Sobrien#define CGEN_OPCODE_FORMAT(opc) ((opc)->format) 95160484Sobrien#define CGEN_OPCODE_MASK_BITSIZE(opc) CGEN_IFMT_MASK_LENGTH (CGEN_OPCODE_FORMAT (opc)) 95260484Sobrien#define CGEN_OPCODE_BITSIZE(opc) CGEN_IFMT_LENGTH (CGEN_OPCODE_FORMAT (opc)) 95360484Sobrien#define CGEN_OPCODE_IFLDS(opc) CGEN_IFMT_IFLDS (CGEN_OPCODE_FORMAT (opc)) 95460484Sobrien 95560484Sobrien /* Instruction opcode value. */ 95660484Sobrien CGEN_IVALUE value; 95760484Sobrien#define CGEN_OPCODE_VALUE(opc) (& (opc)->value) 95860484Sobrien#define CGEN_OPCODE_BASE_VALUE(opc) (CGEN_OPCODE_VALUE (opc)->base_value) 95960484Sobrien#define CGEN_OPCODE_BASE_MASK(opc) CGEN_IFMT_MASK (CGEN_OPCODE_FORMAT (opc)) 96060484Sobrien} CGEN_OPCODE; 96160484Sobrien 96260484Sobrien/* Instruction attributes. 96360484Sobrien This is made a published type as applications can cache a pointer to 96460484Sobrien the attributes for speed. */ 96560484Sobrien 96660484Sobrien#ifndef CGEN_INSN_NBOOL_ATTRS 96760484Sobrien#define CGEN_INSN_NBOOL_ATTRS 1 96860484Sobrien#endif 96960484Sobrientypedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE; 97060484Sobrien 97160484Sobrien/* Enum of architecture independent attributes. */ 97260484Sobrien 97360484Sobrien#ifndef CGEN_ARCH 97460484Sobrien/* ??? Numbers here are recorded in two places. */ 97560484Sobrientypedef enum cgen_insn_attr { 97660484Sobrien CGEN_INSN_ALIAS = 0 97760484Sobrien} CGEN_INSN_ATTR; 978218822Sdim#define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) ((attrs)->bool & (1 << CGEN_INSN_ALIAS)) 97960484Sobrien#endif 98060484Sobrien 98133965Sjdp/* This struct defines each entry in the instruction table. */ 98233965Sjdp 98360484Sobrientypedef struct 98438889Sjdp{ 98560484Sobrien /* Each real instruction is enumerated. */ 98660484Sobrien /* ??? This may go away in time. */ 98760484Sobrien int num; 98860484Sobrien#define CGEN_INSN_NUM(insn) ((insn)->base->num) 98933965Sjdp 99060484Sobrien /* Name of entry (that distinguishes it from all other entries). */ 99138889Sjdp /* ??? If mnemonics have operands, try to print full mnemonic. */ 99260484Sobrien const char *name; 99360484Sobrien#define CGEN_INSN_NAME(insn) ((insn)->base->name) 99433965Sjdp 99538889Sjdp /* Mnemonic. This is used when parsing and printing the insn. 99638889Sjdp In the case of insns that have operands on the mnemonics, this is 99738889Sjdp only the constant part. E.g. for conditional execution of an `add' insn, 99860484Sobrien where the full mnemonic is addeq, addne, etc., and the condition is 99960484Sobrien treated as an operand, this is only "add". */ 100060484Sobrien const char *mnemonic; 100160484Sobrien#define CGEN_INSN_MNEMONIC(insn) ((insn)->base->mnemonic) 100238889Sjdp 100360484Sobrien /* Total length of instruction, in bits. */ 100460484Sobrien int bitsize; 100560484Sobrien#define CGEN_INSN_BITSIZE(insn) ((insn)->base->bitsize) 100638889Sjdp 100760484Sobrien#if 0 /* ??? Disabled for now as there is a problem with embedded newlines 100860484Sobrien and the table is already pretty big. Should perhaps be moved 100960484Sobrien to a file of its own. */ 101060484Sobrien /* Semantics, as RTL. */ 101160484Sobrien /* ??? Plain text or bytecodes? */ 101260484Sobrien /* ??? Note that the operand instance table could be computed at run-time 101360484Sobrien if we parse this and cache the results. Something to eventually do. */ 101460484Sobrien const char *rtx; 101560484Sobrien#define CGEN_INSN_RTX(insn) ((insn)->base->rtx) 101660484Sobrien#endif 101738889Sjdp 101838889Sjdp /* Attributes. 101938889Sjdp This must appear last. It is a variable sized array in that one 102038889Sjdp architecture may have 1 nonbool attribute and another may have more. 102138889Sjdp Having this last means the non-architecture specific code needn't 102260484Sobrien care. The goal is to eventually record attributes in their raw form, 102360484Sobrien evaluate them at run-time, and cache the values, so this worry will go 102460484Sobrien away anyway. */ 102560484Sobrien CGEN_INSN_ATTR_TYPE attrs; 102660484Sobrien#define CGEN_INSN_ATTRS(insn) (&(insn)->base->attrs) 102733965Sjdp/* Return value of attribute ATTR in INSN. */ 102860484Sobrien#define CGEN_INSN_ATTR_VALUE(insn, attr) \ 102960484SobrienCGEN_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 1030218822Sdim#define CGEN_INSN_BITSET_ATTR_VALUE(insn, attr) \ 1031218822Sdim CGEN_BITSET_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 103260484Sobrien} CGEN_IBASE; 103360484Sobrien 103460484Sobrien/* Return non-zero if INSN is the "invalid" insn marker. */ 103560484Sobrien 103660484Sobrien#define CGEN_INSN_INVALID_P(insn) (CGEN_INSN_MNEMONIC (insn) == 0) 103760484Sobrien 103860484Sobrien/* Main struct contain instruction information. 103960484Sobrien BASE is always present, the rest is present only if asked for. */ 104060484Sobrien 104160484Sobrienstruct cgen_insn 104260484Sobrien{ 104360484Sobrien /* ??? May be of use to put a type indicator here. 104460484Sobrien Then this struct could different info for different classes of insns. */ 104560484Sobrien /* ??? A speedup can be had by moving `base' into this struct. 104660484Sobrien Maybe later. */ 104760484Sobrien const CGEN_IBASE *base; 104860484Sobrien const CGEN_OPCODE *opcode; 104960484Sobrien const CGEN_OPINST *opinst; 105089857Sobrien 105189857Sobrien /* Regex to disambiguate overloaded opcodes */ 105289857Sobrien void *rx; 105389857Sobrien#define CGEN_INSN_RX(insn) ((insn)->rx) 105489857Sobrien#define CGEN_MAX_RX_ELEMENTS (CGEN_MAX_SYNTAX_ELEMENTS * 5) 105538889Sjdp}; 105633965Sjdp 105733965Sjdp/* Instruction lists. 105833965Sjdp This is used for adding new entries and for creating the hash lists. */ 105933965Sjdp 106038889Sjdptypedef struct cgen_insn_list 106138889Sjdp{ 106260484Sobrien struct cgen_insn_list *next; 106360484Sobrien const CGEN_INSN *insn; 106433965Sjdp} CGEN_INSN_LIST; 106533965Sjdp 106660484Sobrien/* Table of instructions. */ 106733965Sjdp 106838889Sjdptypedef struct 106938889Sjdp{ 107060484Sobrien const CGEN_INSN *init_entries; 107160484Sobrien unsigned int entry_size; /* since the attribute member is variable sized */ 107233965Sjdp unsigned int num_init_entries; 107360484Sobrien CGEN_INSN_LIST *new_entries; 107433965Sjdp} CGEN_INSN_TABLE; 107533965Sjdp 107660484Sobrien/* Return number of instructions. This includes any added at run-time. */ 107733965Sjdp 1078130561Sobrienextern int cgen_insn_count (CGEN_CPU_DESC); 1079130561Sobrienextern int cgen_macro_insn_count (CGEN_CPU_DESC); 108033965Sjdp 108160484Sobrien/* Macros to access the other insn elements not recorded in CGEN_IBASE. */ 108233965Sjdp 108360484Sobrien/* Fetch INSN's operand instance table. */ 108460484Sobrien/* ??? Doesn't handle insns added at runtime. */ 108560484Sobrien#define CGEN_INSN_OPERANDS(insn) ((insn)->opinst) 108660484Sobrien 108760484Sobrien/* Return INSN's opcode table entry. */ 108860484Sobrien#define CGEN_INSN_OPCODE(insn) ((insn)->opcode) 108960484Sobrien 109060484Sobrien/* Return INSN's handler data. */ 109160484Sobrien#define CGEN_INSN_HANDLERS(insn) CGEN_OPCODE_HANDLERS (CGEN_INSN_OPCODE (insn)) 109260484Sobrien 109360484Sobrien/* Return INSN's syntax. */ 109460484Sobrien#define CGEN_INSN_SYNTAX(insn) CGEN_OPCODE_SYNTAX (CGEN_INSN_OPCODE (insn)) 109560484Sobrien 109660484Sobrien/* Return size of base mask in bits. */ 109760484Sobrien#define CGEN_INSN_MASK_BITSIZE(insn) \ 109860484Sobrien CGEN_OPCODE_MASK_BITSIZE (CGEN_INSN_OPCODE (insn)) 109960484Sobrien 110060484Sobrien/* Return mask of base part of INSN. */ 110160484Sobrien#define CGEN_INSN_BASE_MASK(insn) \ 110260484Sobrien CGEN_OPCODE_BASE_MASK (CGEN_INSN_OPCODE (insn)) 110360484Sobrien 110460484Sobrien/* Return value of base part of INSN. */ 110560484Sobrien#define CGEN_INSN_BASE_VALUE(insn) \ 110660484Sobrien CGEN_OPCODE_BASE_VALUE (CGEN_INSN_OPCODE (insn)) 110760484Sobrien 110860484Sobrien/* Standard way to test whether INSN is supported by MACH. 110960484Sobrien MACH is one of enum mach_attr. 111060484Sobrien The "|1" is because the base mach is always selected. */ 111160484Sobrien#define CGEN_INSN_MACH_HAS_P(insn, mach) \ 111260484Sobrien((CGEN_INSN_ATTR_VALUE ((insn), CGEN_INSN_MACH) & ((1 << (mach)) | 1)) != 0) 111360484Sobrien 111460484Sobrien/* Macro instructions. 111560484Sobrien Macro insns aren't real insns, they map to one or more real insns. 111660484Sobrien E.g. An architecture's "nop" insn may actually be an "mv r0,r0" or 111760484Sobrien some such. 111860484Sobrien 111960484Sobrien Macro insns can expand to nothing (e.g. a nop that is optimized away). 112060484Sobrien This is useful in multi-insn macros that build a constant in a register. 112160484Sobrien Of course this isn't the default behaviour and must be explicitly enabled. 112260484Sobrien 112360484Sobrien Assembly of macro-insns is relatively straightforward. Disassembly isn't. 112460484Sobrien However, disassembly of at least some kinds of macro insns is important 112560484Sobrien in order that the disassembled code preserve the readability of the original 112660484Sobrien insn. What is attempted here is to disassemble all "simple" macro-insns, 112760484Sobrien where "simple" is currently defined to mean "expands to one real insn". 112860484Sobrien 112960484Sobrien Simple macro-insns are handled specially. They are emitted as ALIAS's 113060484Sobrien of real insns. This simplifies their handling since there's usually more 113160484Sobrien of them than any other kind of macro-insn, and proper disassembly of them 113260484Sobrien falls out for free. */ 113360484Sobrien 113460484Sobrien/* For each macro-insn there may be multiple expansion possibilities, 113560484Sobrien depending on the arguments. This structure is accessed via the `data' 113660484Sobrien member of CGEN_INSN. */ 113760484Sobrien 113860484Sobrientypedef struct cgen_minsn_expansion { 113960484Sobrien /* Function to do the expansion. 114060484Sobrien If the expansion fails (e.g. "no match") NULL is returned. 114160484Sobrien Space for the expansion is obtained with malloc. 114260484Sobrien It is up to the caller to free it. */ 1143130561Sobrien const char * (* fn) 1144130561Sobrien (const struct cgen_minsn_expansion *, 1145130561Sobrien const char *, const char **, int *, 1146130561Sobrien CGEN_OPERAND **); 114760484Sobrien#define CGEN_MIEXPN_FN(ex) ((ex)->fn) 114860484Sobrien 114960484Sobrien /* Instruction(s) the macro expands to. 115060484Sobrien The format of STR is defined by FN. 115160484Sobrien It is typically the assembly code of the real insn, but it could also be 115260484Sobrien the original Scheme expression or a tokenized form of it (with FN being 115360484Sobrien an appropriate interpreter). */ 115460484Sobrien const char * str; 115560484Sobrien#define CGEN_MIEXPN_STR(ex) ((ex)->str) 115660484Sobrien} CGEN_MINSN_EXPANSION; 115760484Sobrien 115860484Sobrien/* Normal expander. 115960484Sobrien When supported, this function will convert the input string to another 116060484Sobrien string and the parser will be invoked recursively. The output string 116160484Sobrien may contain further macro invocations. */ 116260484Sobrien 116360484Sobrienextern const char * cgen_expand_macro_insn 1164130561Sobrien (CGEN_CPU_DESC, const struct cgen_minsn_expansion *, 1165130561Sobrien const char *, const char **, int *, CGEN_OPERAND **); 116660484Sobrien 116733965Sjdp/* The assembler insn table is hashed based on some function of the mnemonic 116833965Sjdp (the actually hashing done is up to the target, but we provide a few 116960484Sobrien examples like the first letter or a function of the entire mnemonic). */ 117033965Sjdp 117160484Sobrienextern CGEN_INSN_LIST * cgen_asm_lookup_insn 1172130561Sobrien (CGEN_CPU_DESC, const char *); 117360484Sobrien#define CGEN_ASM_LOOKUP_INSN(cd, string) cgen_asm_lookup_insn ((cd), (string)) 117433965Sjdp#define CGEN_ASM_NEXT_INSN(insn) ((insn)->next) 117533965Sjdp 117633965Sjdp/* The disassembler insn table is hashed based on some function of machine 117733965Sjdp instruction (the actually hashing done is up to the target). */ 117833965Sjdp 117960484Sobrienextern CGEN_INSN_LIST * cgen_dis_lookup_insn 1180130561Sobrien (CGEN_CPU_DESC, const char *, CGEN_INSN_INT); 118160484Sobrien/* FIXME: delete these two */ 118260484Sobrien#define CGEN_DIS_LOOKUP_INSN(cd, buf, value) cgen_dis_lookup_insn ((cd), (buf), (value)) 118333965Sjdp#define CGEN_DIS_NEXT_INSN(insn) ((insn)->next) 118433965Sjdp 118560484Sobrien/* The CPU description. 118660484Sobrien A copy of this is created when the cpu table is "opened". 118760484Sobrien All global state information is recorded here. 118860484Sobrien Access macros are provided for "public" members. */ 118933965Sjdp 119060484Sobrientypedef struct cgen_cpu_desc 119138889Sjdp{ 119260484Sobrien /* Bitmap of selected machine(s) (a la BFD machine number). */ 119360484Sobrien int machs; 119433965Sjdp 1195218822Sdim /* Bitmap of selected isa(s). */ 1196218822Sdim CGEN_BITSET *isas; 1197218822Sdim#define CGEN_CPU_ISAS(cd) ((cd)->isas) 119833965Sjdp 119960484Sobrien /* Current endian. */ 120060484Sobrien enum cgen_endian endian; 120160484Sobrien#define CGEN_CPU_ENDIAN(cd) ((cd)->endian) 120233965Sjdp 120360484Sobrien /* Current insn endian. */ 120460484Sobrien enum cgen_endian insn_endian; 120560484Sobrien#define CGEN_CPU_INSN_ENDIAN(cd) ((cd)->insn_endian) 120633965Sjdp 120760484Sobrien /* Word size (in bits). */ 120860484Sobrien /* ??? Or maybe maximum word size - might we ever need to allow a cpu table 120960484Sobrien to be opened for both sparc32/sparc64? 121060484Sobrien ??? Another alternative is to create a table of selected machs and 121160484Sobrien lazily fetch the data from there. */ 121260484Sobrien unsigned int word_bitsize; 121333965Sjdp 121489857Sobrien /* Instruction chunk size (in bits), for purposes of endianness 121589857Sobrien conversion. */ 121689857Sobrien unsigned int insn_chunk_bitsize; 121789857Sobrien 121860484Sobrien /* Indicator if sizes are unknown. 121960484Sobrien This is used by default_insn_bitsize,base_insn_bitsize if there is a 122060484Sobrien difference between the selected isa's. */ 122160484Sobrien#define CGEN_SIZE_UNKNOWN 65535 122233965Sjdp 122360484Sobrien /* Default instruction size (in bits). 122460484Sobrien This is used by the assembler when it encounters an unknown insn. */ 122560484Sobrien unsigned int default_insn_bitsize; 122633965Sjdp 122760484Sobrien /* Base instruction size (in bits). 122860484Sobrien For non-LIW cpus this is generally the length of the smallest insn. 122960484Sobrien For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 123060484Sobrien unsigned int base_insn_bitsize; 123133965Sjdp 123260484Sobrien /* Minimum/maximum instruction size (in bits). */ 123360484Sobrien unsigned int min_insn_bitsize; 123460484Sobrien unsigned int max_insn_bitsize; 123538889Sjdp 123660484Sobrien /* Instruction set variants. */ 123760484Sobrien const CGEN_ISA *isa_table; 123860484Sobrien 123960484Sobrien /* Machine variants. */ 124060484Sobrien const CGEN_MACH *mach_table; 124160484Sobrien 124260484Sobrien /* Hardware elements. */ 124360484Sobrien CGEN_HW_TABLE hw_table; 124460484Sobrien 124560484Sobrien /* Instruction fields. */ 124660484Sobrien const CGEN_IFLD *ifld_table; 124760484Sobrien 124860484Sobrien /* Operands. */ 124960484Sobrien CGEN_OPERAND_TABLE operand_table; 125060484Sobrien 125160484Sobrien /* Main instruction table. */ 125260484Sobrien CGEN_INSN_TABLE insn_table; 125360484Sobrien#define CGEN_CPU_INSN_TABLE(cd) (& (cd)->insn_table) 125460484Sobrien 125560484Sobrien /* Macro instructions are defined separately and are combined with real 125660484Sobrien insns during hash table computation. */ 125760484Sobrien CGEN_INSN_TABLE macro_insn_table; 125860484Sobrien 125960484Sobrien /* Copy of CGEN_INT_INSN_P. */ 126060484Sobrien int int_insn_p; 126160484Sobrien 126260484Sobrien /* Called to rebuild the tables after something has changed. */ 1263130561Sobrien void (*rebuild_tables) (CGEN_CPU_DESC); 126460484Sobrien 126560484Sobrien /* Operand parser callback. */ 126660484Sobrien cgen_parse_operand_fn * parse_operand_fn; 126760484Sobrien 126860484Sobrien /* Parse/insert/extract/print cover fns for operands. */ 126960484Sobrien const char * (*parse_operand) 1270130561Sobrien (CGEN_CPU_DESC, int opindex_, const char **, CGEN_FIELDS *fields_); 1271130561Sobrien#ifdef __BFD_H_SEEN__ 127260484Sobrien const char * (*insert_operand) 1273130561Sobrien (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, 1274130561Sobrien CGEN_INSN_BYTES_PTR, bfd_vma pc_); 127560484Sobrien int (*extract_operand) 1276130561Sobrien (CGEN_CPU_DESC, int opindex_, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, 1277130561Sobrien CGEN_FIELDS *fields_, bfd_vma pc_); 127860484Sobrien void (*print_operand) 1279130561Sobrien (CGEN_CPU_DESC, int opindex_, void * info_, CGEN_FIELDS * fields_, 1280130561Sobrien void const *attrs_, bfd_vma pc_, int length_); 128160484Sobrien#else 128260484Sobrien const char * (*insert_operand) (); 128360484Sobrien int (*extract_operand) (); 128460484Sobrien void (*print_operand) (); 128533965Sjdp#endif 128660484Sobrien#define CGEN_CPU_PARSE_OPERAND(cd) ((cd)->parse_operand) 128760484Sobrien#define CGEN_CPU_INSERT_OPERAND(cd) ((cd)->insert_operand) 128860484Sobrien#define CGEN_CPU_EXTRACT_OPERAND(cd) ((cd)->extract_operand) 128960484Sobrien#define CGEN_CPU_PRINT_OPERAND(cd) ((cd)->print_operand) 129033965Sjdp 129160484Sobrien /* Size of CGEN_FIELDS struct. */ 129260484Sobrien unsigned int sizeof_fields; 129360484Sobrien#define CGEN_CPU_SIZEOF_FIELDS(cd) ((cd)->sizeof_fields) 129433965Sjdp 129560484Sobrien /* Set the bitsize field. */ 1296130561Sobrien void (*set_fields_bitsize) (CGEN_FIELDS *fields_, int size_); 129760484Sobrien#define CGEN_CPU_SET_FIELDS_BITSIZE(cd) ((cd)->set_fields_bitsize) 129838889Sjdp 129960484Sobrien /* CGEN_FIELDS accessors. */ 130060484Sobrien int (*get_int_operand) 1301130561Sobrien (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 130260484Sobrien void (*set_int_operand) 1303130561Sobrien (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, int value_); 1304130561Sobrien#ifdef __BFD_H_SEEN__ 130560484Sobrien bfd_vma (*get_vma_operand) 1306130561Sobrien (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 130760484Sobrien void (*set_vma_operand) 1308130561Sobrien (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, bfd_vma value_); 130960484Sobrien#else 131060484Sobrien long (*get_vma_operand) (); 131160484Sobrien void (*set_vma_operand) (); 131260484Sobrien#endif 131360484Sobrien#define CGEN_CPU_GET_INT_OPERAND(cd) ((cd)->get_int_operand) 131460484Sobrien#define CGEN_CPU_SET_INT_OPERAND(cd) ((cd)->set_int_operand) 131560484Sobrien#define CGEN_CPU_GET_VMA_OPERAND(cd) ((cd)->get_vma_operand) 131660484Sobrien#define CGEN_CPU_SET_VMA_OPERAND(cd) ((cd)->set_vma_operand) 131733965Sjdp 131860484Sobrien /* Instruction parse/insert/extract/print handlers. */ 131960484Sobrien /* FIXME: make these types uppercase. */ 132060484Sobrien cgen_parse_fn * const *parse_handlers; 132160484Sobrien cgen_insert_fn * const *insert_handlers; 132260484Sobrien cgen_extract_fn * const *extract_handlers; 132360484Sobrien cgen_print_fn * const *print_handlers; 132460484Sobrien#define CGEN_PARSE_FN(cd, insn) (cd->parse_handlers[(insn)->opcode->handlers.parse]) 132560484Sobrien#define CGEN_INSERT_FN(cd, insn) (cd->insert_handlers[(insn)->opcode->handlers.insert]) 132660484Sobrien#define CGEN_EXTRACT_FN(cd, insn) (cd->extract_handlers[(insn)->opcode->handlers.extract]) 132760484Sobrien#define CGEN_PRINT_FN(cd, insn) (cd->print_handlers[(insn)->opcode->handlers.print]) 132833965Sjdp 132960484Sobrien /* Return non-zero if insn should be added to hash table. */ 1330130561Sobrien int (* asm_hash_p) (const CGEN_INSN *); 133133965Sjdp 133260484Sobrien /* Assembler hash function. */ 1333130561Sobrien unsigned int (* asm_hash) (const char *); 133433965Sjdp 133560484Sobrien /* Number of entries in assembler hash table. */ 133660484Sobrien unsigned int asm_hash_size; 133733965Sjdp 133860484Sobrien /* Return non-zero if insn should be added to hash table. */ 1339130561Sobrien int (* dis_hash_p) (const CGEN_INSN *); 134060484Sobrien 134160484Sobrien /* Disassembler hash function. */ 1342130561Sobrien unsigned int (* dis_hash) (const char *, CGEN_INSN_INT); 134360484Sobrien 134460484Sobrien /* Number of entries in disassembler hash table. */ 134560484Sobrien unsigned int dis_hash_size; 134660484Sobrien 134760484Sobrien /* Assembler instruction hash table. */ 134860484Sobrien CGEN_INSN_LIST **asm_hash_table; 134960484Sobrien CGEN_INSN_LIST *asm_hash_table_entries; 135060484Sobrien 135160484Sobrien /* Disassembler instruction hash table. */ 135260484Sobrien CGEN_INSN_LIST **dis_hash_table; 135360484Sobrien CGEN_INSN_LIST *dis_hash_table_entries; 135460484Sobrien 135560484Sobrien /* This field could be turned into a bitfield if room for other flags is needed. */ 135660484Sobrien unsigned int signed_overflow_ok_p; 135760484Sobrien 135860484Sobrien} CGEN_CPU_TABLE; 135960484Sobrien 136060484Sobrien/* wip */ 136160484Sobrien#ifndef CGEN_WORD_ENDIAN 136260484Sobrien#define CGEN_WORD_ENDIAN(cd) CGEN_CPU_ENDIAN (cd) 136360484Sobrien#endif 136460484Sobrien#ifndef CGEN_INSN_WORD_ENDIAN 136560484Sobrien#define CGEN_INSN_WORD_ENDIAN(cd) CGEN_CPU_INSN_ENDIAN (cd) 136660484Sobrien#endif 136760484Sobrien 136860484Sobrien/* Prototypes of major functions. */ 136960484Sobrien/* FIXME: Move more CGEN_SYM-defined functions into CGEN_CPU_DESC. 137060484Sobrien Not the init fns though, as that would drag in things that mightn't be 137160484Sobrien used and might not even exist. */ 137260484Sobrien 137360484Sobrien/* Argument types to cpu_open. */ 137460484Sobrien 137560484Sobrienenum cgen_cpu_open_arg { 137660484Sobrien CGEN_CPU_OPEN_END, 137760484Sobrien /* Select instruction set(s), arg is bitmap or 0 meaning "unspecified". */ 137860484Sobrien CGEN_CPU_OPEN_ISAS, 137960484Sobrien /* Select machine(s), arg is bitmap or 0 meaning "unspecified". */ 138060484Sobrien CGEN_CPU_OPEN_MACHS, 138160484Sobrien /* Select machine, arg is mach's bfd name. 138260484Sobrien Multiple machines can be specified by repeated use. */ 138360484Sobrien CGEN_CPU_OPEN_BFDMACH, 138460484Sobrien /* Select endian, arg is CGEN_ENDIAN_*. */ 138560484Sobrien CGEN_CPU_OPEN_ENDIAN 138660484Sobrien}; 138760484Sobrien 138860484Sobrien/* Open a cpu descriptor table for use. 138960484Sobrien ??? We only support ISO C stdargs here, not K&R. 139060484Sobrien Laziness, plus experiment to see if anything requires K&R - eventually 139160484Sobrien K&R will no longer be supported - e.g. GDB is currently trying this. */ 139260484Sobrien 139360484Sobrienextern CGEN_CPU_DESC CGEN_SYM (cpu_open) (enum cgen_cpu_open_arg, ...); 139460484Sobrien 139560484Sobrien/* Cover fn to handle simple case. */ 139660484Sobrien 1397130561Sobrienextern CGEN_CPU_DESC CGEN_SYM (cpu_open_1) 1398130561Sobrien (const char *mach_name_, enum cgen_endian endian_); 139960484Sobrien 140060484Sobrien/* Close it. */ 140160484Sobrien 1402130561Sobrienextern void CGEN_SYM (cpu_close) (CGEN_CPU_DESC); 140360484Sobrien 140460484Sobrien/* Initialize the opcode table for use. 140560484Sobrien Called by init_asm/init_dis. */ 140660484Sobrien 1407130561Sobrienextern void CGEN_SYM (init_opcode_table) (CGEN_CPU_DESC cd_); 140860484Sobrien 140989857Sobrien/* build the insn selection regex. 141089857Sobrien called by init_opcode_table */ 141189857Sobrien 1412130561Sobrienextern char * CGEN_SYM(build_insn_regex) (CGEN_INSN *insn_); 141389857Sobrien 141460484Sobrien/* Initialize the ibld table for use. 141560484Sobrien Called by init_asm/init_dis. */ 141660484Sobrien 1417130561Sobrienextern void CGEN_SYM (init_ibld_table) (CGEN_CPU_DESC cd_); 141860484Sobrien 141960484Sobrien/* Initialize an cpu table for assembler or disassembler use. 142060484Sobrien These must be called immediately after cpu_open. */ 142160484Sobrien 1422130561Sobrienextern void CGEN_SYM (init_asm) (CGEN_CPU_DESC); 1423130561Sobrienextern void CGEN_SYM (init_dis) (CGEN_CPU_DESC); 142460484Sobrien 142560484Sobrien/* Initialize the operand instance table for use. */ 142660484Sobrien 1427130561Sobrienextern void CGEN_SYM (init_opinst_table) (CGEN_CPU_DESC cd_); 142860484Sobrien 142960484Sobrien/* Assemble an instruction. */ 143060484Sobrien 143160484Sobrienextern const CGEN_INSN * CGEN_SYM (assemble_insn) 1432130561Sobrien (CGEN_CPU_DESC, const char *, CGEN_FIELDS *, 1433130561Sobrien CGEN_INSN_BYTES_PTR, char **); 143460484Sobrien 143560484Sobrienextern const CGEN_KEYWORD CGEN_SYM (operand_mach); 1436130561Sobrienextern int CGEN_SYM (get_mach) (const char *); 143760484Sobrien 143860484Sobrien/* Operand index computation. */ 143960484Sobrienextern const CGEN_INSN * cgen_lookup_insn 1440130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN * insn_, 1441130561Sobrien CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 1442130561Sobrien int length_, CGEN_FIELDS *fields_, int alias_p_); 144360484Sobrienextern void cgen_get_insn_operands 1444130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN * insn_, 1445130561Sobrien const CGEN_FIELDS *fields_, int *indices_); 144660484Sobrienextern const CGEN_INSN * cgen_lookup_get_insn_operands 1447130561Sobrien (CGEN_CPU_DESC, const CGEN_INSN *insn_, 1448130561Sobrien CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 1449130561Sobrien int length_, int *indices_, CGEN_FIELDS *fields_); 145060484Sobrien 145160484Sobrien/* Cover fns to bfd_get/set. */ 145260484Sobrien 145360484Sobrienextern CGEN_INSN_INT cgen_get_insn_value 1454130561Sobrien (CGEN_CPU_DESC, unsigned char *, int); 145560484Sobrienextern void cgen_put_insn_value 1456130561Sobrien (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT); 145760484Sobrien 145860484Sobrien/* Read in a cpu description file. 145960484Sobrien ??? For future concerns, including adding instructions to the assembler/ 146060484Sobrien disassembler at run-time. */ 146160484Sobrien 1462130561Sobrienextern const char * cgen_read_cpu_file (CGEN_CPU_DESC, const char * filename_); 146360484Sobrien 146460484Sobrien/* Allow signed overflow of instruction fields. */ 1465130561Sobrienextern void cgen_set_signed_overflow_ok (CGEN_CPU_DESC); 146660484Sobrien 146760484Sobrien/* Generate an error message if a signed field in an instruction overflows. */ 1468130561Sobrienextern void cgen_clear_signed_overflow_ok (CGEN_CPU_DESC); 146960484Sobrien 147060484Sobrien/* Will an error message be generated if a signed field in an instruction overflows ? */ 1471130561Sobrienextern unsigned int cgen_signed_overflow_ok_p (CGEN_CPU_DESC); 147260484Sobrien 147333965Sjdp#endif /* CGEN_H */ 1474