175fd0b74Schristos /* Header file for targets using CGEN: Cpu tools GENerator. 275fd0b74Schristos 3*e992f068Schristos Copyright (C) 1996-2022 Free Software Foundation, Inc. 475fd0b74Schristos 575fd0b74Schristos This file is part of GDB, the GNU debugger, and the GNU Binutils. 675fd0b74Schristos 775fd0b74Schristos This program is free software; you can redistribute it and/or modify 875fd0b74Schristos it under the terms of the GNU General Public License as published by 975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or 1075fd0b74Schristos (at your option) any later version. 1175fd0b74Schristos 1275fd0b74Schristos This program is distributed in the hope that it will be useful, 1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1575fd0b74Schristos GNU General Public License for more details. 1675fd0b74Schristos 1775fd0b74Schristos You should have received a copy of the GNU General Public License along 1875fd0b74Schristos with this program; if not, write to the Free Software Foundation, Inc., 1975fd0b74Schristos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2075fd0b74Schristos 2175fd0b74Schristos #ifndef OPCODE_CGEN_H 2275fd0b74Schristos #define OPCODE_CGEN_H 2375fd0b74Schristos 2475fd0b74Schristos #include "symcat.h" 2575fd0b74Schristos #include "cgen/bitset.h" 2675fd0b74Schristos 27*e992f068Schristos #include <stdint.h> 2875fd0b74Schristos 2975fd0b74Schristos #ifdef __cplusplus 3075fd0b74Schristos extern "C" { 3175fd0b74Schristos #endif 3275fd0b74Schristos 3375fd0b74Schristos /* ??? This file requires bfd.h but only to get bfd_vma. 3475fd0b74Schristos Seems like an awful lot to require just to get such a fundamental type. 3575fd0b74Schristos Perhaps the definition of bfd_vma can be moved outside of bfd.h. 3675fd0b74Schristos Or perhaps one could duplicate its definition in another file. 3775fd0b74Schristos Until such time, this file conditionally compiles definitions that require 3875fd0b74Schristos bfd_vma using __BFD_H_SEEN__. */ 3975fd0b74Schristos 4075fd0b74Schristos /* Enums must be defined before they can be used. 4175fd0b74Schristos Allow them to be used in struct definitions, even though the enum must 4275fd0b74Schristos be defined elsewhere. 4375fd0b74Schristos If CGEN_ARCH isn't defined, this file is being included by something other 4475fd0b74Schristos than <arch>-desc.h. */ 4575fd0b74Schristos 4675fd0b74Schristos /* Prepend the arch name, defined in <arch>-desc.h, and _cgen_ to symbol S. 4775fd0b74Schristos The lack of spaces in the arg list is important for non-stdc systems. 4875fd0b74Schristos This file is included by <arch>-desc.h. 4975fd0b74Schristos It can be included independently of <arch>-desc.h, in which case the arch 5075fd0b74Schristos dependent portions will be declared as "unknown_cgen_foo". */ 5175fd0b74Schristos 5275fd0b74Schristos #ifndef CGEN_SYM 5375fd0b74Schristos #define CGEN_SYM(s) CONCAT3 (unknown,_cgen_,s) 5475fd0b74Schristos #endif 5575fd0b74Schristos 5675fd0b74Schristos /* This file contains the static (unchanging) pieces and as much other stuff 5775fd0b74Schristos as we can reasonably put here. It's generally cleaner to put stuff here 5875fd0b74Schristos rather than having it machine generated if possible. */ 5975fd0b74Schristos 6075fd0b74Schristos /* The assembler syntax is made up of expressions (duh...). 6175fd0b74Schristos At the lowest level the values are mnemonics, register names, numbers, etc. 6275fd0b74Schristos Above that are subexpressions, if any (an example might be the 6375fd0b74Schristos "effective address" in m68k cpus). Subexpressions are wip. 6475fd0b74Schristos At the second highest level are the insns themselves. Above that are 6575fd0b74Schristos pseudo-insns, synthetic insns, and macros, if any. */ 6675fd0b74Schristos 6775fd0b74Schristos /* Lots of cpu's have a fixed insn size, or one which rarely changes, 6875fd0b74Schristos and it's generally easier to handle these by treating the insn as an 6975fd0b74Schristos integer type, rather than an array of characters. So we allow targets 7075fd0b74Schristos to control this. When an integer type the value is in host byte order, 7175fd0b74Schristos when an array of characters the value is in target byte order. */ 7275fd0b74Schristos 7375fd0b74Schristos typedef unsigned int CGEN_INSN_INT; 7475fd0b74Schristos typedef int64_t CGEN_INSN_LGSINT; /* large/long SINT */ 7575fd0b74Schristos typedef uint64_t CGEN_INSN_LGUINT; /* large/long UINT */ 7675fd0b74Schristos 7775fd0b74Schristos #if CGEN_INT_INSN_P 7875fd0b74Schristos typedef CGEN_INSN_INT CGEN_INSN_BYTES; 7975fd0b74Schristos typedef CGEN_INSN_INT *CGEN_INSN_BYTES_PTR; 8075fd0b74Schristos #else 8175fd0b74Schristos typedef unsigned char *CGEN_INSN_BYTES; 8275fd0b74Schristos typedef unsigned char *CGEN_INSN_BYTES_PTR; 8375fd0b74Schristos #endif 8475fd0b74Schristos 8575fd0b74Schristos #ifdef __GNUC__ 8675fd0b74Schristos #define CGEN_INLINE __inline__ 8775fd0b74Schristos #else 8875fd0b74Schristos #define CGEN_INLINE 8975fd0b74Schristos #endif 9075fd0b74Schristos 9175fd0b74Schristos enum cgen_endian 9275fd0b74Schristos { 9375fd0b74Schristos CGEN_ENDIAN_UNKNOWN, 9475fd0b74Schristos CGEN_ENDIAN_LITTLE, 9575fd0b74Schristos CGEN_ENDIAN_BIG 9675fd0b74Schristos }; 9775fd0b74Schristos 9875fd0b74Schristos /* Forward decl. */ 9975fd0b74Schristos 10075fd0b74Schristos typedef struct cgen_insn CGEN_INSN; 10175fd0b74Schristos 10275fd0b74Schristos /* Opaque pointer version for use by external world. */ 10375fd0b74Schristos 10475fd0b74Schristos typedef struct cgen_cpu_desc *CGEN_CPU_DESC; 10575fd0b74Schristos 10675fd0b74Schristos /* Attributes. 10775fd0b74Schristos Attributes are used to describe various random things associated with 10875fd0b74Schristos an object (ifield, hardware, operand, insn, whatever) and are specified 10975fd0b74Schristos as name/value pairs. 11075fd0b74Schristos Integer attributes computed at compile time are currently all that's 11175fd0b74Schristos supported, though adding string attributes and run-time computation is 11275fd0b74Schristos straightforward. Integer attribute values are always host int's 11375fd0b74Schristos (signed or unsigned). For portability, this means 32 bits. 11475fd0b74Schristos Integer attributes are further categorized as boolean, bitset, integer, 11575fd0b74Schristos and enum types. Boolean attributes appear frequently enough that they're 11675fd0b74Schristos recorded in one host int. This limits the maximum number of boolean 11775fd0b74Schristos attributes to 32, though that's a *lot* of attributes. */ 11875fd0b74Schristos 11975fd0b74Schristos /* Type of attribute values. */ 12075fd0b74Schristos 12175fd0b74Schristos typedef CGEN_BITSET CGEN_ATTR_VALUE_BITSET_TYPE; 12275fd0b74Schristos typedef int CGEN_ATTR_VALUE_ENUM_TYPE; 12375fd0b74Schristos typedef union 12475fd0b74Schristos { 12575fd0b74Schristos CGEN_ATTR_VALUE_BITSET_TYPE bitset; 12675fd0b74Schristos CGEN_ATTR_VALUE_ENUM_TYPE nonbitset; 12775fd0b74Schristos } CGEN_ATTR_VALUE_TYPE; 12875fd0b74Schristos 12975fd0b74Schristos /* Struct to record attribute information. */ 13075fd0b74Schristos 13175fd0b74Schristos typedef struct 13275fd0b74Schristos { 13375fd0b74Schristos /* Boolean attributes. */ 13475fd0b74Schristos unsigned int bool_; 13575fd0b74Schristos /* Non-boolean integer attributes. */ 13675fd0b74Schristos CGEN_ATTR_VALUE_TYPE nonbool[1]; 13775fd0b74Schristos } CGEN_ATTR; 13875fd0b74Schristos 13975fd0b74Schristos /* Define a structure member for attributes with N non-boolean entries. 14075fd0b74Schristos There is no maximum number of non-boolean attributes. 14175fd0b74Schristos There is a maximum of 32 boolean attributes (since they are all recorded 14275fd0b74Schristos in one host int). */ 14375fd0b74Schristos 14475fd0b74Schristos #define CGEN_ATTR_TYPE(n) \ 14575fd0b74Schristos struct { unsigned int bool_; \ 14675fd0b74Schristos CGEN_ATTR_VALUE_TYPE nonbool[(n) ? (n) : 1]; } 14775fd0b74Schristos 14875fd0b74Schristos /* Return the boolean attributes. */ 14975fd0b74Schristos 15075fd0b74Schristos #define CGEN_ATTR_BOOLS(a) ((a)->bool_) 15175fd0b74Schristos 15275fd0b74Schristos /* Non-boolean attribute numbers are offset by this much. */ 15375fd0b74Schristos 15475fd0b74Schristos #define CGEN_ATTR_NBOOL_OFFSET 32 15575fd0b74Schristos 15675fd0b74Schristos /* Given a boolean attribute number, return its mask. */ 15775fd0b74Schristos 15875fd0b74Schristos #define CGEN_ATTR_MASK(attr) (1 << (attr)) 15975fd0b74Schristos 16075fd0b74Schristos /* Return the value of boolean attribute ATTR in ATTRS. */ 16175fd0b74Schristos 16275fd0b74Schristos #define CGEN_BOOL_ATTR(attrs, attr) ((CGEN_ATTR_MASK (attr) & (attrs)) != 0) 16375fd0b74Schristos 16475fd0b74Schristos /* Return value of attribute ATTR in ATTR_TABLE for OBJ. 16575fd0b74Schristos OBJ is a pointer to the entity that has the attributes 16675fd0b74Schristos (??? not used at present but is reserved for future purposes - eventually 16775fd0b74Schristos the goal is to allow recording attributes in source form and computing 16875fd0b74Schristos them lazily at runtime, not sure of the details yet). */ 16975fd0b74Schristos 17075fd0b74Schristos #define CGEN_ATTR_VALUE(obj, attr_table, attr) \ 17175fd0b74Schristos ((unsigned int) (attr) < CGEN_ATTR_NBOOL_OFFSET \ 17275fd0b74Schristos ? ((CGEN_ATTR_BOOLS (attr_table) & CGEN_ATTR_MASK (attr)) != 0) \ 17375fd0b74Schristos : ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].nonbitset)) 17475fd0b74Schristos #define CGEN_BITSET_ATTR_VALUE(obj, attr_table, attr) \ 17575fd0b74Schristos ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].bitset) 17675fd0b74Schristos 17775fd0b74Schristos /* Attribute name/value tables. 17875fd0b74Schristos These are used to assist parsing of descriptions at run-time. */ 17975fd0b74Schristos 18075fd0b74Schristos typedef struct 18175fd0b74Schristos { 18275fd0b74Schristos const char * name; 18375fd0b74Schristos unsigned value; 18475fd0b74Schristos } CGEN_ATTR_ENTRY; 18575fd0b74Schristos 18675fd0b74Schristos /* For each domain (ifld,hw,operand,insn), list of attributes. */ 18775fd0b74Schristos 18875fd0b74Schristos typedef struct 18975fd0b74Schristos { 19075fd0b74Schristos const char * name; 19175fd0b74Schristos const CGEN_ATTR_ENTRY * dfault; 19275fd0b74Schristos const CGEN_ATTR_ENTRY * vals; 19375fd0b74Schristos } CGEN_ATTR_TABLE; 19475fd0b74Schristos 19575fd0b74Schristos /* Instruction set variants. */ 19675fd0b74Schristos 19775fd0b74Schristos typedef struct { 19875fd0b74Schristos const char *name; 19975fd0b74Schristos 20075fd0b74Schristos /* Default instruction size (in bits). 20175fd0b74Schristos This is used by the assembler when it encounters an unknown insn. */ 20275fd0b74Schristos unsigned int default_insn_bitsize; 20375fd0b74Schristos 20475fd0b74Schristos /* Base instruction size (in bits). 20575fd0b74Schristos For non-LIW cpus this is generally the length of the smallest insn. 20675fd0b74Schristos For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 20775fd0b74Schristos unsigned int base_insn_bitsize; 20875fd0b74Schristos 20975fd0b74Schristos /* Minimum/maximum instruction size (in bits). */ 21075fd0b74Schristos unsigned int min_insn_bitsize; 21175fd0b74Schristos unsigned int max_insn_bitsize; 21275fd0b74Schristos } CGEN_ISA; 21375fd0b74Schristos 21475fd0b74Schristos /* Machine variants. */ 21575fd0b74Schristos 21675fd0b74Schristos typedef struct { 21775fd0b74Schristos const char *name; 21875fd0b74Schristos /* The argument to bfd_arch_info->scan. */ 21975fd0b74Schristos const char *bfd_name; 22075fd0b74Schristos /* one of enum mach_attr */ 22175fd0b74Schristos int num; 22275fd0b74Schristos /* parameter from mach->cpu */ 22375fd0b74Schristos unsigned int insn_chunk_bitsize; 22475fd0b74Schristos } CGEN_MACH; 22575fd0b74Schristos 22675fd0b74Schristos /* Parse result (also extraction result). 22775fd0b74Schristos 22875fd0b74Schristos The result of parsing an insn is stored here. 22975fd0b74Schristos To generate the actual insn, this is passed to the insert handler. 23075fd0b74Schristos When printing an insn, the result of extraction is stored here. 23175fd0b74Schristos To print the insn, this is passed to the print handler. 23275fd0b74Schristos 23375fd0b74Schristos It is machine generated so we don't define it here, 23475fd0b74Schristos but we do need a forward decl for the handler fns. 23575fd0b74Schristos 23675fd0b74Schristos There is one member for each possible field in the insn. 23775fd0b74Schristos The type depends on the field. 23875fd0b74Schristos Also recorded here is the computed length of the insn for architectures 23975fd0b74Schristos where it varies. 24075fd0b74Schristos */ 24175fd0b74Schristos 24275fd0b74Schristos typedef struct cgen_fields CGEN_FIELDS; 24375fd0b74Schristos 24475fd0b74Schristos /* Total length of the insn, as recorded in the `fields' struct. */ 24575fd0b74Schristos /* ??? The field insert handler has lots of opportunities for optimization 24675fd0b74Schristos if it ever gets inlined. On architectures where insns all have the same 24775fd0b74Schristos size, may wish to detect that and make this macro a constant - to allow 24875fd0b74Schristos further optimizations. */ 24975fd0b74Schristos 25075fd0b74Schristos #define CGEN_FIELDS_BITSIZE(fields) ((fields)->length) 25175fd0b74Schristos 25275fd0b74Schristos /* Extraction support for variable length insn sets. */ 25375fd0b74Schristos 25475fd0b74Schristos /* When disassembling we don't know the number of bytes to read at the start. 25575fd0b74Schristos So the first CGEN_BASE_INSN_SIZE bytes are read at the start and the rest 25675fd0b74Schristos are read when needed. This struct controls this. It is basically the 25775fd0b74Schristos disassemble_info stuff, except that we provide a cache for values already 25875fd0b74Schristos read (since bytes can typically be read several times to fetch multiple 25975fd0b74Schristos operands that may be in them), and that extraction of fields is needed 26075fd0b74Schristos in contexts other than disassembly. */ 26175fd0b74Schristos 26275fd0b74Schristos typedef struct { 26375fd0b74Schristos /* A pointer to the disassemble_info struct. 26475fd0b74Schristos We don't require dis-asm.h so we use void * for the type here. 26575fd0b74Schristos If NULL, BYTES is full of valid data (VALID == -1). */ 26675fd0b74Schristos void *dis_info; 26775fd0b74Schristos /* Points to a working buffer of sufficient size. */ 26875fd0b74Schristos unsigned char *insn_bytes; 26975fd0b74Schristos /* Mask of bytes that are valid in INSN_BYTES. */ 27075fd0b74Schristos unsigned int valid; 27175fd0b74Schristos } CGEN_EXTRACT_INFO; 27275fd0b74Schristos 27375fd0b74Schristos /* Associated with each insn or expression is a set of "handlers" for 27475fd0b74Schristos performing operations like parsing, printing, etc. These require a bfd_vma 27575fd0b74Schristos value to be passed around but we don't want all applications to need bfd.h. 27675fd0b74Schristos So this stuff is only provided if bfd.h has been included. */ 27775fd0b74Schristos 27875fd0b74Schristos /* Parse handler. 27975fd0b74Schristos CD is a cpu table descriptor. 28075fd0b74Schristos INSN is a pointer to a struct describing the insn being parsed. 28175fd0b74Schristos STRP is a pointer to a pointer to the text being parsed. 28275fd0b74Schristos FIELDS is a pointer to a cgen_fields struct in which the results are placed. 28375fd0b74Schristos If the expression is successfully parsed, *STRP is updated. 28475fd0b74Schristos If not it is left alone. 28575fd0b74Schristos The result is NULL if success or an error message. */ 28675fd0b74Schristos typedef const char * (cgen_parse_fn) 28775fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 28875fd0b74Schristos const char **strp_, CGEN_FIELDS *fields_); 28975fd0b74Schristos 29075fd0b74Schristos /* Insert handler. 29175fd0b74Schristos CD is a cpu table descriptor. 29275fd0b74Schristos INSN is a pointer to a struct describing the insn being parsed. 29375fd0b74Schristos FIELDS is a pointer to a cgen_fields struct from which the values 29475fd0b74Schristos are fetched. 29575fd0b74Schristos INSNP is a pointer to a buffer in which to place the insn. 29675fd0b74Schristos PC is the pc value of the insn. 29775fd0b74Schristos The result is an error message or NULL if success. */ 29875fd0b74Schristos 29975fd0b74Schristos #ifdef __BFD_H_SEEN__ 30075fd0b74Schristos typedef const char * (cgen_insert_fn) 30175fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 30275fd0b74Schristos CGEN_FIELDS *fields_, CGEN_INSN_BYTES_PTR insnp_, 30375fd0b74Schristos bfd_vma pc_); 30475fd0b74Schristos #else 30575fd0b74Schristos typedef const char * (cgen_insert_fn) (); 30675fd0b74Schristos #endif 30775fd0b74Schristos 30875fd0b74Schristos /* Extract handler. 30975fd0b74Schristos CD is a cpu table descriptor. 31075fd0b74Schristos INSN is a pointer to a struct describing the insn being parsed. 31175fd0b74Schristos The second argument is a pointer to a struct controlling extraction 31275fd0b74Schristos (only used for variable length insns). 31375fd0b74Schristos EX_INFO is a pointer to a struct for controlling reading of further 31475fd0b74Schristos bytes for the insn. 31575fd0b74Schristos BASE_INSN is the first CGEN_BASE_INSN_SIZE bytes (host order). 31675fd0b74Schristos FIELDS is a pointer to a cgen_fields struct in which the results are placed. 31775fd0b74Schristos PC is the pc value of the insn. 31875fd0b74Schristos The result is the length of the insn in bits or zero if not recognized. */ 31975fd0b74Schristos 32075fd0b74Schristos #ifdef __BFD_H_SEEN__ 32175fd0b74Schristos typedef int (cgen_extract_fn) 32275fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 32375fd0b74Schristos CGEN_EXTRACT_INFO *ex_info_, CGEN_INSN_INT base_insn_, 32475fd0b74Schristos CGEN_FIELDS *fields_, bfd_vma pc_); 32575fd0b74Schristos #else 32675fd0b74Schristos typedef int (cgen_extract_fn) (); 32775fd0b74Schristos #endif 32875fd0b74Schristos 32975fd0b74Schristos /* Print handler. 33075fd0b74Schristos CD is a cpu table descriptor. 33175fd0b74Schristos INFO is a pointer to the disassembly info. 33275fd0b74Schristos Eg: disassemble_info. It's defined as `PTR' so this file can be included 33375fd0b74Schristos without dis-asm.h. 33475fd0b74Schristos INSN is a pointer to a struct describing the insn being printed. 33575fd0b74Schristos FIELDS is a pointer to a cgen_fields struct. 33675fd0b74Schristos PC is the pc value of the insn. 33775fd0b74Schristos LEN is the length of the insn, in bits. */ 33875fd0b74Schristos 33975fd0b74Schristos #ifdef __BFD_H_SEEN__ 34075fd0b74Schristos typedef void (cgen_print_fn) 34175fd0b74Schristos (CGEN_CPU_DESC, void * info_, const CGEN_INSN *insn_, 34275fd0b74Schristos CGEN_FIELDS *fields_, bfd_vma pc_, int len_); 34375fd0b74Schristos #else 34475fd0b74Schristos typedef void (cgen_print_fn) (); 34575fd0b74Schristos #endif 34675fd0b74Schristos 34775fd0b74Schristos /* Parse/insert/extract/print handlers. 34875fd0b74Schristos 34975fd0b74Schristos Indices into the handler tables. 35075fd0b74Schristos We could use pointers here instead, but 90% of them are generally identical 35175fd0b74Schristos and that's a lot of redundant data. Making these unsigned char indices 35275fd0b74Schristos into tables of pointers saves a bit of space. 35375fd0b74Schristos Using indices also keeps assembler code out of the disassembler and 35475fd0b74Schristos vice versa. */ 35575fd0b74Schristos 35675fd0b74Schristos struct cgen_opcode_handler 35775fd0b74Schristos { 35875fd0b74Schristos unsigned char parse, insert, extract, print; 35975fd0b74Schristos }; 36075fd0b74Schristos 36175fd0b74Schristos /* Assembler interface. 36275fd0b74Schristos 36375fd0b74Schristos The interface to the assembler is intended to be clean in the sense that 36475fd0b74Schristos libopcodes.a is a standalone entity and could be used with any assembler. 36575fd0b74Schristos Not that one would necessarily want to do that but rather that it helps 36675fd0b74Schristos keep a clean interface. The interface will obviously be slanted towards 36775fd0b74Schristos GAS, but at least it's a start. 36875fd0b74Schristos ??? Note that one possible user of the assembler besides GAS is GDB. 36975fd0b74Schristos 37075fd0b74Schristos Parsing is controlled by the assembler which calls 37175fd0b74Schristos CGEN_SYM (assemble_insn). If it can parse and build the entire insn 37275fd0b74Schristos it doesn't call back to the assembler. If it needs/wants to call back 37375fd0b74Schristos to the assembler, cgen_parse_operand_fn is called which can either 37475fd0b74Schristos 37575fd0b74Schristos - return a number to be inserted in the insn 37675fd0b74Schristos - return a "register" value to be inserted 37775fd0b74Schristos (the register might not be a register per pe) 37875fd0b74Schristos - queue the argument and return a marker saying the expression has been 37975fd0b74Schristos queued (eg: a fix-up) 38075fd0b74Schristos - return an error message indicating the expression wasn't recognizable 38175fd0b74Schristos 38275fd0b74Schristos The result is an error message or NULL for success. 38375fd0b74Schristos The parsed value is stored in the bfd_vma *. */ 38475fd0b74Schristos 38575fd0b74Schristos /* Values for indicating what the caller wants. */ 38675fd0b74Schristos 38775fd0b74Schristos enum cgen_parse_operand_type 38875fd0b74Schristos { 38975fd0b74Schristos CGEN_PARSE_OPERAND_INIT, 39075fd0b74Schristos CGEN_PARSE_OPERAND_INTEGER, 39175fd0b74Schristos CGEN_PARSE_OPERAND_ADDRESS, 39275fd0b74Schristos CGEN_PARSE_OPERAND_SYMBOLIC 39375fd0b74Schristos }; 39475fd0b74Schristos 39575fd0b74Schristos /* Values for indicating what was parsed. */ 39675fd0b74Schristos 39775fd0b74Schristos enum cgen_parse_operand_result 39875fd0b74Schristos { 39975fd0b74Schristos CGEN_PARSE_OPERAND_RESULT_NUMBER, 40075fd0b74Schristos CGEN_PARSE_OPERAND_RESULT_REGISTER, 40175fd0b74Schristos CGEN_PARSE_OPERAND_RESULT_QUEUED, 40275fd0b74Schristos CGEN_PARSE_OPERAND_RESULT_ERROR 40375fd0b74Schristos }; 40475fd0b74Schristos 40575fd0b74Schristos #ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 40675fd0b74Schristos typedef const char * (cgen_parse_operand_fn) 40775fd0b74Schristos (CGEN_CPU_DESC, 40875fd0b74Schristos enum cgen_parse_operand_type, const char **, int, int, 40975fd0b74Schristos enum cgen_parse_operand_result *, bfd_vma *); 41075fd0b74Schristos #else 41175fd0b74Schristos typedef const char * (cgen_parse_operand_fn) (); 41275fd0b74Schristos #endif 41375fd0b74Schristos 41475fd0b74Schristos /* Set the cgen_parse_operand_fn callback. */ 41575fd0b74Schristos 41675fd0b74Schristos extern void cgen_set_parse_operand_fn 41775fd0b74Schristos (CGEN_CPU_DESC, cgen_parse_operand_fn); 41875fd0b74Schristos 41975fd0b74Schristos /* Called before trying to match a table entry with the insn. */ 42075fd0b74Schristos 42175fd0b74Schristos extern void cgen_init_parse_operand (CGEN_CPU_DESC); 42275fd0b74Schristos 42375fd0b74Schristos /* Operand values (keywords, integers, symbols, etc.) */ 42475fd0b74Schristos 42575fd0b74Schristos /* Types of assembler elements. */ 42675fd0b74Schristos 42775fd0b74Schristos enum cgen_asm_type 42875fd0b74Schristos { 42975fd0b74Schristos CGEN_ASM_NONE, CGEN_ASM_KEYWORD, CGEN_ASM_MAX 43075fd0b74Schristos }; 43175fd0b74Schristos 43275fd0b74Schristos #ifndef CGEN_ARCH 43375fd0b74Schristos enum cgen_hw_type { CGEN_HW_MAX }; 43475fd0b74Schristos #endif 43575fd0b74Schristos 43675fd0b74Schristos /* List of hardware elements. */ 43775fd0b74Schristos 43875fd0b74Schristos typedef struct 43975fd0b74Schristos { 44075fd0b74Schristos char *name; 44175fd0b74Schristos enum cgen_hw_type type; 44275fd0b74Schristos /* There is currently no example where both index specs and value specs 44375fd0b74Schristos are required, so for now both are clumped under "asm_data". */ 44475fd0b74Schristos enum cgen_asm_type asm_type; 44575fd0b74Schristos void *asm_data; 44675fd0b74Schristos #ifndef CGEN_HW_NBOOL_ATTRS 44775fd0b74Schristos #define CGEN_HW_NBOOL_ATTRS 1 44875fd0b74Schristos #endif 44975fd0b74Schristos CGEN_ATTR_TYPE (CGEN_HW_NBOOL_ATTRS) attrs; 45075fd0b74Schristos #define CGEN_HW_ATTRS(hw) (&(hw)->attrs) 45175fd0b74Schristos } CGEN_HW_ENTRY; 45275fd0b74Schristos 45375fd0b74Schristos /* Return value of attribute ATTR in HW. */ 45475fd0b74Schristos 45575fd0b74Schristos #define CGEN_HW_ATTR_VALUE(hw, attr) \ 45675fd0b74Schristos CGEN_ATTR_VALUE ((hw), CGEN_HW_ATTRS (hw), (attr)) 45775fd0b74Schristos 45875fd0b74Schristos /* Table of hardware elements for selected mach, computed at runtime. 45975fd0b74Schristos enum cgen_hw_type is an index into this table (specifically `entries'). */ 46075fd0b74Schristos 46175fd0b74Schristos typedef struct { 46275fd0b74Schristos /* Pointer to null terminated table of all compiled in entries. */ 46375fd0b74Schristos const CGEN_HW_ENTRY *init_entries; 46475fd0b74Schristos unsigned int entry_size; /* since the attribute member is variable sized */ 46575fd0b74Schristos /* Array of all entries, initial and run-time added. */ 46675fd0b74Schristos const CGEN_HW_ENTRY **entries; 46775fd0b74Schristos /* Number of elements in `entries'. */ 46875fd0b74Schristos unsigned int num_entries; 46975fd0b74Schristos /* For now, xrealloc is called each time a new entry is added at runtime. 47075fd0b74Schristos ??? May wish to keep track of some slop to reduce the number of calls to 47175fd0b74Schristos xrealloc, except that there's unlikely to be many and not expected to be 47275fd0b74Schristos in speed critical code. */ 47375fd0b74Schristos } CGEN_HW_TABLE; 47475fd0b74Schristos 47575fd0b74Schristos extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_name 47675fd0b74Schristos (CGEN_CPU_DESC, const char *); 47775fd0b74Schristos extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_num 47875fd0b74Schristos (CGEN_CPU_DESC, unsigned int); 47975fd0b74Schristos 48075fd0b74Schristos /* This struct is used to describe things like register names, etc. */ 48175fd0b74Schristos 48275fd0b74Schristos typedef struct cgen_keyword_entry 48375fd0b74Schristos { 48475fd0b74Schristos /* Name (as in register name). */ 48575fd0b74Schristos char * name; 48675fd0b74Schristos 48775fd0b74Schristos /* Value (as in register number). 48875fd0b74Schristos The value cannot be -1 as that is used to indicate "not found". 48975fd0b74Schristos IDEA: Have "FUNCTION" attribute? [function is called to fetch value]. */ 49075fd0b74Schristos int value; 49175fd0b74Schristos 49275fd0b74Schristos /* Attributes. 49375fd0b74Schristos This should, but technically needn't, appear last. It is a variable sized 49475fd0b74Schristos array in that one architecture may have 1 nonbool attribute and another 49575fd0b74Schristos may have more. Having this last means the non-architecture specific code 49675fd0b74Schristos needn't care. The goal is to eventually record 49775fd0b74Schristos attributes in their raw form, evaluate them at run-time, and cache the 49875fd0b74Schristos values, so this worry will go away anyway. */ 49975fd0b74Schristos /* ??? Moving this last should be done by treating keywords like insn lists 50075fd0b74Schristos and moving the `next' fields into a CGEN_KEYWORD_LIST struct. */ 50175fd0b74Schristos /* FIXME: Not used yet. */ 50275fd0b74Schristos #ifndef CGEN_KEYWORD_NBOOL_ATTRS 50375fd0b74Schristos #define CGEN_KEYWORD_NBOOL_ATTRS 1 50475fd0b74Schristos #endif 50575fd0b74Schristos CGEN_ATTR_TYPE (CGEN_KEYWORD_NBOOL_ATTRS) attrs; 50675fd0b74Schristos 50775fd0b74Schristos /* ??? Putting these here means compiled in entries can't be const. 50875fd0b74Schristos Not a really big deal, but something to consider. */ 50975fd0b74Schristos /* Next name hash table entry. */ 51075fd0b74Schristos struct cgen_keyword_entry *next_name; 51175fd0b74Schristos /* Next value hash table entry. */ 51275fd0b74Schristos struct cgen_keyword_entry *next_value; 51375fd0b74Schristos } CGEN_KEYWORD_ENTRY; 51475fd0b74Schristos 51575fd0b74Schristos /* Top level struct for describing a set of related keywords 51675fd0b74Schristos (e.g. register names). 51775fd0b74Schristos 51875fd0b74Schristos This struct supports run-time entry of new values, and hashed lookups. */ 51975fd0b74Schristos 52075fd0b74Schristos typedef struct cgen_keyword 52175fd0b74Schristos { 52275fd0b74Schristos /* Pointer to initial [compiled in] values. */ 52375fd0b74Schristos CGEN_KEYWORD_ENTRY *init_entries; 52475fd0b74Schristos 52575fd0b74Schristos /* Number of entries in `init_entries'. */ 52675fd0b74Schristos unsigned int num_init_entries; 52775fd0b74Schristos 52875fd0b74Schristos /* Hash table used for name lookup. */ 52975fd0b74Schristos CGEN_KEYWORD_ENTRY **name_hash_table; 53075fd0b74Schristos 53175fd0b74Schristos /* Hash table used for value lookup. */ 53275fd0b74Schristos CGEN_KEYWORD_ENTRY **value_hash_table; 53375fd0b74Schristos 53475fd0b74Schristos /* Number of entries in the hash_tables. */ 53575fd0b74Schristos unsigned int hash_table_size; 53675fd0b74Schristos 53775fd0b74Schristos /* Pointer to null keyword "" entry if present. */ 53875fd0b74Schristos const CGEN_KEYWORD_ENTRY *null_entry; 53975fd0b74Schristos 54075fd0b74Schristos /* String containing non-alphanumeric characters used 54175fd0b74Schristos in keywords. 54275fd0b74Schristos At present, the highest number of entries used is 1. */ 54375fd0b74Schristos char nonalpha_chars[8]; 54475fd0b74Schristos } CGEN_KEYWORD; 54575fd0b74Schristos 54675fd0b74Schristos /* Structure used for searching. */ 54775fd0b74Schristos 54875fd0b74Schristos typedef struct 54975fd0b74Schristos { 55075fd0b74Schristos /* Table being searched. */ 55175fd0b74Schristos const CGEN_KEYWORD *table; 55275fd0b74Schristos 55375fd0b74Schristos /* Specification of what is being searched for. */ 55475fd0b74Schristos const char *spec; 55575fd0b74Schristos 55675fd0b74Schristos /* Current index in hash table. */ 55775fd0b74Schristos unsigned int current_hash; 55875fd0b74Schristos 55975fd0b74Schristos /* Current element in current hash chain. */ 56075fd0b74Schristos CGEN_KEYWORD_ENTRY *current_entry; 56175fd0b74Schristos } CGEN_KEYWORD_SEARCH; 56275fd0b74Schristos 56375fd0b74Schristos /* Lookup a keyword from its name. */ 56475fd0b74Schristos 56575fd0b74Schristos const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_name 56675fd0b74Schristos (CGEN_KEYWORD *, const char *); 56775fd0b74Schristos 56875fd0b74Schristos /* Lookup a keyword from its value. */ 56975fd0b74Schristos 57075fd0b74Schristos const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_value 57175fd0b74Schristos (CGEN_KEYWORD *, int); 57275fd0b74Schristos 57375fd0b74Schristos /* Add a keyword. */ 57475fd0b74Schristos 57575fd0b74Schristos void cgen_keyword_add (CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *); 57675fd0b74Schristos 57775fd0b74Schristos /* Keyword searching. 57875fd0b74Schristos This can be used to retrieve every keyword, or a subset. */ 57975fd0b74Schristos 58075fd0b74Schristos CGEN_KEYWORD_SEARCH cgen_keyword_search_init 58175fd0b74Schristos (CGEN_KEYWORD *, const char *); 58275fd0b74Schristos const CGEN_KEYWORD_ENTRY *cgen_keyword_search_next 58375fd0b74Schristos (CGEN_KEYWORD_SEARCH *); 58475fd0b74Schristos 58575fd0b74Schristos /* Operand value support routines. */ 58675fd0b74Schristos 58775fd0b74Schristos extern const char *cgen_parse_keyword 58875fd0b74Schristos (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); 58975fd0b74Schristos #ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 59075fd0b74Schristos extern const char *cgen_parse_signed_integer 59175fd0b74Schristos (CGEN_CPU_DESC, const char **, int, long *); 59275fd0b74Schristos extern const char *cgen_parse_unsigned_integer 59375fd0b74Schristos (CGEN_CPU_DESC, const char **, int, unsigned long *); 59475fd0b74Schristos extern const char *cgen_parse_address 59575fd0b74Schristos (CGEN_CPU_DESC, const char **, int, int, 59675fd0b74Schristos enum cgen_parse_operand_result *, bfd_vma *); 59775fd0b74Schristos extern const char *cgen_validate_signed_integer 59875fd0b74Schristos (long, long, long); 59975fd0b74Schristos extern const char *cgen_validate_unsigned_integer 60075fd0b74Schristos (unsigned long, unsigned long, unsigned long); 60175fd0b74Schristos #endif 60275fd0b74Schristos 60375fd0b74Schristos /* Operand modes. */ 60475fd0b74Schristos 60575fd0b74Schristos /* ??? This duplicates the values in arch.h. Revisit. 60675fd0b74Schristos These however need the CGEN_ prefix [as does everything in this file]. */ 60775fd0b74Schristos /* ??? Targets may need to add their own modes so we may wish to move this 60875fd0b74Schristos to <arch>-opc.h, or add a hook. */ 60975fd0b74Schristos 61075fd0b74Schristos enum cgen_mode { 61175fd0b74Schristos CGEN_MODE_VOID, /* ??? rename simulator's VM to VOID? */ 61275fd0b74Schristos CGEN_MODE_BI, CGEN_MODE_QI, CGEN_MODE_HI, CGEN_MODE_SI, CGEN_MODE_DI, 61375fd0b74Schristos CGEN_MODE_UBI, CGEN_MODE_UQI, CGEN_MODE_UHI, CGEN_MODE_USI, CGEN_MODE_UDI, 61475fd0b74Schristos CGEN_MODE_SF, CGEN_MODE_DF, CGEN_MODE_XF, CGEN_MODE_TF, 61575fd0b74Schristos CGEN_MODE_TARGET_MAX, 61675fd0b74Schristos CGEN_MODE_INT, CGEN_MODE_UINT, 61775fd0b74Schristos CGEN_MODE_MAX 61875fd0b74Schristos }; 61975fd0b74Schristos 62075fd0b74Schristos /* FIXME: Until simulator is updated. */ 62175fd0b74Schristos 62275fd0b74Schristos #define CGEN_MODE_VM CGEN_MODE_VOID 62375fd0b74Schristos 62475fd0b74Schristos /* Operands. */ 62575fd0b74Schristos 62675fd0b74Schristos #ifndef CGEN_ARCH 62775fd0b74Schristos enum cgen_operand_type { CGEN_OPERAND_MAX }; 62875fd0b74Schristos #endif 62975fd0b74Schristos 63075fd0b74Schristos /* "nil" indicator for the operand instance table */ 63175fd0b74Schristos #define CGEN_OPERAND_NIL CGEN_OPERAND_MAX 63275fd0b74Schristos 63375fd0b74Schristos /* A tree of these structs represents the multi-ifield 63475fd0b74Schristos structure of an operand's hw-index value, if it exists. */ 63575fd0b74Schristos 63675fd0b74Schristos struct cgen_ifld; 63775fd0b74Schristos 63875fd0b74Schristos typedef struct cgen_maybe_multi_ifield 63975fd0b74Schristos { 64075fd0b74Schristos int count; /* 0: indexed by single cgen_ifld (possibly null: dead entry); 64175fd0b74Schristos n: indexed by array of more cgen_maybe_multi_ifields. */ 64275fd0b74Schristos union 64375fd0b74Schristos { 64475fd0b74Schristos const void *p; 64575fd0b74Schristos const struct cgen_maybe_multi_ifield * multi; 64675fd0b74Schristos const struct cgen_ifld * leaf; 64775fd0b74Schristos } val; 64875fd0b74Schristos } 64975fd0b74Schristos CGEN_MAYBE_MULTI_IFLD; 65075fd0b74Schristos 65175fd0b74Schristos /* This struct defines each entry in the operand table. */ 65275fd0b74Schristos 65375fd0b74Schristos typedef struct 65475fd0b74Schristos { 65575fd0b74Schristos /* Name as it appears in the syntax string. */ 65675fd0b74Schristos char *name; 65775fd0b74Schristos 65875fd0b74Schristos /* Operand type. */ 65975fd0b74Schristos enum cgen_operand_type type; 66075fd0b74Schristos 66175fd0b74Schristos /* The hardware element associated with this operand. */ 66275fd0b74Schristos enum cgen_hw_type hw_type; 66375fd0b74Schristos 66475fd0b74Schristos /* FIXME: We don't yet record ifield definitions, which we should. 66575fd0b74Schristos When we do it might make sense to delete start/length (since they will 66675fd0b74Schristos be duplicated in the ifield's definition) and replace them with a 66775fd0b74Schristos pointer to the ifield entry. */ 66875fd0b74Schristos 66975fd0b74Schristos /* Bit position. 67075fd0b74Schristos This is just a hint, and may be unused in more complex operands. 67175fd0b74Schristos May be unused for a modifier. */ 67275fd0b74Schristos unsigned char start; 67375fd0b74Schristos 67475fd0b74Schristos /* The number of bits in the operand. 67575fd0b74Schristos This is just a hint, and may be unused in more complex operands. 67675fd0b74Schristos May be unused for a modifier. */ 67775fd0b74Schristos unsigned char length; 67875fd0b74Schristos 67975fd0b74Schristos /* The (possibly-multi) ifield used as an index for this operand, if it 68075fd0b74Schristos is indexed by a field at all. This substitutes / extends the start and 68175fd0b74Schristos length fields above, but unsure at this time whether they are used 68275fd0b74Schristos anywhere. */ 68375fd0b74Schristos CGEN_MAYBE_MULTI_IFLD index_fields; 68475fd0b74Schristos #if 0 /* ??? Interesting idea but relocs tend to get too complicated, 68575fd0b74Schristos and ABI dependent, for simple table lookups to work. */ 68675fd0b74Schristos /* Ideally this would be the internal (external?) reloc type. */ 68775fd0b74Schristos int reloc_type; 68875fd0b74Schristos #endif 68975fd0b74Schristos 69075fd0b74Schristos /* Attributes. 69175fd0b74Schristos This should, but technically needn't, appear last. It is a variable sized 69275fd0b74Schristos array in that one architecture may have 1 nonbool attribute and another 69375fd0b74Schristos may have more. Having this last means the non-architecture specific code 69475fd0b74Schristos needn't care, now or tomorrow. The goal is to eventually record 69575fd0b74Schristos attributes in their raw form, evaluate them at run-time, and cache the 69675fd0b74Schristos values, so this worry will go away anyway. */ 69775fd0b74Schristos #ifndef CGEN_OPERAND_NBOOL_ATTRS 69875fd0b74Schristos #define CGEN_OPERAND_NBOOL_ATTRS 1 69975fd0b74Schristos #endif 70075fd0b74Schristos CGEN_ATTR_TYPE (CGEN_OPERAND_NBOOL_ATTRS) attrs; 70175fd0b74Schristos #define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs) 70275fd0b74Schristos } CGEN_OPERAND; 70375fd0b74Schristos 70475fd0b74Schristos /* Return value of attribute ATTR in OPERAND. */ 70575fd0b74Schristos 70675fd0b74Schristos #define CGEN_OPERAND_ATTR_VALUE(operand, attr) \ 70775fd0b74Schristos CGEN_ATTR_VALUE ((operand), CGEN_OPERAND_ATTRS (operand), (attr)) 70875fd0b74Schristos 70975fd0b74Schristos /* Table of operands for selected mach/isa, computed at runtime. 71075fd0b74Schristos enum cgen_operand_type is an index into this table (specifically 71175fd0b74Schristos `entries'). */ 71275fd0b74Schristos 71375fd0b74Schristos typedef struct { 71475fd0b74Schristos /* Pointer to null terminated table of all compiled in entries. */ 71575fd0b74Schristos const CGEN_OPERAND *init_entries; 71675fd0b74Schristos unsigned int entry_size; /* since the attribute member is variable sized */ 71775fd0b74Schristos /* Array of all entries, initial and run-time added. */ 71875fd0b74Schristos const CGEN_OPERAND **entries; 71975fd0b74Schristos /* Number of elements in `entries'. */ 72075fd0b74Schristos unsigned int num_entries; 72175fd0b74Schristos /* For now, xrealloc is called each time a new entry is added at runtime. 72275fd0b74Schristos ??? May wish to keep track of some slop to reduce the number of calls to 72375fd0b74Schristos xrealloc, except that there's unlikely to be many and not expected to be 72475fd0b74Schristos in speed critical code. */ 72575fd0b74Schristos } CGEN_OPERAND_TABLE; 72675fd0b74Schristos 72775fd0b74Schristos extern const CGEN_OPERAND * cgen_operand_lookup_by_name 72875fd0b74Schristos (CGEN_CPU_DESC, const char *); 72975fd0b74Schristos extern const CGEN_OPERAND * cgen_operand_lookup_by_num 73075fd0b74Schristos (CGEN_CPU_DESC, int); 73175fd0b74Schristos 73275fd0b74Schristos /* Instruction operand instances. 73375fd0b74Schristos 73475fd0b74Schristos For each instruction, a list of the hardware elements that are read and 73575fd0b74Schristos written are recorded. */ 73675fd0b74Schristos 73775fd0b74Schristos /* The type of the instance. */ 73875fd0b74Schristos 73975fd0b74Schristos enum cgen_opinst_type { 74075fd0b74Schristos /* End of table marker. */ 74175fd0b74Schristos CGEN_OPINST_END = 0, 74275fd0b74Schristos CGEN_OPINST_INPUT, CGEN_OPINST_OUTPUT 74375fd0b74Schristos }; 74475fd0b74Schristos 74575fd0b74Schristos typedef struct 74675fd0b74Schristos { 74775fd0b74Schristos /* Input or output indicator. */ 74875fd0b74Schristos enum cgen_opinst_type type; 74975fd0b74Schristos 75075fd0b74Schristos /* Name of operand. */ 75175fd0b74Schristos const char *name; 75275fd0b74Schristos 75375fd0b74Schristos /* The hardware element referenced. */ 75475fd0b74Schristos enum cgen_hw_type hw_type; 75575fd0b74Schristos 75675fd0b74Schristos /* The mode in which the operand is being used. */ 75775fd0b74Schristos enum cgen_mode mode; 75875fd0b74Schristos 75975fd0b74Schristos /* The operand table entry CGEN_OPERAND_NIL if there is none 76075fd0b74Schristos (i.e. an explicit hardware reference). */ 76175fd0b74Schristos enum cgen_operand_type op_type; 76275fd0b74Schristos 76375fd0b74Schristos /* If `operand' is "nil", the index (e.g. into array of registers). */ 76475fd0b74Schristos int index; 76575fd0b74Schristos 76675fd0b74Schristos /* Attributes. 76775fd0b74Schristos ??? This perhaps should be a real attribute struct but there's 76875fd0b74Schristos no current need, so we save a bit of space and just have a set of 76975fd0b74Schristos flags. The interface is such that this can easily be made attributes 77075fd0b74Schristos should it prove useful. */ 77175fd0b74Schristos unsigned int attrs; 77275fd0b74Schristos #define CGEN_OPINST_ATTRS(opinst) ((opinst)->attrs) 77375fd0b74Schristos /* Return value of attribute ATTR in OPINST. */ 77475fd0b74Schristos #define CGEN_OPINST_ATTR(opinst, attr) \ 77575fd0b74Schristos ((CGEN_OPINST_ATTRS (opinst) & (attr)) != 0) 77675fd0b74Schristos /* Operand is conditionally referenced (read/written). */ 77775fd0b74Schristos #define CGEN_OPINST_COND_REF 1 77875fd0b74Schristos } CGEN_OPINST; 77975fd0b74Schristos 78075fd0b74Schristos /* Syntax string. 78175fd0b74Schristos 78275fd0b74Schristos Each insn format and subexpression has one of these. 78375fd0b74Schristos 78475fd0b74Schristos The syntax "string" consists of characters (n > 0 && n < 128), and operand 78575fd0b74Schristos values (n >= 128), and is terminated by 0. Operand values are 128 + index 78675fd0b74Schristos into the operand table. The operand table doesn't exist in C, per se, as 78775fd0b74Schristos the data is recorded in the parse/insert/extract/print switch statements. */ 78875fd0b74Schristos 78975fd0b74Schristos /* This should be at least as large as necessary for any target. */ 79075fd0b74Schristos #define CGEN_MAX_SYNTAX_ELEMENTS 48 79175fd0b74Schristos 79275fd0b74Schristos /* A target may know its own precise maximum. Assert that it falls below 79375fd0b74Schristos the above limit. */ 79475fd0b74Schristos #ifdef CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 79575fd0b74Schristos #if CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS > CGEN_MAX_SYNTAX_ELEMENTS 79675fd0b74Schristos #error "CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS too high - enlarge CGEN_MAX_SYNTAX_ELEMENTS" 79775fd0b74Schristos #endif 79875fd0b74Schristos #endif 79975fd0b74Schristos 80075fd0b74Schristos typedef unsigned short CGEN_SYNTAX_CHAR_TYPE; 80175fd0b74Schristos 80275fd0b74Schristos typedef struct 80375fd0b74Schristos { 80475fd0b74Schristos CGEN_SYNTAX_CHAR_TYPE syntax[CGEN_MAX_SYNTAX_ELEMENTS]; 80575fd0b74Schristos } CGEN_SYNTAX; 80675fd0b74Schristos 80775fd0b74Schristos #define CGEN_SYNTAX_STRING(syn) (syn->syntax) 80875fd0b74Schristos #define CGEN_SYNTAX_CHAR_P(c) ((c) < 128) 80975fd0b74Schristos #define CGEN_SYNTAX_CHAR(c) ((unsigned char)c) 81075fd0b74Schristos #define CGEN_SYNTAX_FIELD(c) ((c) - 128) 81175fd0b74Schristos #define CGEN_SYNTAX_MAKE_FIELD(c) ((c) + 128) 81275fd0b74Schristos 81375fd0b74Schristos /* ??? I can't currently think of any case where the mnemonic doesn't come 81475fd0b74Schristos first [and if one ever doesn't building the hash tables will be tricky]. 81575fd0b74Schristos However, we treat mnemonics as just another operand of the instruction. 81675fd0b74Schristos A value of 1 means "this is where the mnemonic appears". 1 isn't 81775fd0b74Schristos special other than it's a non-printable ASCII char. */ 81875fd0b74Schristos 81975fd0b74Schristos #define CGEN_SYNTAX_MNEMONIC 1 82075fd0b74Schristos #define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == CGEN_SYNTAX_MNEMONIC) 82175fd0b74Schristos 82275fd0b74Schristos /* Instruction fields. 82375fd0b74Schristos 82475fd0b74Schristos ??? We currently don't allow adding fields at run-time. 82575fd0b74Schristos Easy to fix when needed. */ 82675fd0b74Schristos 82775fd0b74Schristos typedef struct cgen_ifld { 82875fd0b74Schristos /* Enum of ifield. */ 82975fd0b74Schristos int num; 83075fd0b74Schristos #define CGEN_IFLD_NUM(f) ((f)->num) 83175fd0b74Schristos 83275fd0b74Schristos /* Name of the field, distinguishes it from all other fields. */ 83375fd0b74Schristos const char *name; 83475fd0b74Schristos #define CGEN_IFLD_NAME(f) ((f)->name) 83575fd0b74Schristos 83675fd0b74Schristos /* Default offset, in bits, from the start of the insn to the word 83775fd0b74Schristos containing the field. */ 83875fd0b74Schristos int word_offset; 83975fd0b74Schristos #define CGEN_IFLD_WORD_OFFSET(f) ((f)->word_offset) 84075fd0b74Schristos 84175fd0b74Schristos /* Default length of the word containing the field. */ 84275fd0b74Schristos int word_size; 84375fd0b74Schristos #define CGEN_IFLD_WORD_SIZE(f) ((f)->word_size) 84475fd0b74Schristos 84575fd0b74Schristos /* Default starting bit number. 84675fd0b74Schristos Whether lsb=0 or msb=0 is determined by CGEN_INSN_LSB0_P. */ 84775fd0b74Schristos int start; 84875fd0b74Schristos #define CGEN_IFLD_START(f) ((f)->start) 84975fd0b74Schristos 85075fd0b74Schristos /* Length of the field, in bits. */ 85175fd0b74Schristos int length; 85275fd0b74Schristos #define CGEN_IFLD_LENGTH(f) ((f)->length) 85375fd0b74Schristos 85475fd0b74Schristos #ifndef CGEN_IFLD_NBOOL_ATTRS 85575fd0b74Schristos #define CGEN_IFLD_NBOOL_ATTRS 1 85675fd0b74Schristos #endif 85775fd0b74Schristos CGEN_ATTR_TYPE (CGEN_IFLD_NBOOL_ATTRS) attrs; 85875fd0b74Schristos #define CGEN_IFLD_ATTRS(f) (&(f)->attrs) 85975fd0b74Schristos } CGEN_IFLD; 86075fd0b74Schristos 86175fd0b74Schristos /* Return value of attribute ATTR in IFLD. */ 86275fd0b74Schristos #define CGEN_IFLD_ATTR_VALUE(ifld, attr) \ 86375fd0b74Schristos CGEN_ATTR_VALUE ((ifld), CGEN_IFLD_ATTRS (ifld), (attr)) 86475fd0b74Schristos 86575fd0b74Schristos /* Instruction data. */ 86675fd0b74Schristos 86775fd0b74Schristos /* Instruction formats. 86875fd0b74Schristos 86975fd0b74Schristos Instructions are grouped by format. Associated with an instruction is its 87075fd0b74Schristos format. Each insn's opcode table entry contains a format table entry. 87175fd0b74Schristos ??? There is usually very few formats compared with the number of insns, 87275fd0b74Schristos so one can reduce the size of the opcode table by recording the format table 87375fd0b74Schristos as a separate entity. Given that we currently don't, format table entries 87475fd0b74Schristos are also distinguished by their operands. This increases the size of the 87575fd0b74Schristos table, but reduces the number of tables. It's all minutiae anyway so it 87675fd0b74Schristos doesn't really matter [at this point in time]. 87775fd0b74Schristos 87875fd0b74Schristos ??? Support for variable length ISA's is wip. */ 87975fd0b74Schristos 88075fd0b74Schristos /* Accompanying each iformat description is a list of its fields. */ 88175fd0b74Schristos 88275fd0b74Schristos typedef struct { 88375fd0b74Schristos const CGEN_IFLD *ifld; 88475fd0b74Schristos #define CGEN_IFMT_IFLD_IFLD(ii) ((ii)->ifld) 88575fd0b74Schristos } CGEN_IFMT_IFLD; 88675fd0b74Schristos 88775fd0b74Schristos /* This should be at least as large as necessary for any target. */ 88875fd0b74Schristos #define CGEN_MAX_IFMT_OPERANDS 16 88975fd0b74Schristos 89075fd0b74Schristos /* A target may know its own precise maximum. Assert that it falls below 89175fd0b74Schristos the above limit. */ 89275fd0b74Schristos #ifdef CGEN_ACTUAL_MAX_IFMT_OPERANDS 89375fd0b74Schristos #if CGEN_ACTUAL_MAX_IFMT_OPERANDS > CGEN_MAX_IFMT_OPERANDS 89475fd0b74Schristos #error "CGEN_ACTUAL_MAX_IFMT_OPERANDS too high - enlarge CGEN_MAX_IFMT_OPERANDS" 89575fd0b74Schristos #endif 89675fd0b74Schristos #endif 89775fd0b74Schristos 89875fd0b74Schristos 89975fd0b74Schristos typedef struct 90075fd0b74Schristos { 90175fd0b74Schristos /* Length that MASK and VALUE have been calculated to 90275fd0b74Schristos [VALUE is recorded elsewhere]. 90375fd0b74Schristos Normally it is base_insn_bitsize. On [V]LIW architectures where the base 90475fd0b74Schristos insn size may be larger than the size of an insn, this field is less than 90575fd0b74Schristos base_insn_bitsize. */ 90675fd0b74Schristos unsigned char mask_length; 90775fd0b74Schristos #define CGEN_IFMT_MASK_LENGTH(ifmt) ((ifmt)->mask_length) 90875fd0b74Schristos 90975fd0b74Schristos /* Total length of instruction, in bits. */ 91075fd0b74Schristos unsigned char length; 91175fd0b74Schristos #define CGEN_IFMT_LENGTH(ifmt) ((ifmt)->length) 91275fd0b74Schristos 91375fd0b74Schristos /* Mask to apply to the first MASK_LENGTH bits. 91475fd0b74Schristos Each insn's value is stored with the insn. 91575fd0b74Schristos The first step in recognizing an insn for disassembly is 91675fd0b74Schristos (opcode & mask) == value. */ 91775fd0b74Schristos CGEN_INSN_INT mask; 91875fd0b74Schristos #define CGEN_IFMT_MASK(ifmt) ((ifmt)->mask) 91975fd0b74Schristos 92075fd0b74Schristos /* Instruction fields. 92175fd0b74Schristos +1 for trailing NULL. */ 92275fd0b74Schristos CGEN_IFMT_IFLD iflds[CGEN_MAX_IFMT_OPERANDS + 1]; 92375fd0b74Schristos #define CGEN_IFMT_IFLDS(ifmt) ((ifmt)->iflds) 92475fd0b74Schristos } CGEN_IFMT; 92575fd0b74Schristos 92675fd0b74Schristos /* Instruction values. */ 92775fd0b74Schristos 92875fd0b74Schristos typedef struct 92975fd0b74Schristos { 93075fd0b74Schristos /* The opcode portion of the base insn. */ 93175fd0b74Schristos CGEN_INSN_INT base_value; 93275fd0b74Schristos 93375fd0b74Schristos #ifdef CGEN_MAX_EXTRA_OPCODE_OPERANDS 93475fd0b74Schristos /* Extra opcode values beyond base_value. */ 93575fd0b74Schristos unsigned long ifield_values[CGEN_MAX_EXTRA_OPCODE_OPERANDS]; 93675fd0b74Schristos #endif 93775fd0b74Schristos } CGEN_IVALUE; 93875fd0b74Schristos 93975fd0b74Schristos /* Instruction opcode table. 94075fd0b74Schristos This contains the syntax and format data of an instruction. */ 94175fd0b74Schristos 94275fd0b74Schristos /* ??? Some ports already have an opcode table yet still need to use the rest 94375fd0b74Schristos of what cgen_insn has. Plus keeping the opcode data with the operand 94475fd0b74Schristos instance data can create a pretty big file. So we keep them separately. 94575fd0b74Schristos Not sure this is a good idea in the long run. */ 94675fd0b74Schristos 94775fd0b74Schristos typedef struct 94875fd0b74Schristos { 94975fd0b74Schristos /* Indices into parse/insert/extract/print handler tables. */ 95075fd0b74Schristos struct cgen_opcode_handler handlers; 95175fd0b74Schristos #define CGEN_OPCODE_HANDLERS(opc) (& (opc)->handlers) 95275fd0b74Schristos 95375fd0b74Schristos /* Syntax string. */ 95475fd0b74Schristos CGEN_SYNTAX syntax; 95575fd0b74Schristos #define CGEN_OPCODE_SYNTAX(opc) (& (opc)->syntax) 95675fd0b74Schristos 95775fd0b74Schristos /* Format entry. */ 95875fd0b74Schristos const CGEN_IFMT *format; 95975fd0b74Schristos #define CGEN_OPCODE_FORMAT(opc) ((opc)->format) 96075fd0b74Schristos #define CGEN_OPCODE_MASK_BITSIZE(opc) CGEN_IFMT_MASK_LENGTH (CGEN_OPCODE_FORMAT (opc)) 96175fd0b74Schristos #define CGEN_OPCODE_BITSIZE(opc) CGEN_IFMT_LENGTH (CGEN_OPCODE_FORMAT (opc)) 96275fd0b74Schristos #define CGEN_OPCODE_IFLDS(opc) CGEN_IFMT_IFLDS (CGEN_OPCODE_FORMAT (opc)) 96375fd0b74Schristos 96475fd0b74Schristos /* Instruction opcode value. */ 96575fd0b74Schristos CGEN_IVALUE value; 96675fd0b74Schristos #define CGEN_OPCODE_VALUE(opc) (& (opc)->value) 96775fd0b74Schristos #define CGEN_OPCODE_BASE_VALUE(opc) (CGEN_OPCODE_VALUE (opc)->base_value) 96875fd0b74Schristos #define CGEN_OPCODE_BASE_MASK(opc) CGEN_IFMT_MASK (CGEN_OPCODE_FORMAT (opc)) 96975fd0b74Schristos } CGEN_OPCODE; 97075fd0b74Schristos 97175fd0b74Schristos /* Instruction attributes. 97275fd0b74Schristos This is made a published type as applications can cache a pointer to 97375fd0b74Schristos the attributes for speed. */ 97475fd0b74Schristos 97575fd0b74Schristos #ifndef CGEN_INSN_NBOOL_ATTRS 97675fd0b74Schristos #define CGEN_INSN_NBOOL_ATTRS 1 97775fd0b74Schristos #endif 97875fd0b74Schristos typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE; 97975fd0b74Schristos 98075fd0b74Schristos /* Enum of architecture independent attributes. */ 98175fd0b74Schristos 98275fd0b74Schristos #ifndef CGEN_ARCH 98375fd0b74Schristos /* ??? Numbers here are recorded in two places. */ 98475fd0b74Schristos typedef enum cgen_insn_attr { 98575fd0b74Schristos CGEN_INSN_ALIAS = 0 98675fd0b74Schristos } CGEN_INSN_ATTR; 98775fd0b74Schristos #define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) ((attrs)->bool_ & (1 << CGEN_INSN_ALIAS)) 98875fd0b74Schristos #endif 98975fd0b74Schristos 99075fd0b74Schristos /* This struct defines each entry in the instruction table. */ 99175fd0b74Schristos 99275fd0b74Schristos typedef struct 99375fd0b74Schristos { 99475fd0b74Schristos /* Each real instruction is enumerated. */ 99575fd0b74Schristos /* ??? This may go away in time. */ 99675fd0b74Schristos int num; 99775fd0b74Schristos #define CGEN_INSN_NUM(insn) ((insn)->base->num) 99875fd0b74Schristos 99975fd0b74Schristos /* Name of entry (that distinguishes it from all other entries). */ 100075fd0b74Schristos /* ??? If mnemonics have operands, try to print full mnemonic. */ 100175fd0b74Schristos const char *name; 100275fd0b74Schristos #define CGEN_INSN_NAME(insn) ((insn)->base->name) 100375fd0b74Schristos 100475fd0b74Schristos /* Mnemonic. This is used when parsing and printing the insn. 100575fd0b74Schristos In the case of insns that have operands on the mnemonics, this is 100675fd0b74Schristos only the constant part. E.g. for conditional execution of an `add' insn, 100775fd0b74Schristos where the full mnemonic is addeq, addne, etc., and the condition is 100875fd0b74Schristos treated as an operand, this is only "add". */ 100975fd0b74Schristos const char *mnemonic; 101075fd0b74Schristos #define CGEN_INSN_MNEMONIC(insn) ((insn)->base->mnemonic) 101175fd0b74Schristos 101275fd0b74Schristos /* Total length of instruction, in bits. */ 101375fd0b74Schristos int bitsize; 101475fd0b74Schristos #define CGEN_INSN_BITSIZE(insn) ((insn)->base->bitsize) 101575fd0b74Schristos 101675fd0b74Schristos #if 0 /* ??? Disabled for now as there is a problem with embedded newlines 101775fd0b74Schristos and the table is already pretty big. Should perhaps be moved 101875fd0b74Schristos to a file of its own. */ 101975fd0b74Schristos /* Semantics, as RTL. */ 102075fd0b74Schristos /* ??? Plain text or bytecodes? */ 102175fd0b74Schristos /* ??? Note that the operand instance table could be computed at run-time 102275fd0b74Schristos if we parse this and cache the results. Something to eventually do. */ 102375fd0b74Schristos const char *rtx; 102475fd0b74Schristos #define CGEN_INSN_RTX(insn) ((insn)->base->rtx) 102575fd0b74Schristos #endif 102675fd0b74Schristos 102775fd0b74Schristos /* Attributes. 102875fd0b74Schristos This must appear last. It is a variable sized array in that one 102975fd0b74Schristos architecture may have 1 nonbool attribute and another may have more. 103075fd0b74Schristos Having this last means the non-architecture specific code needn't 103175fd0b74Schristos care. The goal is to eventually record attributes in their raw form, 103275fd0b74Schristos evaluate them at run-time, and cache the values, so this worry will go 103375fd0b74Schristos away anyway. */ 103475fd0b74Schristos CGEN_INSN_ATTR_TYPE attrs; 103575fd0b74Schristos #define CGEN_INSN_ATTRS(insn) (&(insn)->base->attrs) 103675fd0b74Schristos /* Return value of attribute ATTR in INSN. */ 103775fd0b74Schristos #define CGEN_INSN_ATTR_VALUE(insn, attr) \ 103875fd0b74Schristos CGEN_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 103975fd0b74Schristos #define CGEN_INSN_BITSET_ATTR_VALUE(insn, attr) \ 104075fd0b74Schristos CGEN_BITSET_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 104175fd0b74Schristos } CGEN_IBASE; 104275fd0b74Schristos 104375fd0b74Schristos /* Return non-zero if INSN is the "invalid" insn marker. */ 104475fd0b74Schristos 104575fd0b74Schristos #define CGEN_INSN_INVALID_P(insn) (CGEN_INSN_MNEMONIC (insn) == 0) 104675fd0b74Schristos 104775fd0b74Schristos /* Main struct contain instruction information. 104875fd0b74Schristos BASE is always present, the rest is present only if asked for. */ 104975fd0b74Schristos 105075fd0b74Schristos struct cgen_insn 105175fd0b74Schristos { 105275fd0b74Schristos /* ??? May be of use to put a type indicator here. 105375fd0b74Schristos Then this struct could different info for different classes of insns. */ 105475fd0b74Schristos /* ??? A speedup can be had by moving `base' into this struct. 105575fd0b74Schristos Maybe later. */ 105675fd0b74Schristos const CGEN_IBASE *base; 105775fd0b74Schristos const CGEN_OPCODE *opcode; 105875fd0b74Schristos const CGEN_OPINST *opinst; 105975fd0b74Schristos 106075fd0b74Schristos /* Regex to disambiguate overloaded opcodes */ 106175fd0b74Schristos void *rx; 106275fd0b74Schristos #define CGEN_INSN_RX(insn) ((insn)->rx) 106375fd0b74Schristos #define CGEN_MAX_RX_ELEMENTS (CGEN_MAX_SYNTAX_ELEMENTS * 5) 106475fd0b74Schristos }; 106575fd0b74Schristos 106675fd0b74Schristos /* Instruction lists. 106775fd0b74Schristos This is used for adding new entries and for creating the hash lists. */ 106875fd0b74Schristos 106975fd0b74Schristos typedef struct cgen_insn_list 107075fd0b74Schristos { 107175fd0b74Schristos struct cgen_insn_list *next; 107275fd0b74Schristos const CGEN_INSN *insn; 107375fd0b74Schristos } CGEN_INSN_LIST; 107475fd0b74Schristos 107575fd0b74Schristos /* Table of instructions. */ 107675fd0b74Schristos 107775fd0b74Schristos typedef struct 107875fd0b74Schristos { 107975fd0b74Schristos const CGEN_INSN *init_entries; 108075fd0b74Schristos unsigned int entry_size; /* since the attribute member is variable sized */ 108175fd0b74Schristos unsigned int num_init_entries; 108275fd0b74Schristos CGEN_INSN_LIST *new_entries; 108375fd0b74Schristos } CGEN_INSN_TABLE; 108475fd0b74Schristos 108575fd0b74Schristos /* Return number of instructions. This includes any added at run-time. */ 108675fd0b74Schristos 108775fd0b74Schristos extern int cgen_insn_count (CGEN_CPU_DESC); 108875fd0b74Schristos extern int cgen_macro_insn_count (CGEN_CPU_DESC); 108975fd0b74Schristos 109075fd0b74Schristos /* Macros to access the other insn elements not recorded in CGEN_IBASE. */ 109175fd0b74Schristos 109275fd0b74Schristos /* Fetch INSN's operand instance table. */ 109375fd0b74Schristos /* ??? Doesn't handle insns added at runtime. */ 109475fd0b74Schristos #define CGEN_INSN_OPERANDS(insn) ((insn)->opinst) 109575fd0b74Schristos 109675fd0b74Schristos /* Return INSN's opcode table entry. */ 109775fd0b74Schristos #define CGEN_INSN_OPCODE(insn) ((insn)->opcode) 109875fd0b74Schristos 109975fd0b74Schristos /* Return INSN's handler data. */ 110075fd0b74Schristos #define CGEN_INSN_HANDLERS(insn) CGEN_OPCODE_HANDLERS (CGEN_INSN_OPCODE (insn)) 110175fd0b74Schristos 110275fd0b74Schristos /* Return INSN's syntax. */ 110375fd0b74Schristos #define CGEN_INSN_SYNTAX(insn) CGEN_OPCODE_SYNTAX (CGEN_INSN_OPCODE (insn)) 110475fd0b74Schristos 110575fd0b74Schristos /* Return size of base mask in bits. */ 110675fd0b74Schristos #define CGEN_INSN_MASK_BITSIZE(insn) \ 110775fd0b74Schristos CGEN_OPCODE_MASK_BITSIZE (CGEN_INSN_OPCODE (insn)) 110875fd0b74Schristos 110975fd0b74Schristos /* Return mask of base part of INSN. */ 111075fd0b74Schristos #define CGEN_INSN_BASE_MASK(insn) \ 111175fd0b74Schristos CGEN_OPCODE_BASE_MASK (CGEN_INSN_OPCODE (insn)) 111275fd0b74Schristos 111375fd0b74Schristos /* Return value of base part of INSN. */ 111475fd0b74Schristos #define CGEN_INSN_BASE_VALUE(insn) \ 111575fd0b74Schristos CGEN_OPCODE_BASE_VALUE (CGEN_INSN_OPCODE (insn)) 111675fd0b74Schristos 111775fd0b74Schristos /* Standard way to test whether INSN is supported by MACH. 111875fd0b74Schristos MACH is one of enum mach_attr. 111975fd0b74Schristos The "|1" is because the base mach is always selected. */ 112075fd0b74Schristos #define CGEN_INSN_MACH_HAS_P(insn, mach) \ 112175fd0b74Schristos ((CGEN_INSN_ATTR_VALUE ((insn), CGEN_INSN_MACH) & ((1 << (mach)) | 1)) != 0) 112275fd0b74Schristos 112375fd0b74Schristos /* Macro instructions. 112475fd0b74Schristos Macro insns aren't real insns, they map to one or more real insns. 112575fd0b74Schristos E.g. An architecture's "nop" insn may actually be an "mv r0,r0" or 112675fd0b74Schristos some such. 112775fd0b74Schristos 112875fd0b74Schristos Macro insns can expand to nothing (e.g. a nop that is optimized away). 112975fd0b74Schristos This is useful in multi-insn macros that build a constant in a register. 113075fd0b74Schristos Of course this isn't the default behaviour and must be explicitly enabled. 113175fd0b74Schristos 113275fd0b74Schristos Assembly of macro-insns is relatively straightforward. Disassembly isn't. 113375fd0b74Schristos However, disassembly of at least some kinds of macro insns is important 113475fd0b74Schristos in order that the disassembled code preserve the readability of the original 113575fd0b74Schristos insn. What is attempted here is to disassemble all "simple" macro-insns, 113675fd0b74Schristos where "simple" is currently defined to mean "expands to one real insn". 113775fd0b74Schristos 113875fd0b74Schristos Simple macro-insns are handled specially. They are emitted as ALIAS's 113975fd0b74Schristos of real insns. This simplifies their handling since there's usually more 114075fd0b74Schristos of them than any other kind of macro-insn, and proper disassembly of them 114175fd0b74Schristos falls out for free. */ 114275fd0b74Schristos 114375fd0b74Schristos /* For each macro-insn there may be multiple expansion possibilities, 114475fd0b74Schristos depending on the arguments. This structure is accessed via the `data' 114575fd0b74Schristos member of CGEN_INSN. */ 114675fd0b74Schristos 114775fd0b74Schristos typedef struct cgen_minsn_expansion { 114875fd0b74Schristos /* Function to do the expansion. 114975fd0b74Schristos If the expansion fails (e.g. "no match") NULL is returned. 115075fd0b74Schristos Space for the expansion is obtained with malloc. 115175fd0b74Schristos It is up to the caller to free it. */ 115275fd0b74Schristos const char * (* fn) 115375fd0b74Schristos (const struct cgen_minsn_expansion *, 115475fd0b74Schristos const char *, const char **, int *, 115575fd0b74Schristos CGEN_OPERAND **); 115675fd0b74Schristos #define CGEN_MIEXPN_FN(ex) ((ex)->fn) 115775fd0b74Schristos 115875fd0b74Schristos /* Instruction(s) the macro expands to. 115975fd0b74Schristos The format of STR is defined by FN. 116075fd0b74Schristos It is typically the assembly code of the real insn, but it could also be 116175fd0b74Schristos the original Scheme expression or a tokenized form of it (with FN being 116275fd0b74Schristos an appropriate interpreter). */ 116375fd0b74Schristos const char * str; 116475fd0b74Schristos #define CGEN_MIEXPN_STR(ex) ((ex)->str) 116575fd0b74Schristos } CGEN_MINSN_EXPANSION; 116675fd0b74Schristos 116775fd0b74Schristos /* Normal expander. 116875fd0b74Schristos When supported, this function will convert the input string to another 116975fd0b74Schristos string and the parser will be invoked recursively. The output string 117075fd0b74Schristos may contain further macro invocations. */ 117175fd0b74Schristos 117275fd0b74Schristos extern const char * cgen_expand_macro_insn 117375fd0b74Schristos (CGEN_CPU_DESC, const struct cgen_minsn_expansion *, 117475fd0b74Schristos const char *, const char **, int *, CGEN_OPERAND **); 117575fd0b74Schristos 117675fd0b74Schristos /* The assembler insn table is hashed based on some function of the mnemonic 117775fd0b74Schristos (the actually hashing done is up to the target, but we provide a few 117875fd0b74Schristos examples like the first letter or a function of the entire mnemonic). */ 117975fd0b74Schristos 118075fd0b74Schristos extern CGEN_INSN_LIST * cgen_asm_lookup_insn 118175fd0b74Schristos (CGEN_CPU_DESC, const char *); 118275fd0b74Schristos #define CGEN_ASM_LOOKUP_INSN(cd, string) cgen_asm_lookup_insn ((cd), (string)) 118375fd0b74Schristos #define CGEN_ASM_NEXT_INSN(insn) ((insn)->next) 118475fd0b74Schristos 118575fd0b74Schristos /* The disassembler insn table is hashed based on some function of machine 118675fd0b74Schristos instruction (the actually hashing done is up to the target). */ 118775fd0b74Schristos 118875fd0b74Schristos extern CGEN_INSN_LIST * cgen_dis_lookup_insn 118975fd0b74Schristos (CGEN_CPU_DESC, const char *, CGEN_INSN_INT); 119075fd0b74Schristos /* FIXME: delete these two */ 119175fd0b74Schristos #define CGEN_DIS_LOOKUP_INSN(cd, buf, value) cgen_dis_lookup_insn ((cd), (buf), (value)) 119275fd0b74Schristos #define CGEN_DIS_NEXT_INSN(insn) ((insn)->next) 119375fd0b74Schristos 119475fd0b74Schristos /* The CPU description. 119575fd0b74Schristos A copy of this is created when the cpu table is "opened". 119675fd0b74Schristos All global state information is recorded here. 119775fd0b74Schristos Access macros are provided for "public" members. */ 119875fd0b74Schristos 119975fd0b74Schristos typedef struct cgen_cpu_desc 120075fd0b74Schristos { 120175fd0b74Schristos /* Bitmap of selected machine(s) (a la BFD machine number). */ 120275fd0b74Schristos int machs; 120375fd0b74Schristos 120475fd0b74Schristos /* Bitmap of selected isa(s). */ 120575fd0b74Schristos CGEN_BITSET *isas; 120675fd0b74Schristos #define CGEN_CPU_ISAS(cd) ((cd)->isas) 120775fd0b74Schristos 120875fd0b74Schristos /* Current endian. */ 120975fd0b74Schristos enum cgen_endian endian; 121075fd0b74Schristos #define CGEN_CPU_ENDIAN(cd) ((cd)->endian) 121175fd0b74Schristos 121275fd0b74Schristos /* Current insn endian. */ 121375fd0b74Schristos enum cgen_endian insn_endian; 121475fd0b74Schristos #define CGEN_CPU_INSN_ENDIAN(cd) ((cd)->insn_endian) 121575fd0b74Schristos 121675fd0b74Schristos /* Word size (in bits). */ 121775fd0b74Schristos /* ??? Or maybe maximum word size - might we ever need to allow a cpu table 121875fd0b74Schristos to be opened for both sparc32/sparc64? 121975fd0b74Schristos ??? Another alternative is to create a table of selected machs and 122075fd0b74Schristos lazily fetch the data from there. */ 122175fd0b74Schristos unsigned int word_bitsize; 122275fd0b74Schristos 122375fd0b74Schristos /* Instruction chunk size (in bits), for purposes of endianness 122475fd0b74Schristos conversion. */ 122575fd0b74Schristos unsigned int insn_chunk_bitsize; 122675fd0b74Schristos 122775fd0b74Schristos /* Indicator if sizes are unknown. 122875fd0b74Schristos This is used by default_insn_bitsize,base_insn_bitsize if there is a 122975fd0b74Schristos difference between the selected isa's. */ 123075fd0b74Schristos #define CGEN_SIZE_UNKNOWN 65535 123175fd0b74Schristos 123275fd0b74Schristos /* Default instruction size (in bits). 123375fd0b74Schristos This is used by the assembler when it encounters an unknown insn. */ 123475fd0b74Schristos unsigned int default_insn_bitsize; 123575fd0b74Schristos 123675fd0b74Schristos /* Base instruction size (in bits). 123775fd0b74Schristos For non-LIW cpus this is generally the length of the smallest insn. 123875fd0b74Schristos For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 123975fd0b74Schristos unsigned int base_insn_bitsize; 124075fd0b74Schristos 124175fd0b74Schristos /* Minimum/maximum instruction size (in bits). */ 124275fd0b74Schristos unsigned int min_insn_bitsize; 124375fd0b74Schristos unsigned int max_insn_bitsize; 124475fd0b74Schristos 124575fd0b74Schristos /* Instruction set variants. */ 124675fd0b74Schristos const CGEN_ISA *isa_table; 124775fd0b74Schristos 124875fd0b74Schristos /* Machine variants. */ 124975fd0b74Schristos const CGEN_MACH *mach_table; 125075fd0b74Schristos 125175fd0b74Schristos /* Hardware elements. */ 125275fd0b74Schristos CGEN_HW_TABLE hw_table; 125375fd0b74Schristos 125475fd0b74Schristos /* Instruction fields. */ 125575fd0b74Schristos const CGEN_IFLD *ifld_table; 125675fd0b74Schristos 125775fd0b74Schristos /* Operands. */ 125875fd0b74Schristos CGEN_OPERAND_TABLE operand_table; 125975fd0b74Schristos 126075fd0b74Schristos /* Main instruction table. */ 126175fd0b74Schristos CGEN_INSN_TABLE insn_table; 126275fd0b74Schristos #define CGEN_CPU_INSN_TABLE(cd) (& (cd)->insn_table) 126375fd0b74Schristos 126475fd0b74Schristos /* Macro instructions are defined separately and are combined with real 126575fd0b74Schristos insns during hash table computation. */ 126675fd0b74Schristos CGEN_INSN_TABLE macro_insn_table; 126775fd0b74Schristos 126875fd0b74Schristos /* Copy of CGEN_INT_INSN_P. */ 126975fd0b74Schristos int int_insn_p; 127075fd0b74Schristos 127175fd0b74Schristos /* Called to rebuild the tables after something has changed. */ 127275fd0b74Schristos void (*rebuild_tables) (CGEN_CPU_DESC); 127375fd0b74Schristos 127475fd0b74Schristos /* Operand parser callback. */ 127575fd0b74Schristos cgen_parse_operand_fn * parse_operand_fn; 127675fd0b74Schristos 127775fd0b74Schristos /* Parse/insert/extract/print cover fns for operands. */ 127875fd0b74Schristos const char * (*parse_operand) 127975fd0b74Schristos (CGEN_CPU_DESC, int opindex_, const char **, CGEN_FIELDS *fields_); 128075fd0b74Schristos #ifdef __BFD_H_SEEN__ 128175fd0b74Schristos const char * (*insert_operand) 128275fd0b74Schristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, 128375fd0b74Schristos CGEN_INSN_BYTES_PTR, bfd_vma pc_); 128475fd0b74Schristos int (*extract_operand) 128575fd0b74Schristos (CGEN_CPU_DESC, int opindex_, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, 128675fd0b74Schristos CGEN_FIELDS *fields_, bfd_vma pc_); 128775fd0b74Schristos void (*print_operand) 128875fd0b74Schristos (CGEN_CPU_DESC, int opindex_, void * info_, CGEN_FIELDS * fields_, 128975fd0b74Schristos void const *attrs_, bfd_vma pc_, int length_); 129075fd0b74Schristos #else 129175fd0b74Schristos const char * (*insert_operand) (); 129275fd0b74Schristos int (*extract_operand) (); 129375fd0b74Schristos void (*print_operand) (); 129475fd0b74Schristos #endif 129575fd0b74Schristos #define CGEN_CPU_PARSE_OPERAND(cd) ((cd)->parse_operand) 129675fd0b74Schristos #define CGEN_CPU_INSERT_OPERAND(cd) ((cd)->insert_operand) 129775fd0b74Schristos #define CGEN_CPU_EXTRACT_OPERAND(cd) ((cd)->extract_operand) 129875fd0b74Schristos #define CGEN_CPU_PRINT_OPERAND(cd) ((cd)->print_operand) 129975fd0b74Schristos 130075fd0b74Schristos /* Size of CGEN_FIELDS struct. */ 130175fd0b74Schristos unsigned int sizeof_fields; 130275fd0b74Schristos #define CGEN_CPU_SIZEOF_FIELDS(cd) ((cd)->sizeof_fields) 130375fd0b74Schristos 130475fd0b74Schristos /* Set the bitsize field. */ 130575fd0b74Schristos void (*set_fields_bitsize) (CGEN_FIELDS *fields_, int size_); 130675fd0b74Schristos #define CGEN_CPU_SET_FIELDS_BITSIZE(cd) ((cd)->set_fields_bitsize) 130775fd0b74Schristos 130875fd0b74Schristos /* CGEN_FIELDS accessors. */ 130975fd0b74Schristos int (*get_int_operand) 131075fd0b74Schristos (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 131175fd0b74Schristos void (*set_int_operand) 131275fd0b74Schristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, int value_); 131375fd0b74Schristos #ifdef __BFD_H_SEEN__ 131475fd0b74Schristos bfd_vma (*get_vma_operand) 131575fd0b74Schristos (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 131675fd0b74Schristos void (*set_vma_operand) 131775fd0b74Schristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, bfd_vma value_); 131875fd0b74Schristos #else 131975fd0b74Schristos long (*get_vma_operand) (); 132075fd0b74Schristos void (*set_vma_operand) (); 132175fd0b74Schristos #endif 132275fd0b74Schristos #define CGEN_CPU_GET_INT_OPERAND(cd) ((cd)->get_int_operand) 132375fd0b74Schristos #define CGEN_CPU_SET_INT_OPERAND(cd) ((cd)->set_int_operand) 132475fd0b74Schristos #define CGEN_CPU_GET_VMA_OPERAND(cd) ((cd)->get_vma_operand) 132575fd0b74Schristos #define CGEN_CPU_SET_VMA_OPERAND(cd) ((cd)->set_vma_operand) 132675fd0b74Schristos 132775fd0b74Schristos /* Instruction parse/insert/extract/print handlers. */ 132875fd0b74Schristos /* FIXME: make these types uppercase. */ 132975fd0b74Schristos cgen_parse_fn * const *parse_handlers; 133075fd0b74Schristos cgen_insert_fn * const *insert_handlers; 133175fd0b74Schristos cgen_extract_fn * const *extract_handlers; 133275fd0b74Schristos cgen_print_fn * const *print_handlers; 133375fd0b74Schristos #define CGEN_PARSE_FN(cd, insn) (cd->parse_handlers[(insn)->opcode->handlers.parse]) 133475fd0b74Schristos #define CGEN_INSERT_FN(cd, insn) (cd->insert_handlers[(insn)->opcode->handlers.insert]) 133575fd0b74Schristos #define CGEN_EXTRACT_FN(cd, insn) (cd->extract_handlers[(insn)->opcode->handlers.extract]) 133675fd0b74Schristos #define CGEN_PRINT_FN(cd, insn) (cd->print_handlers[(insn)->opcode->handlers.print]) 133775fd0b74Schristos 133875fd0b74Schristos /* Return non-zero if insn should be added to hash table. */ 133975fd0b74Schristos int (* asm_hash_p) (const CGEN_INSN *); 134075fd0b74Schristos 134175fd0b74Schristos /* Assembler hash function. */ 134275fd0b74Schristos unsigned int (* asm_hash) (const char *); 134375fd0b74Schristos 134475fd0b74Schristos /* Number of entries in assembler hash table. */ 134575fd0b74Schristos unsigned int asm_hash_size; 134675fd0b74Schristos 134775fd0b74Schristos /* Return non-zero if insn should be added to hash table. */ 134875fd0b74Schristos int (* dis_hash_p) (const CGEN_INSN *); 134975fd0b74Schristos 135075fd0b74Schristos /* Disassembler hash function. */ 135175fd0b74Schristos unsigned int (* dis_hash) (const char *, CGEN_INSN_INT); 135275fd0b74Schristos 135375fd0b74Schristos /* Number of entries in disassembler hash table. */ 135475fd0b74Schristos unsigned int dis_hash_size; 135575fd0b74Schristos 135675fd0b74Schristos /* Assembler instruction hash table. */ 135775fd0b74Schristos CGEN_INSN_LIST **asm_hash_table; 135875fd0b74Schristos CGEN_INSN_LIST *asm_hash_table_entries; 135975fd0b74Schristos 136075fd0b74Schristos /* Disassembler instruction hash table. */ 136175fd0b74Schristos CGEN_INSN_LIST **dis_hash_table; 136275fd0b74Schristos CGEN_INSN_LIST *dis_hash_table_entries; 136375fd0b74Schristos 136475fd0b74Schristos /* This field could be turned into a bitfield if room for other flags is needed. */ 136575fd0b74Schristos unsigned int signed_overflow_ok_p; 136675fd0b74Schristos 136775fd0b74Schristos } CGEN_CPU_TABLE; 136875fd0b74Schristos 136975fd0b74Schristos /* wip */ 137075fd0b74Schristos #ifndef CGEN_WORD_ENDIAN 137175fd0b74Schristos #define CGEN_WORD_ENDIAN(cd) CGEN_CPU_ENDIAN (cd) 137275fd0b74Schristos #endif 137375fd0b74Schristos #ifndef CGEN_INSN_WORD_ENDIAN 137475fd0b74Schristos #define CGEN_INSN_WORD_ENDIAN(cd) CGEN_CPU_INSN_ENDIAN (cd) 137575fd0b74Schristos #endif 137675fd0b74Schristos 137775fd0b74Schristos /* Prototypes of major functions. */ 137875fd0b74Schristos /* FIXME: Move more CGEN_SYM-defined functions into CGEN_CPU_DESC. 137975fd0b74Schristos Not the init fns though, as that would drag in things that mightn't be 138075fd0b74Schristos used and might not even exist. */ 138175fd0b74Schristos 138275fd0b74Schristos /* Argument types to cpu_open. */ 138375fd0b74Schristos 138475fd0b74Schristos enum cgen_cpu_open_arg { 138575fd0b74Schristos CGEN_CPU_OPEN_END, 138675fd0b74Schristos /* Select instruction set(s), arg is bitmap or 0 meaning "unspecified". */ 138775fd0b74Schristos CGEN_CPU_OPEN_ISAS, 138875fd0b74Schristos /* Select machine(s), arg is bitmap or 0 meaning "unspecified". */ 138975fd0b74Schristos CGEN_CPU_OPEN_MACHS, 139075fd0b74Schristos /* Select machine, arg is mach's bfd name. 139175fd0b74Schristos Multiple machines can be specified by repeated use. */ 139275fd0b74Schristos CGEN_CPU_OPEN_BFDMACH, 139375fd0b74Schristos /* Select endian, arg is CGEN_ENDIAN_*. */ 1394*e992f068Schristos CGEN_CPU_OPEN_ENDIAN, 1395*e992f068Schristos /* Select instruction endian, arg is CGEN_ENDIAN_*. */ 1396*e992f068Schristos CGEN_CPU_OPEN_INSN_ENDIAN, 139775fd0b74Schristos }; 139875fd0b74Schristos 139975fd0b74Schristos /* Open a cpu descriptor table for use. 140075fd0b74Schristos ??? We only support ISO C stdargs here, not K&R. 140175fd0b74Schristos Laziness, plus experiment to see if anything requires K&R - eventually 140275fd0b74Schristos K&R will no longer be supported - e.g. GDB is currently trying this. */ 140375fd0b74Schristos 140475fd0b74Schristos extern CGEN_CPU_DESC CGEN_SYM (cpu_open) (enum cgen_cpu_open_arg, ...); 140575fd0b74Schristos 140675fd0b74Schristos /* Cover fn to handle simple case. */ 140775fd0b74Schristos 140875fd0b74Schristos extern CGEN_CPU_DESC CGEN_SYM (cpu_open_1) 140975fd0b74Schristos (const char *mach_name_, enum cgen_endian endian_); 141075fd0b74Schristos 141175fd0b74Schristos /* Close it. */ 141275fd0b74Schristos 141375fd0b74Schristos extern void CGEN_SYM (cpu_close) (CGEN_CPU_DESC); 141475fd0b74Schristos 141575fd0b74Schristos /* Initialize the opcode table for use. 141675fd0b74Schristos Called by init_asm/init_dis. */ 141775fd0b74Schristos 141875fd0b74Schristos extern void CGEN_SYM (init_opcode_table) (CGEN_CPU_DESC cd_); 141975fd0b74Schristos 142075fd0b74Schristos /* build the insn selection regex. 142175fd0b74Schristos called by init_opcode_table */ 142275fd0b74Schristos 142375fd0b74Schristos extern char * CGEN_SYM(build_insn_regex) (CGEN_INSN *insn_); 142475fd0b74Schristos 142575fd0b74Schristos /* Initialize the ibld table for use. 142675fd0b74Schristos Called by init_asm/init_dis. */ 142775fd0b74Schristos 142875fd0b74Schristos extern void CGEN_SYM (init_ibld_table) (CGEN_CPU_DESC cd_); 142975fd0b74Schristos 143075fd0b74Schristos /* Initialize an cpu table for assembler or disassembler use. 143175fd0b74Schristos These must be called immediately after cpu_open. */ 143275fd0b74Schristos 143375fd0b74Schristos extern void CGEN_SYM (init_asm) (CGEN_CPU_DESC); 143475fd0b74Schristos extern void CGEN_SYM (init_dis) (CGEN_CPU_DESC); 143575fd0b74Schristos 143675fd0b74Schristos /* Initialize the operand instance table for use. */ 143775fd0b74Schristos 143875fd0b74Schristos extern void CGEN_SYM (init_opinst_table) (CGEN_CPU_DESC cd_); 143975fd0b74Schristos 144075fd0b74Schristos /* Assemble an instruction. */ 144175fd0b74Schristos 144275fd0b74Schristos extern const CGEN_INSN * CGEN_SYM (assemble_insn) 144375fd0b74Schristos (CGEN_CPU_DESC, const char *, CGEN_FIELDS *, 144475fd0b74Schristos CGEN_INSN_BYTES_PTR, char **); 144575fd0b74Schristos 144675fd0b74Schristos extern const CGEN_KEYWORD CGEN_SYM (operand_mach); 144775fd0b74Schristos extern int CGEN_SYM (get_mach) (const char *); 144875fd0b74Schristos 144975fd0b74Schristos /* Operand index computation. */ 145075fd0b74Schristos extern const CGEN_INSN * cgen_lookup_insn 145175fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN * insn_, 145275fd0b74Schristos CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 145375fd0b74Schristos int length_, CGEN_FIELDS *fields_, int alias_p_); 145475fd0b74Schristos extern void cgen_get_insn_operands 145575fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN * insn_, 145675fd0b74Schristos const CGEN_FIELDS *fields_, int *indices_); 145775fd0b74Schristos extern const CGEN_INSN * cgen_lookup_get_insn_operands 145875fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 145975fd0b74Schristos CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 146075fd0b74Schristos int length_, int *indices_, CGEN_FIELDS *fields_); 146175fd0b74Schristos 146275fd0b74Schristos /* Cover fns to bfd_get/set. */ 146375fd0b74Schristos 146475fd0b74Schristos extern CGEN_INSN_INT cgen_get_insn_value 1465*e992f068Schristos (CGEN_CPU_DESC, unsigned char *, int, int); 146675fd0b74Schristos extern void cgen_put_insn_value 1467*e992f068Schristos (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT, int); 1468*e992f068Schristos 1469*e992f068Schristos extern CGEN_INSN_INT cgen_get_base_insn_value 1470*e992f068Schristos (CGEN_CPU_DESC, unsigned char *, int); 1471*e992f068Schristos extern void cgen_put_base_insn_value 147275fd0b74Schristos (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT); 147375fd0b74Schristos 147475fd0b74Schristos /* Read in a cpu description file. 147575fd0b74Schristos ??? For future concerns, including adding instructions to the assembler/ 147675fd0b74Schristos disassembler at run-time. */ 147775fd0b74Schristos 147875fd0b74Schristos extern const char * cgen_read_cpu_file (CGEN_CPU_DESC, const char * filename_); 147975fd0b74Schristos 148075fd0b74Schristos /* Allow signed overflow of instruction fields. */ 148175fd0b74Schristos extern void cgen_set_signed_overflow_ok (CGEN_CPU_DESC); 148275fd0b74Schristos 148375fd0b74Schristos /* Generate an error message if a signed field in an instruction overflows. */ 148475fd0b74Schristos extern void cgen_clear_signed_overflow_ok (CGEN_CPU_DESC); 148575fd0b74Schristos 148675fd0b74Schristos /* Will an error message be generated if a signed field in an instruction overflows ? */ 148775fd0b74Schristos extern unsigned int cgen_signed_overflow_ok_p (CGEN_CPU_DESC); 148875fd0b74Schristos 148975fd0b74Schristos #ifdef __cplusplus 149075fd0b74Schristos } 149175fd0b74Schristos #endif 149275fd0b74Schristos 149375fd0b74Schristos #endif /* OPCODE_CGEN_H */ 1494