198b9484cSchristos /* Header file for targets using CGEN: Cpu tools GENerator. 298b9484cSchristos 3*02f41505Schristos Copyright (C) 1996-2024 Free Software Foundation, Inc. 498b9484cSchristos 598b9484cSchristos This file is part of GDB, the GNU debugger, and the GNU Binutils. 698b9484cSchristos 798b9484cSchristos This program is free software; you can redistribute it and/or modify 898b9484cSchristos it under the terms of the GNU General Public License as published by 998b9484cSchristos the Free Software Foundation; either version 3 of the License, or 1098b9484cSchristos (at your option) any later version. 1198b9484cSchristos 1298b9484cSchristos This program is distributed in the hope that it will be useful, 1398b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1498b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598b9484cSchristos GNU General Public License for more details. 1698b9484cSchristos 1798b9484cSchristos You should have received a copy of the GNU General Public License along 1898b9484cSchristos with this program; if not, write to the Free Software Foundation, Inc., 1998b9484cSchristos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2098b9484cSchristos 2198b9484cSchristos #ifndef OPCODE_CGEN_H 2298b9484cSchristos #define OPCODE_CGEN_H 2398b9484cSchristos 2498b9484cSchristos #include "symcat.h" 2598b9484cSchristos #include "cgen/bitset.h" 2698b9484cSchristos 274b169a6bSchristos #include <stdint.h> 2898b9484cSchristos 29212397c6Schristos #ifdef __cplusplus 30212397c6Schristos extern "C" { 31212397c6Schristos #endif 32212397c6Schristos 3398b9484cSchristos /* ??? This file requires bfd.h but only to get bfd_vma. 3498b9484cSchristos Seems like an awful lot to require just to get such a fundamental type. 3598b9484cSchristos Perhaps the definition of bfd_vma can be moved outside of bfd.h. 3698b9484cSchristos Or perhaps one could duplicate its definition in another file. 3798b9484cSchristos Until such time, this file conditionally compiles definitions that require 3898b9484cSchristos bfd_vma using __BFD_H_SEEN__. */ 3998b9484cSchristos 4098b9484cSchristos /* Enums must be defined before they can be used. 4198b9484cSchristos Allow them to be used in struct definitions, even though the enum must 4298b9484cSchristos be defined elsewhere. 4398b9484cSchristos If CGEN_ARCH isn't defined, this file is being included by something other 4498b9484cSchristos than <arch>-desc.h. */ 4598b9484cSchristos 4698b9484cSchristos /* Prepend the arch name, defined in <arch>-desc.h, and _cgen_ to symbol S. 4798b9484cSchristos The lack of spaces in the arg list is important for non-stdc systems. 4898b9484cSchristos This file is included by <arch>-desc.h. 4998b9484cSchristos It can be included independently of <arch>-desc.h, in which case the arch 5098b9484cSchristos dependent portions will be declared as "unknown_cgen_foo". */ 5198b9484cSchristos 5298b9484cSchristos #ifndef CGEN_SYM 5398b9484cSchristos #define CGEN_SYM(s) CONCAT3 (unknown,_cgen_,s) 5498b9484cSchristos #endif 5598b9484cSchristos 5698b9484cSchristos /* This file contains the static (unchanging) pieces and as much other stuff 5798b9484cSchristos as we can reasonably put here. It's generally cleaner to put stuff here 5898b9484cSchristos rather than having it machine generated if possible. */ 5998b9484cSchristos 6098b9484cSchristos /* The assembler syntax is made up of expressions (duh...). 6198b9484cSchristos At the lowest level the values are mnemonics, register names, numbers, etc. 6298b9484cSchristos Above that are subexpressions, if any (an example might be the 6398b9484cSchristos "effective address" in m68k cpus). Subexpressions are wip. 6498b9484cSchristos At the second highest level are the insns themselves. Above that are 6598b9484cSchristos pseudo-insns, synthetic insns, and macros, if any. */ 6698b9484cSchristos 6798b9484cSchristos /* Lots of cpu's have a fixed insn size, or one which rarely changes, 6898b9484cSchristos and it's generally easier to handle these by treating the insn as an 6998b9484cSchristos integer type, rather than an array of characters. So we allow targets 7098b9484cSchristos to control this. When an integer type the value is in host byte order, 7198b9484cSchristos when an array of characters the value is in target byte order. */ 7298b9484cSchristos 7398b9484cSchristos typedef unsigned int CGEN_INSN_INT; 7498b9484cSchristos typedef int64_t CGEN_INSN_LGSINT; /* large/long SINT */ 7598b9484cSchristos typedef uint64_t CGEN_INSN_LGUINT; /* large/long UINT */ 7698b9484cSchristos 7798b9484cSchristos #if CGEN_INT_INSN_P 7898b9484cSchristos typedef CGEN_INSN_INT CGEN_INSN_BYTES; 7998b9484cSchristos typedef CGEN_INSN_INT *CGEN_INSN_BYTES_PTR; 8098b9484cSchristos #else 8198b9484cSchristos typedef unsigned char *CGEN_INSN_BYTES; 8298b9484cSchristos typedef unsigned char *CGEN_INSN_BYTES_PTR; 8398b9484cSchristos #endif 8498b9484cSchristos 8598b9484cSchristos #ifdef __GNUC__ 8698b9484cSchristos #define CGEN_INLINE __inline__ 8798b9484cSchristos #else 8898b9484cSchristos #define CGEN_INLINE 8998b9484cSchristos #endif 9098b9484cSchristos 9198b9484cSchristos enum cgen_endian 9298b9484cSchristos { 9398b9484cSchristos CGEN_ENDIAN_UNKNOWN, 9498b9484cSchristos CGEN_ENDIAN_LITTLE, 9598b9484cSchristos CGEN_ENDIAN_BIG 9698b9484cSchristos }; 9798b9484cSchristos 9898b9484cSchristos /* Forward decl. */ 9998b9484cSchristos 10098b9484cSchristos typedef struct cgen_insn CGEN_INSN; 10198b9484cSchristos 10298b9484cSchristos /* Opaque pointer version for use by external world. */ 10398b9484cSchristos 10498b9484cSchristos typedef struct cgen_cpu_desc *CGEN_CPU_DESC; 10598b9484cSchristos 10698b9484cSchristos /* Attributes. 10798b9484cSchristos Attributes are used to describe various random things associated with 10898b9484cSchristos an object (ifield, hardware, operand, insn, whatever) and are specified 10998b9484cSchristos as name/value pairs. 11098b9484cSchristos Integer attributes computed at compile time are currently all that's 11198b9484cSchristos supported, though adding string attributes and run-time computation is 11298b9484cSchristos straightforward. Integer attribute values are always host int's 11398b9484cSchristos (signed or unsigned). For portability, this means 32 bits. 11498b9484cSchristos Integer attributes are further categorized as boolean, bitset, integer, 11598b9484cSchristos and enum types. Boolean attributes appear frequently enough that they're 11698b9484cSchristos recorded in one host int. This limits the maximum number of boolean 11798b9484cSchristos attributes to 32, though that's a *lot* of attributes. */ 11898b9484cSchristos 11998b9484cSchristos /* Type of attribute values. */ 12098b9484cSchristos 12198b9484cSchristos typedef CGEN_BITSET CGEN_ATTR_VALUE_BITSET_TYPE; 12298b9484cSchristos typedef int CGEN_ATTR_VALUE_ENUM_TYPE; 12398b9484cSchristos typedef union 12498b9484cSchristos { 12598b9484cSchristos CGEN_ATTR_VALUE_BITSET_TYPE bitset; 12698b9484cSchristos CGEN_ATTR_VALUE_ENUM_TYPE nonbitset; 12798b9484cSchristos } CGEN_ATTR_VALUE_TYPE; 12898b9484cSchristos 12998b9484cSchristos /* Struct to record attribute information. */ 13098b9484cSchristos 13198b9484cSchristos typedef struct 13298b9484cSchristos { 13398b9484cSchristos /* Boolean attributes. */ 13498b9484cSchristos unsigned int bool_; 13598b9484cSchristos /* Non-boolean integer attributes. */ 13698b9484cSchristos CGEN_ATTR_VALUE_TYPE nonbool[1]; 13798b9484cSchristos } CGEN_ATTR; 13898b9484cSchristos 13998b9484cSchristos /* Define a structure member for attributes with N non-boolean entries. 14098b9484cSchristos There is no maximum number of non-boolean attributes. 14198b9484cSchristos There is a maximum of 32 boolean attributes (since they are all recorded 14298b9484cSchristos in one host int). */ 14398b9484cSchristos 14498b9484cSchristos #define CGEN_ATTR_TYPE(n) \ 14598b9484cSchristos struct { unsigned int bool_; \ 14698b9484cSchristos CGEN_ATTR_VALUE_TYPE nonbool[(n) ? (n) : 1]; } 14798b9484cSchristos 14898b9484cSchristos /* Return the boolean attributes. */ 14998b9484cSchristos 15098b9484cSchristos #define CGEN_ATTR_BOOLS(a) ((a)->bool_) 15198b9484cSchristos 15298b9484cSchristos /* Non-boolean attribute numbers are offset by this much. */ 15398b9484cSchristos 15498b9484cSchristos #define CGEN_ATTR_NBOOL_OFFSET 32 15598b9484cSchristos 15698b9484cSchristos /* Given a boolean attribute number, return its mask. */ 15798b9484cSchristos 15898b9484cSchristos #define CGEN_ATTR_MASK(attr) (1 << (attr)) 15998b9484cSchristos 16098b9484cSchristos /* Return the value of boolean attribute ATTR in ATTRS. */ 16198b9484cSchristos 16298b9484cSchristos #define CGEN_BOOL_ATTR(attrs, attr) ((CGEN_ATTR_MASK (attr) & (attrs)) != 0) 16398b9484cSchristos 16498b9484cSchristos /* Return value of attribute ATTR in ATTR_TABLE for OBJ. 16598b9484cSchristos OBJ is a pointer to the entity that has the attributes 16698b9484cSchristos (??? not used at present but is reserved for future purposes - eventually 16798b9484cSchristos the goal is to allow recording attributes in source form and computing 16898b9484cSchristos them lazily at runtime, not sure of the details yet). */ 16998b9484cSchristos 17098b9484cSchristos #define CGEN_ATTR_VALUE(obj, attr_table, attr) \ 17198b9484cSchristos ((unsigned int) (attr) < CGEN_ATTR_NBOOL_OFFSET \ 17298b9484cSchristos ? ((CGEN_ATTR_BOOLS (attr_table) & CGEN_ATTR_MASK (attr)) != 0) \ 17398b9484cSchristos : ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].nonbitset)) 17498b9484cSchristos #define CGEN_BITSET_ATTR_VALUE(obj, attr_table, attr) \ 17598b9484cSchristos ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET].bitset) 17698b9484cSchristos 17798b9484cSchristos /* Attribute name/value tables. 17898b9484cSchristos These are used to assist parsing of descriptions at run-time. */ 17998b9484cSchristos 18098b9484cSchristos typedef struct 18198b9484cSchristos { 18298b9484cSchristos const char * name; 18398b9484cSchristos unsigned value; 18498b9484cSchristos } CGEN_ATTR_ENTRY; 18598b9484cSchristos 18698b9484cSchristos /* For each domain (ifld,hw,operand,insn), list of attributes. */ 18798b9484cSchristos 18898b9484cSchristos typedef struct 18998b9484cSchristos { 19098b9484cSchristos const char * name; 19198b9484cSchristos const CGEN_ATTR_ENTRY * dfault; 19298b9484cSchristos const CGEN_ATTR_ENTRY * vals; 19398b9484cSchristos } CGEN_ATTR_TABLE; 19498b9484cSchristos 19598b9484cSchristos /* Instruction set variants. */ 19698b9484cSchristos 19798b9484cSchristos typedef struct { 19898b9484cSchristos const char *name; 19998b9484cSchristos 20098b9484cSchristos /* Default instruction size (in bits). 20198b9484cSchristos This is used by the assembler when it encounters an unknown insn. */ 20298b9484cSchristos unsigned int default_insn_bitsize; 20398b9484cSchristos 20498b9484cSchristos /* Base instruction size (in bits). 20598b9484cSchristos For non-LIW cpus this is generally the length of the smallest insn. 20698b9484cSchristos For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 20798b9484cSchristos unsigned int base_insn_bitsize; 20898b9484cSchristos 20998b9484cSchristos /* Minimum/maximum instruction size (in bits). */ 21098b9484cSchristos unsigned int min_insn_bitsize; 21198b9484cSchristos unsigned int max_insn_bitsize; 21298b9484cSchristos } CGEN_ISA; 21398b9484cSchristos 21498b9484cSchristos /* Machine variants. */ 21598b9484cSchristos 21698b9484cSchristos typedef struct { 21798b9484cSchristos const char *name; 21898b9484cSchristos /* The argument to bfd_arch_info->scan. */ 21998b9484cSchristos const char *bfd_name; 22098b9484cSchristos /* one of enum mach_attr */ 22198b9484cSchristos int num; 22298b9484cSchristos /* parameter from mach->cpu */ 22398b9484cSchristos unsigned int insn_chunk_bitsize; 22498b9484cSchristos } CGEN_MACH; 22598b9484cSchristos 22698b9484cSchristos /* Parse result (also extraction result). 22798b9484cSchristos 22898b9484cSchristos The result of parsing an insn is stored here. 22998b9484cSchristos To generate the actual insn, this is passed to the insert handler. 23098b9484cSchristos When printing an insn, the result of extraction is stored here. 23198b9484cSchristos To print the insn, this is passed to the print handler. 23298b9484cSchristos 23398b9484cSchristos It is machine generated so we don't define it here, 23498b9484cSchristos but we do need a forward decl for the handler fns. 23598b9484cSchristos 23698b9484cSchristos There is one member for each possible field in the insn. 23798b9484cSchristos The type depends on the field. 23898b9484cSchristos Also recorded here is the computed length of the insn for architectures 23998b9484cSchristos where it varies. 24098b9484cSchristos */ 24198b9484cSchristos 24298b9484cSchristos typedef struct cgen_fields CGEN_FIELDS; 24398b9484cSchristos 24498b9484cSchristos /* Total length of the insn, as recorded in the `fields' struct. */ 24598b9484cSchristos /* ??? The field insert handler has lots of opportunities for optimization 24698b9484cSchristos if it ever gets inlined. On architectures where insns all have the same 24798b9484cSchristos size, may wish to detect that and make this macro a constant - to allow 24898b9484cSchristos further optimizations. */ 24998b9484cSchristos 25098b9484cSchristos #define CGEN_FIELDS_BITSIZE(fields) ((fields)->length) 25198b9484cSchristos 25298b9484cSchristos /* Extraction support for variable length insn sets. */ 25398b9484cSchristos 25498b9484cSchristos /* When disassembling we don't know the number of bytes to read at the start. 25598b9484cSchristos So the first CGEN_BASE_INSN_SIZE bytes are read at the start and the rest 25698b9484cSchristos are read when needed. This struct controls this. It is basically the 25798b9484cSchristos disassemble_info stuff, except that we provide a cache for values already 25898b9484cSchristos read (since bytes can typically be read several times to fetch multiple 25998b9484cSchristos operands that may be in them), and that extraction of fields is needed 26098b9484cSchristos in contexts other than disassembly. */ 26198b9484cSchristos 26298b9484cSchristos typedef struct { 26398b9484cSchristos /* A pointer to the disassemble_info struct. 26498b9484cSchristos We don't require dis-asm.h so we use void * for the type here. 26598b9484cSchristos If NULL, BYTES is full of valid data (VALID == -1). */ 26698b9484cSchristos void *dis_info; 26798b9484cSchristos /* Points to a working buffer of sufficient size. */ 26898b9484cSchristos unsigned char *insn_bytes; 26998b9484cSchristos /* Mask of bytes that are valid in INSN_BYTES. */ 27098b9484cSchristos unsigned int valid; 27198b9484cSchristos } CGEN_EXTRACT_INFO; 27298b9484cSchristos 27398b9484cSchristos /* Associated with each insn or expression is a set of "handlers" for 27498b9484cSchristos performing operations like parsing, printing, etc. These require a bfd_vma 27598b9484cSchristos value to be passed around but we don't want all applications to need bfd.h. 27698b9484cSchristos So this stuff is only provided if bfd.h has been included. */ 27798b9484cSchristos 27898b9484cSchristos /* Parse handler. 27998b9484cSchristos CD is a cpu table descriptor. 28098b9484cSchristos INSN is a pointer to a struct describing the insn being parsed. 28198b9484cSchristos STRP is a pointer to a pointer to the text being parsed. 28298b9484cSchristos FIELDS is a pointer to a cgen_fields struct in which the results are placed. 28398b9484cSchristos If the expression is successfully parsed, *STRP is updated. 28498b9484cSchristos If not it is left alone. 28598b9484cSchristos The result is NULL if success or an error message. */ 28698b9484cSchristos typedef const char * (cgen_parse_fn) 28798b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 28898b9484cSchristos const char **strp_, CGEN_FIELDS *fields_); 28998b9484cSchristos 29098b9484cSchristos /* Insert handler. 29198b9484cSchristos CD is a cpu table descriptor. 29298b9484cSchristos INSN is a pointer to a struct describing the insn being parsed. 29398b9484cSchristos FIELDS is a pointer to a cgen_fields struct from which the values 29498b9484cSchristos are fetched. 29598b9484cSchristos INSNP is a pointer to a buffer in which to place the insn. 29698b9484cSchristos PC is the pc value of the insn. 29798b9484cSchristos The result is an error message or NULL if success. */ 29898b9484cSchristos 29998b9484cSchristos #ifdef __BFD_H_SEEN__ 30098b9484cSchristos typedef const char * (cgen_insert_fn) 30198b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 30298b9484cSchristos CGEN_FIELDS *fields_, CGEN_INSN_BYTES_PTR insnp_, 30398b9484cSchristos bfd_vma pc_); 30498b9484cSchristos #else 30598b9484cSchristos typedef const char * (cgen_insert_fn) (); 30698b9484cSchristos #endif 30798b9484cSchristos 30898b9484cSchristos /* Extract handler. 30998b9484cSchristos CD is a cpu table descriptor. 31098b9484cSchristos INSN is a pointer to a struct describing the insn being parsed. 31198b9484cSchristos The second argument is a pointer to a struct controlling extraction 31298b9484cSchristos (only used for variable length insns). 31398b9484cSchristos EX_INFO is a pointer to a struct for controlling reading of further 31498b9484cSchristos bytes for the insn. 31598b9484cSchristos BASE_INSN is the first CGEN_BASE_INSN_SIZE bytes (host order). 31698b9484cSchristos FIELDS is a pointer to a cgen_fields struct in which the results are placed. 31798b9484cSchristos PC is the pc value of the insn. 31898b9484cSchristos The result is the length of the insn in bits or zero if not recognized. */ 31998b9484cSchristos 32098b9484cSchristos #ifdef __BFD_H_SEEN__ 32198b9484cSchristos typedef int (cgen_extract_fn) 32298b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 32398b9484cSchristos CGEN_EXTRACT_INFO *ex_info_, CGEN_INSN_INT base_insn_, 32498b9484cSchristos CGEN_FIELDS *fields_, bfd_vma pc_); 32598b9484cSchristos #else 32698b9484cSchristos typedef int (cgen_extract_fn) (); 32798b9484cSchristos #endif 32898b9484cSchristos 32998b9484cSchristos /* Print handler. 33098b9484cSchristos CD is a cpu table descriptor. 33198b9484cSchristos INFO is a pointer to the disassembly info. 33298b9484cSchristos Eg: disassemble_info. It's defined as `PTR' so this file can be included 33398b9484cSchristos without dis-asm.h. 33498b9484cSchristos INSN is a pointer to a struct describing the insn being printed. 33598b9484cSchristos FIELDS is a pointer to a cgen_fields struct. 33698b9484cSchristos PC is the pc value of the insn. 33798b9484cSchristos LEN is the length of the insn, in bits. */ 33898b9484cSchristos 33998b9484cSchristos #ifdef __BFD_H_SEEN__ 34098b9484cSchristos typedef void (cgen_print_fn) 34198b9484cSchristos (CGEN_CPU_DESC, void * info_, const CGEN_INSN *insn_, 34298b9484cSchristos CGEN_FIELDS *fields_, bfd_vma pc_, int len_); 34398b9484cSchristos #else 34498b9484cSchristos typedef void (cgen_print_fn) (); 34598b9484cSchristos #endif 34698b9484cSchristos 34798b9484cSchristos /* Parse/insert/extract/print handlers. 34898b9484cSchristos 34998b9484cSchristos Indices into the handler tables. 35098b9484cSchristos We could use pointers here instead, but 90% of them are generally identical 35198b9484cSchristos and that's a lot of redundant data. Making these unsigned char indices 35298b9484cSchristos into tables of pointers saves a bit of space. 35398b9484cSchristos Using indices also keeps assembler code out of the disassembler and 35498b9484cSchristos vice versa. */ 35598b9484cSchristos 35698b9484cSchristos struct cgen_opcode_handler 35798b9484cSchristos { 35898b9484cSchristos unsigned char parse, insert, extract, print; 35998b9484cSchristos }; 36098b9484cSchristos 36198b9484cSchristos /* Assembler interface. 36298b9484cSchristos 36398b9484cSchristos The interface to the assembler is intended to be clean in the sense that 36498b9484cSchristos libopcodes.a is a standalone entity and could be used with any assembler. 36598b9484cSchristos Not that one would necessarily want to do that but rather that it helps 36698b9484cSchristos keep a clean interface. The interface will obviously be slanted towards 36798b9484cSchristos GAS, but at least it's a start. 36898b9484cSchristos ??? Note that one possible user of the assembler besides GAS is GDB. 36998b9484cSchristos 37098b9484cSchristos Parsing is controlled by the assembler which calls 37198b9484cSchristos CGEN_SYM (assemble_insn). If it can parse and build the entire insn 37298b9484cSchristos it doesn't call back to the assembler. If it needs/wants to call back 37398b9484cSchristos to the assembler, cgen_parse_operand_fn is called which can either 37498b9484cSchristos 37598b9484cSchristos - return a number to be inserted in the insn 37698b9484cSchristos - return a "register" value to be inserted 37798b9484cSchristos (the register might not be a register per pe) 37898b9484cSchristos - queue the argument and return a marker saying the expression has been 37998b9484cSchristos queued (eg: a fix-up) 38098b9484cSchristos - return an error message indicating the expression wasn't recognizable 38198b9484cSchristos 38298b9484cSchristos The result is an error message or NULL for success. 38398b9484cSchristos The parsed value is stored in the bfd_vma *. */ 38498b9484cSchristos 38598b9484cSchristos /* Values for indicating what the caller wants. */ 38698b9484cSchristos 38798b9484cSchristos enum cgen_parse_operand_type 38898b9484cSchristos { 38998b9484cSchristos CGEN_PARSE_OPERAND_INIT, 39098b9484cSchristos CGEN_PARSE_OPERAND_INTEGER, 39198b9484cSchristos CGEN_PARSE_OPERAND_ADDRESS, 39298b9484cSchristos CGEN_PARSE_OPERAND_SYMBOLIC 39398b9484cSchristos }; 39498b9484cSchristos 39598b9484cSchristos /* Values for indicating what was parsed. */ 39698b9484cSchristos 39798b9484cSchristos enum cgen_parse_operand_result 39898b9484cSchristos { 39998b9484cSchristos CGEN_PARSE_OPERAND_RESULT_NUMBER, 40098b9484cSchristos CGEN_PARSE_OPERAND_RESULT_REGISTER, 40198b9484cSchristos CGEN_PARSE_OPERAND_RESULT_QUEUED, 40298b9484cSchristos CGEN_PARSE_OPERAND_RESULT_ERROR 40398b9484cSchristos }; 40498b9484cSchristos 40598b9484cSchristos #ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 40698b9484cSchristos typedef const char * (cgen_parse_operand_fn) 40798b9484cSchristos (CGEN_CPU_DESC, 40898b9484cSchristos enum cgen_parse_operand_type, const char **, int, int, 40998b9484cSchristos enum cgen_parse_operand_result *, bfd_vma *); 41098b9484cSchristos #else 41198b9484cSchristos typedef const char * (cgen_parse_operand_fn) (); 41298b9484cSchristos #endif 41398b9484cSchristos 41498b9484cSchristos /* Set the cgen_parse_operand_fn callback. */ 41598b9484cSchristos 41698b9484cSchristos extern void cgen_set_parse_operand_fn 41798b9484cSchristos (CGEN_CPU_DESC, cgen_parse_operand_fn); 41898b9484cSchristos 41998b9484cSchristos /* Called before trying to match a table entry with the insn. */ 42098b9484cSchristos 42198b9484cSchristos extern void cgen_init_parse_operand (CGEN_CPU_DESC); 42298b9484cSchristos 42398b9484cSchristos /* Operand values (keywords, integers, symbols, etc.) */ 42498b9484cSchristos 42598b9484cSchristos /* Types of assembler elements. */ 42698b9484cSchristos 42798b9484cSchristos enum cgen_asm_type 42898b9484cSchristos { 42998b9484cSchristos CGEN_ASM_NONE, CGEN_ASM_KEYWORD, CGEN_ASM_MAX 43098b9484cSchristos }; 43198b9484cSchristos 43298b9484cSchristos #ifndef CGEN_ARCH 43398b9484cSchristos enum cgen_hw_type { CGEN_HW_MAX }; 43498b9484cSchristos #endif 43598b9484cSchristos 43698b9484cSchristos /* List of hardware elements. */ 43798b9484cSchristos 43898b9484cSchristos typedef struct 43998b9484cSchristos { 44098b9484cSchristos char *name; 44198b9484cSchristos enum cgen_hw_type type; 44298b9484cSchristos /* There is currently no example where both index specs and value specs 44398b9484cSchristos are required, so for now both are clumped under "asm_data". */ 44498b9484cSchristos enum cgen_asm_type asm_type; 44598b9484cSchristos void *asm_data; 44698b9484cSchristos #ifndef CGEN_HW_NBOOL_ATTRS 44798b9484cSchristos #define CGEN_HW_NBOOL_ATTRS 1 44898b9484cSchristos #endif 44998b9484cSchristos CGEN_ATTR_TYPE (CGEN_HW_NBOOL_ATTRS) attrs; 45098b9484cSchristos #define CGEN_HW_ATTRS(hw) (&(hw)->attrs) 45198b9484cSchristos } CGEN_HW_ENTRY; 45298b9484cSchristos 45398b9484cSchristos /* Return value of attribute ATTR in HW. */ 45498b9484cSchristos 45598b9484cSchristos #define CGEN_HW_ATTR_VALUE(hw, attr) \ 45698b9484cSchristos CGEN_ATTR_VALUE ((hw), CGEN_HW_ATTRS (hw), (attr)) 45798b9484cSchristos 45898b9484cSchristos /* Table of hardware elements for selected mach, computed at runtime. 45998b9484cSchristos enum cgen_hw_type is an index into this table (specifically `entries'). */ 46098b9484cSchristos 46198b9484cSchristos typedef struct { 46298b9484cSchristos /* Pointer to null terminated table of all compiled in entries. */ 46398b9484cSchristos const CGEN_HW_ENTRY *init_entries; 46498b9484cSchristos unsigned int entry_size; /* since the attribute member is variable sized */ 46598b9484cSchristos /* Array of all entries, initial and run-time added. */ 46698b9484cSchristos const CGEN_HW_ENTRY **entries; 46798b9484cSchristos /* Number of elements in `entries'. */ 46898b9484cSchristos unsigned int num_entries; 46998b9484cSchristos /* For now, xrealloc is called each time a new entry is added at runtime. 47098b9484cSchristos ??? May wish to keep track of some slop to reduce the number of calls to 47198b9484cSchristos xrealloc, except that there's unlikely to be many and not expected to be 47298b9484cSchristos in speed critical code. */ 47398b9484cSchristos } CGEN_HW_TABLE; 47498b9484cSchristos 47598b9484cSchristos extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_name 47698b9484cSchristos (CGEN_CPU_DESC, const char *); 47798b9484cSchristos extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_num 47898b9484cSchristos (CGEN_CPU_DESC, unsigned int); 47998b9484cSchristos 48098b9484cSchristos /* This struct is used to describe things like register names, etc. */ 48198b9484cSchristos 48298b9484cSchristos typedef struct cgen_keyword_entry 48398b9484cSchristos { 48498b9484cSchristos /* Name (as in register name). */ 48598b9484cSchristos char * name; 48698b9484cSchristos 48798b9484cSchristos /* Value (as in register number). 48898b9484cSchristos The value cannot be -1 as that is used to indicate "not found". 48998b9484cSchristos IDEA: Have "FUNCTION" attribute? [function is called to fetch value]. */ 49098b9484cSchristos int value; 49198b9484cSchristos 49298b9484cSchristos /* Attributes. 49398b9484cSchristos This should, but technically needn't, appear last. It is a variable sized 49498b9484cSchristos array in that one architecture may have 1 nonbool attribute and another 49598b9484cSchristos may have more. Having this last means the non-architecture specific code 49698b9484cSchristos needn't care. The goal is to eventually record 49798b9484cSchristos attributes in their raw form, evaluate them at run-time, and cache the 49898b9484cSchristos values, so this worry will go away anyway. */ 49998b9484cSchristos /* ??? Moving this last should be done by treating keywords like insn lists 50098b9484cSchristos and moving the `next' fields into a CGEN_KEYWORD_LIST struct. */ 50198b9484cSchristos /* FIXME: Not used yet. */ 50298b9484cSchristos #ifndef CGEN_KEYWORD_NBOOL_ATTRS 50398b9484cSchristos #define CGEN_KEYWORD_NBOOL_ATTRS 1 50498b9484cSchristos #endif 50598b9484cSchristos CGEN_ATTR_TYPE (CGEN_KEYWORD_NBOOL_ATTRS) attrs; 50698b9484cSchristos 50798b9484cSchristos /* ??? Putting these here means compiled in entries can't be const. 50898b9484cSchristos Not a really big deal, but something to consider. */ 50998b9484cSchristos /* Next name hash table entry. */ 51098b9484cSchristos struct cgen_keyword_entry *next_name; 51198b9484cSchristos /* Next value hash table entry. */ 51298b9484cSchristos struct cgen_keyword_entry *next_value; 51398b9484cSchristos } CGEN_KEYWORD_ENTRY; 51498b9484cSchristos 51598b9484cSchristos /* Top level struct for describing a set of related keywords 51698b9484cSchristos (e.g. register names). 51798b9484cSchristos 51898b9484cSchristos This struct supports run-time entry of new values, and hashed lookups. */ 51998b9484cSchristos 52098b9484cSchristos typedef struct cgen_keyword 52198b9484cSchristos { 52298b9484cSchristos /* Pointer to initial [compiled in] values. */ 52398b9484cSchristos CGEN_KEYWORD_ENTRY *init_entries; 52498b9484cSchristos 52598b9484cSchristos /* Number of entries in `init_entries'. */ 52698b9484cSchristos unsigned int num_init_entries; 52798b9484cSchristos 52898b9484cSchristos /* Hash table used for name lookup. */ 52998b9484cSchristos CGEN_KEYWORD_ENTRY **name_hash_table; 53098b9484cSchristos 53198b9484cSchristos /* Hash table used for value lookup. */ 53298b9484cSchristos CGEN_KEYWORD_ENTRY **value_hash_table; 53398b9484cSchristos 53498b9484cSchristos /* Number of entries in the hash_tables. */ 53598b9484cSchristos unsigned int hash_table_size; 53698b9484cSchristos 53798b9484cSchristos /* Pointer to null keyword "" entry if present. */ 53898b9484cSchristos const CGEN_KEYWORD_ENTRY *null_entry; 53998b9484cSchristos 54098b9484cSchristos /* String containing non-alphanumeric characters used 54198b9484cSchristos in keywords. 54298b9484cSchristos At present, the highest number of entries used is 1. */ 54398b9484cSchristos char nonalpha_chars[8]; 54498b9484cSchristos } CGEN_KEYWORD; 54598b9484cSchristos 54698b9484cSchristos /* Structure used for searching. */ 54798b9484cSchristos 54898b9484cSchristos typedef struct 54998b9484cSchristos { 55098b9484cSchristos /* Table being searched. */ 55198b9484cSchristos const CGEN_KEYWORD *table; 55298b9484cSchristos 55398b9484cSchristos /* Specification of what is being searched for. */ 55498b9484cSchristos const char *spec; 55598b9484cSchristos 55698b9484cSchristos /* Current index in hash table. */ 55798b9484cSchristos unsigned int current_hash; 55898b9484cSchristos 55998b9484cSchristos /* Current element in current hash chain. */ 56098b9484cSchristos CGEN_KEYWORD_ENTRY *current_entry; 56198b9484cSchristos } CGEN_KEYWORD_SEARCH; 56298b9484cSchristos 56398b9484cSchristos /* Lookup a keyword from its name. */ 56498b9484cSchristos 56598b9484cSchristos const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_name 56698b9484cSchristos (CGEN_KEYWORD *, const char *); 56798b9484cSchristos 56898b9484cSchristos /* Lookup a keyword from its value. */ 56998b9484cSchristos 57098b9484cSchristos const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_value 57198b9484cSchristos (CGEN_KEYWORD *, int); 57298b9484cSchristos 57398b9484cSchristos /* Add a keyword. */ 57498b9484cSchristos 57598b9484cSchristos void cgen_keyword_add (CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *); 57698b9484cSchristos 57798b9484cSchristos /* Keyword searching. 57898b9484cSchristos This can be used to retrieve every keyword, or a subset. */ 57998b9484cSchristos 58098b9484cSchristos CGEN_KEYWORD_SEARCH cgen_keyword_search_init 58198b9484cSchristos (CGEN_KEYWORD *, const char *); 58298b9484cSchristos const CGEN_KEYWORD_ENTRY *cgen_keyword_search_next 58398b9484cSchristos (CGEN_KEYWORD_SEARCH *); 58498b9484cSchristos 58598b9484cSchristos /* Operand value support routines. */ 58698b9484cSchristos 58798b9484cSchristos extern const char *cgen_parse_keyword 58898b9484cSchristos (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); 58998b9484cSchristos #ifdef __BFD_H_SEEN__ /* Don't require bfd.h unnecessarily. */ 59098b9484cSchristos extern const char *cgen_parse_signed_integer 59198b9484cSchristos (CGEN_CPU_DESC, const char **, int, long *); 59298b9484cSchristos extern const char *cgen_parse_unsigned_integer 59398b9484cSchristos (CGEN_CPU_DESC, const char **, int, unsigned long *); 59498b9484cSchristos extern const char *cgen_parse_address 59598b9484cSchristos (CGEN_CPU_DESC, const char **, int, int, 59698b9484cSchristos enum cgen_parse_operand_result *, bfd_vma *); 59798b9484cSchristos extern const char *cgen_validate_signed_integer 59898b9484cSchristos (long, long, long); 59998b9484cSchristos extern const char *cgen_validate_unsigned_integer 60098b9484cSchristos (unsigned long, unsigned long, unsigned long); 60198b9484cSchristos #endif 60298b9484cSchristos 60398b9484cSchristos /* Operand modes. */ 60498b9484cSchristos 60598b9484cSchristos /* ??? This duplicates the values in arch.h. Revisit. 60698b9484cSchristos These however need the CGEN_ prefix [as does everything in this file]. */ 60798b9484cSchristos /* ??? Targets may need to add their own modes so we may wish to move this 60898b9484cSchristos to <arch>-opc.h, or add a hook. */ 60998b9484cSchristos 61098b9484cSchristos enum cgen_mode { 61198b9484cSchristos CGEN_MODE_VOID, /* ??? rename simulator's VM to VOID? */ 61298b9484cSchristos CGEN_MODE_BI, CGEN_MODE_QI, CGEN_MODE_HI, CGEN_MODE_SI, CGEN_MODE_DI, 61398b9484cSchristos CGEN_MODE_UBI, CGEN_MODE_UQI, CGEN_MODE_UHI, CGEN_MODE_USI, CGEN_MODE_UDI, 61498b9484cSchristos CGEN_MODE_SF, CGEN_MODE_DF, CGEN_MODE_XF, CGEN_MODE_TF, 61598b9484cSchristos CGEN_MODE_TARGET_MAX, 61698b9484cSchristos CGEN_MODE_INT, CGEN_MODE_UINT, 61798b9484cSchristos CGEN_MODE_MAX 61898b9484cSchristos }; 61998b9484cSchristos 62098b9484cSchristos /* FIXME: Until simulator is updated. */ 62198b9484cSchristos 62298b9484cSchristos #define CGEN_MODE_VM CGEN_MODE_VOID 62398b9484cSchristos 62498b9484cSchristos /* Operands. */ 62598b9484cSchristos 62698b9484cSchristos #ifndef CGEN_ARCH 62798b9484cSchristos enum cgen_operand_type { CGEN_OPERAND_MAX }; 62898b9484cSchristos #endif 62998b9484cSchristos 63098b9484cSchristos /* "nil" indicator for the operand instance table */ 63198b9484cSchristos #define CGEN_OPERAND_NIL CGEN_OPERAND_MAX 63298b9484cSchristos 63398b9484cSchristos /* A tree of these structs represents the multi-ifield 63498b9484cSchristos structure of an operand's hw-index value, if it exists. */ 63598b9484cSchristos 63698b9484cSchristos struct cgen_ifld; 63798b9484cSchristos 63898b9484cSchristos typedef struct cgen_maybe_multi_ifield 63998b9484cSchristos { 64098b9484cSchristos int count; /* 0: indexed by single cgen_ifld (possibly null: dead entry); 64198b9484cSchristos n: indexed by array of more cgen_maybe_multi_ifields. */ 64298b9484cSchristos union 64398b9484cSchristos { 64498b9484cSchristos const void *p; 64598b9484cSchristos const struct cgen_maybe_multi_ifield * multi; 64698b9484cSchristos const struct cgen_ifld * leaf; 64798b9484cSchristos } val; 64898b9484cSchristos } 64998b9484cSchristos CGEN_MAYBE_MULTI_IFLD; 65098b9484cSchristos 65198b9484cSchristos /* This struct defines each entry in the operand table. */ 65298b9484cSchristos 65398b9484cSchristos typedef struct 65498b9484cSchristos { 65598b9484cSchristos /* Name as it appears in the syntax string. */ 65698b9484cSchristos char *name; 65798b9484cSchristos 65898b9484cSchristos /* Operand type. */ 65998b9484cSchristos enum cgen_operand_type type; 66098b9484cSchristos 66198b9484cSchristos /* The hardware element associated with this operand. */ 66298b9484cSchristos enum cgen_hw_type hw_type; 66398b9484cSchristos 66498b9484cSchristos /* FIXME: We don't yet record ifield definitions, which we should. 66598b9484cSchristos When we do it might make sense to delete start/length (since they will 66698b9484cSchristos be duplicated in the ifield's definition) and replace them with a 66798b9484cSchristos pointer to the ifield entry. */ 66898b9484cSchristos 66998b9484cSchristos /* Bit position. 67098b9484cSchristos This is just a hint, and may be unused in more complex operands. 67198b9484cSchristos May be unused for a modifier. */ 67298b9484cSchristos unsigned char start; 67398b9484cSchristos 67498b9484cSchristos /* The number of bits in the operand. 67598b9484cSchristos This is just a hint, and may be unused in more complex operands. 67698b9484cSchristos May be unused for a modifier. */ 67798b9484cSchristos unsigned char length; 67898b9484cSchristos 67998b9484cSchristos /* The (possibly-multi) ifield used as an index for this operand, if it 68098b9484cSchristos is indexed by a field at all. This substitutes / extends the start and 68198b9484cSchristos length fields above, but unsure at this time whether they are used 68298b9484cSchristos anywhere. */ 68398b9484cSchristos CGEN_MAYBE_MULTI_IFLD index_fields; 68498b9484cSchristos #if 0 /* ??? Interesting idea but relocs tend to get too complicated, 68598b9484cSchristos and ABI dependent, for simple table lookups to work. */ 68698b9484cSchristos /* Ideally this would be the internal (external?) reloc type. */ 68798b9484cSchristos int reloc_type; 68898b9484cSchristos #endif 68998b9484cSchristos 69098b9484cSchristos /* Attributes. 69198b9484cSchristos This should, but technically needn't, appear last. It is a variable sized 69298b9484cSchristos array in that one architecture may have 1 nonbool attribute and another 69398b9484cSchristos may have more. Having this last means the non-architecture specific code 69498b9484cSchristos needn't care, now or tomorrow. The goal is to eventually record 69598b9484cSchristos attributes in their raw form, evaluate them at run-time, and cache the 69698b9484cSchristos values, so this worry will go away anyway. */ 69798b9484cSchristos #ifndef CGEN_OPERAND_NBOOL_ATTRS 69898b9484cSchristos #define CGEN_OPERAND_NBOOL_ATTRS 1 69998b9484cSchristos #endif 70098b9484cSchristos CGEN_ATTR_TYPE (CGEN_OPERAND_NBOOL_ATTRS) attrs; 70198b9484cSchristos #define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs) 70298b9484cSchristos } CGEN_OPERAND; 70398b9484cSchristos 70498b9484cSchristos /* Return value of attribute ATTR in OPERAND. */ 70598b9484cSchristos 70698b9484cSchristos #define CGEN_OPERAND_ATTR_VALUE(operand, attr) \ 70798b9484cSchristos CGEN_ATTR_VALUE ((operand), CGEN_OPERAND_ATTRS (operand), (attr)) 70898b9484cSchristos 70998b9484cSchristos /* Table of operands for selected mach/isa, computed at runtime. 71098b9484cSchristos enum cgen_operand_type is an index into this table (specifically 71198b9484cSchristos `entries'). */ 71298b9484cSchristos 71398b9484cSchristos typedef struct { 71498b9484cSchristos /* Pointer to null terminated table of all compiled in entries. */ 71598b9484cSchristos const CGEN_OPERAND *init_entries; 71698b9484cSchristos unsigned int entry_size; /* since the attribute member is variable sized */ 71798b9484cSchristos /* Array of all entries, initial and run-time added. */ 71898b9484cSchristos const CGEN_OPERAND **entries; 71998b9484cSchristos /* Number of elements in `entries'. */ 72098b9484cSchristos unsigned int num_entries; 72198b9484cSchristos /* For now, xrealloc is called each time a new entry is added at runtime. 72298b9484cSchristos ??? May wish to keep track of some slop to reduce the number of calls to 72398b9484cSchristos xrealloc, except that there's unlikely to be many and not expected to be 72498b9484cSchristos in speed critical code. */ 72598b9484cSchristos } CGEN_OPERAND_TABLE; 72698b9484cSchristos 72798b9484cSchristos extern const CGEN_OPERAND * cgen_operand_lookup_by_name 72898b9484cSchristos (CGEN_CPU_DESC, const char *); 72998b9484cSchristos extern const CGEN_OPERAND * cgen_operand_lookup_by_num 73098b9484cSchristos (CGEN_CPU_DESC, int); 73198b9484cSchristos 73298b9484cSchristos /* Instruction operand instances. 73398b9484cSchristos 73498b9484cSchristos For each instruction, a list of the hardware elements that are read and 73598b9484cSchristos written are recorded. */ 73698b9484cSchristos 73798b9484cSchristos /* The type of the instance. */ 73898b9484cSchristos 73998b9484cSchristos enum cgen_opinst_type { 74098b9484cSchristos /* End of table marker. */ 74198b9484cSchristos CGEN_OPINST_END = 0, 74298b9484cSchristos CGEN_OPINST_INPUT, CGEN_OPINST_OUTPUT 74398b9484cSchristos }; 74498b9484cSchristos 74598b9484cSchristos typedef struct 74698b9484cSchristos { 74798b9484cSchristos /* Input or output indicator. */ 74898b9484cSchristos enum cgen_opinst_type type; 74998b9484cSchristos 75098b9484cSchristos /* Name of operand. */ 75198b9484cSchristos const char *name; 75298b9484cSchristos 75398b9484cSchristos /* The hardware element referenced. */ 75498b9484cSchristos enum cgen_hw_type hw_type; 75598b9484cSchristos 75698b9484cSchristos /* The mode in which the operand is being used. */ 75798b9484cSchristos enum cgen_mode mode; 75898b9484cSchristos 75998b9484cSchristos /* The operand table entry CGEN_OPERAND_NIL if there is none 76098b9484cSchristos (i.e. an explicit hardware reference). */ 76198b9484cSchristos enum cgen_operand_type op_type; 76298b9484cSchristos 76398b9484cSchristos /* If `operand' is "nil", the index (e.g. into array of registers). */ 76498b9484cSchristos int index; 76598b9484cSchristos 76698b9484cSchristos /* Attributes. 76798b9484cSchristos ??? This perhaps should be a real attribute struct but there's 76898b9484cSchristos no current need, so we save a bit of space and just have a set of 76998b9484cSchristos flags. The interface is such that this can easily be made attributes 77098b9484cSchristos should it prove useful. */ 77198b9484cSchristos unsigned int attrs; 77298b9484cSchristos #define CGEN_OPINST_ATTRS(opinst) ((opinst)->attrs) 77398b9484cSchristos /* Return value of attribute ATTR in OPINST. */ 77498b9484cSchristos #define CGEN_OPINST_ATTR(opinst, attr) \ 77598b9484cSchristos ((CGEN_OPINST_ATTRS (opinst) & (attr)) != 0) 77698b9484cSchristos /* Operand is conditionally referenced (read/written). */ 77798b9484cSchristos #define CGEN_OPINST_COND_REF 1 77898b9484cSchristos } CGEN_OPINST; 77998b9484cSchristos 78098b9484cSchristos /* Syntax string. 78198b9484cSchristos 78298b9484cSchristos Each insn format and subexpression has one of these. 78398b9484cSchristos 78498b9484cSchristos The syntax "string" consists of characters (n > 0 && n < 128), and operand 78598b9484cSchristos values (n >= 128), and is terminated by 0. Operand values are 128 + index 78698b9484cSchristos into the operand table. The operand table doesn't exist in C, per se, as 78798b9484cSchristos the data is recorded in the parse/insert/extract/print switch statements. */ 78898b9484cSchristos 78998b9484cSchristos /* This should be at least as large as necessary for any target. */ 79098b9484cSchristos #define CGEN_MAX_SYNTAX_ELEMENTS 48 79198b9484cSchristos 79298b9484cSchristos /* A target may know its own precise maximum. Assert that it falls below 79398b9484cSchristos the above limit. */ 79498b9484cSchristos #ifdef CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 79598b9484cSchristos #if CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS > CGEN_MAX_SYNTAX_ELEMENTS 79698b9484cSchristos #error "CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS too high - enlarge CGEN_MAX_SYNTAX_ELEMENTS" 79798b9484cSchristos #endif 79898b9484cSchristos #endif 79998b9484cSchristos 80098b9484cSchristos typedef unsigned short CGEN_SYNTAX_CHAR_TYPE; 80198b9484cSchristos 80298b9484cSchristos typedef struct 80398b9484cSchristos { 80498b9484cSchristos CGEN_SYNTAX_CHAR_TYPE syntax[CGEN_MAX_SYNTAX_ELEMENTS]; 80598b9484cSchristos } CGEN_SYNTAX; 80698b9484cSchristos 80798b9484cSchristos #define CGEN_SYNTAX_STRING(syn) (syn->syntax) 80898b9484cSchristos #define CGEN_SYNTAX_CHAR_P(c) ((c) < 128) 80998b9484cSchristos #define CGEN_SYNTAX_CHAR(c) ((unsigned char)c) 81098b9484cSchristos #define CGEN_SYNTAX_FIELD(c) ((c) - 128) 81198b9484cSchristos #define CGEN_SYNTAX_MAKE_FIELD(c) ((c) + 128) 81298b9484cSchristos 81398b9484cSchristos /* ??? I can't currently think of any case where the mnemonic doesn't come 81498b9484cSchristos first [and if one ever doesn't building the hash tables will be tricky]. 81598b9484cSchristos However, we treat mnemonics as just another operand of the instruction. 81698b9484cSchristos A value of 1 means "this is where the mnemonic appears". 1 isn't 81798b9484cSchristos special other than it's a non-printable ASCII char. */ 81898b9484cSchristos 81998b9484cSchristos #define CGEN_SYNTAX_MNEMONIC 1 82098b9484cSchristos #define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == CGEN_SYNTAX_MNEMONIC) 82198b9484cSchristos 82298b9484cSchristos /* Instruction fields. 82398b9484cSchristos 82498b9484cSchristos ??? We currently don't allow adding fields at run-time. 82598b9484cSchristos Easy to fix when needed. */ 82698b9484cSchristos 82798b9484cSchristos typedef struct cgen_ifld { 82898b9484cSchristos /* Enum of ifield. */ 82998b9484cSchristos int num; 83098b9484cSchristos #define CGEN_IFLD_NUM(f) ((f)->num) 83198b9484cSchristos 83298b9484cSchristos /* Name of the field, distinguishes it from all other fields. */ 83398b9484cSchristos const char *name; 83498b9484cSchristos #define CGEN_IFLD_NAME(f) ((f)->name) 83598b9484cSchristos 83698b9484cSchristos /* Default offset, in bits, from the start of the insn to the word 83798b9484cSchristos containing the field. */ 83898b9484cSchristos int word_offset; 83998b9484cSchristos #define CGEN_IFLD_WORD_OFFSET(f) ((f)->word_offset) 84098b9484cSchristos 84198b9484cSchristos /* Default length of the word containing the field. */ 84298b9484cSchristos int word_size; 84398b9484cSchristos #define CGEN_IFLD_WORD_SIZE(f) ((f)->word_size) 84498b9484cSchristos 84598b9484cSchristos /* Default starting bit number. 84698b9484cSchristos Whether lsb=0 or msb=0 is determined by CGEN_INSN_LSB0_P. */ 84798b9484cSchristos int start; 84898b9484cSchristos #define CGEN_IFLD_START(f) ((f)->start) 84998b9484cSchristos 85098b9484cSchristos /* Length of the field, in bits. */ 85198b9484cSchristos int length; 85298b9484cSchristos #define CGEN_IFLD_LENGTH(f) ((f)->length) 85398b9484cSchristos 85498b9484cSchristos #ifndef CGEN_IFLD_NBOOL_ATTRS 85598b9484cSchristos #define CGEN_IFLD_NBOOL_ATTRS 1 85698b9484cSchristos #endif 85798b9484cSchristos CGEN_ATTR_TYPE (CGEN_IFLD_NBOOL_ATTRS) attrs; 85898b9484cSchristos #define CGEN_IFLD_ATTRS(f) (&(f)->attrs) 85998b9484cSchristos } CGEN_IFLD; 86098b9484cSchristos 86198b9484cSchristos /* Return value of attribute ATTR in IFLD. */ 86298b9484cSchristos #define CGEN_IFLD_ATTR_VALUE(ifld, attr) \ 86398b9484cSchristos CGEN_ATTR_VALUE ((ifld), CGEN_IFLD_ATTRS (ifld), (attr)) 86498b9484cSchristos 86598b9484cSchristos /* Instruction data. */ 86698b9484cSchristos 86798b9484cSchristos /* Instruction formats. 86898b9484cSchristos 86998b9484cSchristos Instructions are grouped by format. Associated with an instruction is its 87098b9484cSchristos format. Each insn's opcode table entry contains a format table entry. 87198b9484cSchristos ??? There is usually very few formats compared with the number of insns, 87298b9484cSchristos so one can reduce the size of the opcode table by recording the format table 87398b9484cSchristos as a separate entity. Given that we currently don't, format table entries 87498b9484cSchristos are also distinguished by their operands. This increases the size of the 87598b9484cSchristos table, but reduces the number of tables. It's all minutiae anyway so it 87698b9484cSchristos doesn't really matter [at this point in time]. 87798b9484cSchristos 87898b9484cSchristos ??? Support for variable length ISA's is wip. */ 87998b9484cSchristos 88098b9484cSchristos /* Accompanying each iformat description is a list of its fields. */ 88198b9484cSchristos 88298b9484cSchristos typedef struct { 88398b9484cSchristos const CGEN_IFLD *ifld; 88498b9484cSchristos #define CGEN_IFMT_IFLD_IFLD(ii) ((ii)->ifld) 88598b9484cSchristos } CGEN_IFMT_IFLD; 88698b9484cSchristos 88798b9484cSchristos /* This should be at least as large as necessary for any target. */ 88898b9484cSchristos #define CGEN_MAX_IFMT_OPERANDS 16 88998b9484cSchristos 89098b9484cSchristos /* A target may know its own precise maximum. Assert that it falls below 89198b9484cSchristos the above limit. */ 89298b9484cSchristos #ifdef CGEN_ACTUAL_MAX_IFMT_OPERANDS 89398b9484cSchristos #if CGEN_ACTUAL_MAX_IFMT_OPERANDS > CGEN_MAX_IFMT_OPERANDS 89498b9484cSchristos #error "CGEN_ACTUAL_MAX_IFMT_OPERANDS too high - enlarge CGEN_MAX_IFMT_OPERANDS" 89598b9484cSchristos #endif 89698b9484cSchristos #endif 89798b9484cSchristos 89898b9484cSchristos 89998b9484cSchristos typedef struct 90098b9484cSchristos { 90198b9484cSchristos /* Length that MASK and VALUE have been calculated to 90298b9484cSchristos [VALUE is recorded elsewhere]. 90398b9484cSchristos Normally it is base_insn_bitsize. On [V]LIW architectures where the base 90498b9484cSchristos insn size may be larger than the size of an insn, this field is less than 90598b9484cSchristos base_insn_bitsize. */ 90698b9484cSchristos unsigned char mask_length; 90798b9484cSchristos #define CGEN_IFMT_MASK_LENGTH(ifmt) ((ifmt)->mask_length) 90898b9484cSchristos 90998b9484cSchristos /* Total length of instruction, in bits. */ 91098b9484cSchristos unsigned char length; 91198b9484cSchristos #define CGEN_IFMT_LENGTH(ifmt) ((ifmt)->length) 91298b9484cSchristos 91398b9484cSchristos /* Mask to apply to the first MASK_LENGTH bits. 91498b9484cSchristos Each insn's value is stored with the insn. 91598b9484cSchristos The first step in recognizing an insn for disassembly is 91698b9484cSchristos (opcode & mask) == value. */ 917*02f41505Schristos CGEN_INSN_LGUINT mask; 91898b9484cSchristos #define CGEN_IFMT_MASK(ifmt) ((ifmt)->mask) 91998b9484cSchristos 92098b9484cSchristos /* Instruction fields. 92198b9484cSchristos +1 for trailing NULL. */ 92298b9484cSchristos CGEN_IFMT_IFLD iflds[CGEN_MAX_IFMT_OPERANDS + 1]; 92398b9484cSchristos #define CGEN_IFMT_IFLDS(ifmt) ((ifmt)->iflds) 92498b9484cSchristos } CGEN_IFMT; 92598b9484cSchristos 92698b9484cSchristos /* Instruction values. */ 92798b9484cSchristos 92898b9484cSchristos typedef struct 92998b9484cSchristos { 93098b9484cSchristos /* The opcode portion of the base insn. */ 93198b9484cSchristos CGEN_INSN_INT base_value; 93298b9484cSchristos 93398b9484cSchristos #ifdef CGEN_MAX_EXTRA_OPCODE_OPERANDS 93498b9484cSchristos /* Extra opcode values beyond base_value. */ 93598b9484cSchristos unsigned long ifield_values[CGEN_MAX_EXTRA_OPCODE_OPERANDS]; 93698b9484cSchristos #endif 93798b9484cSchristos } CGEN_IVALUE; 93898b9484cSchristos 93998b9484cSchristos /* Instruction opcode table. 94098b9484cSchristos This contains the syntax and format data of an instruction. */ 94198b9484cSchristos 94298b9484cSchristos /* ??? Some ports already have an opcode table yet still need to use the rest 94398b9484cSchristos of what cgen_insn has. Plus keeping the opcode data with the operand 94498b9484cSchristos instance data can create a pretty big file. So we keep them separately. 94598b9484cSchristos Not sure this is a good idea in the long run. */ 94698b9484cSchristos 94798b9484cSchristos typedef struct 94898b9484cSchristos { 94998b9484cSchristos /* Indices into parse/insert/extract/print handler tables. */ 95098b9484cSchristos struct cgen_opcode_handler handlers; 95198b9484cSchristos #define CGEN_OPCODE_HANDLERS(opc) (& (opc)->handlers) 95298b9484cSchristos 95398b9484cSchristos /* Syntax string. */ 95498b9484cSchristos CGEN_SYNTAX syntax; 95598b9484cSchristos #define CGEN_OPCODE_SYNTAX(opc) (& (opc)->syntax) 95698b9484cSchristos 95798b9484cSchristos /* Format entry. */ 95898b9484cSchristos const CGEN_IFMT *format; 95998b9484cSchristos #define CGEN_OPCODE_FORMAT(opc) ((opc)->format) 96098b9484cSchristos #define CGEN_OPCODE_MASK_BITSIZE(opc) CGEN_IFMT_MASK_LENGTH (CGEN_OPCODE_FORMAT (opc)) 96198b9484cSchristos #define CGEN_OPCODE_BITSIZE(opc) CGEN_IFMT_LENGTH (CGEN_OPCODE_FORMAT (opc)) 96298b9484cSchristos #define CGEN_OPCODE_IFLDS(opc) CGEN_IFMT_IFLDS (CGEN_OPCODE_FORMAT (opc)) 96398b9484cSchristos 96498b9484cSchristos /* Instruction opcode value. */ 96598b9484cSchristos CGEN_IVALUE value; 96698b9484cSchristos #define CGEN_OPCODE_VALUE(opc) (& (opc)->value) 96798b9484cSchristos #define CGEN_OPCODE_BASE_VALUE(opc) (CGEN_OPCODE_VALUE (opc)->base_value) 96898b9484cSchristos #define CGEN_OPCODE_BASE_MASK(opc) CGEN_IFMT_MASK (CGEN_OPCODE_FORMAT (opc)) 96998b9484cSchristos } CGEN_OPCODE; 97098b9484cSchristos 97198b9484cSchristos /* Instruction attributes. 97298b9484cSchristos This is made a published type as applications can cache a pointer to 97398b9484cSchristos the attributes for speed. */ 97498b9484cSchristos 97598b9484cSchristos #ifndef CGEN_INSN_NBOOL_ATTRS 97698b9484cSchristos #define CGEN_INSN_NBOOL_ATTRS 1 97798b9484cSchristos #endif 97898b9484cSchristos typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE; 97998b9484cSchristos 98098b9484cSchristos /* Enum of architecture independent attributes. */ 98198b9484cSchristos 98298b9484cSchristos #ifndef CGEN_ARCH 98398b9484cSchristos /* ??? Numbers here are recorded in two places. */ 98498b9484cSchristos typedef enum cgen_insn_attr { 98598b9484cSchristos CGEN_INSN_ALIAS = 0 98698b9484cSchristos } CGEN_INSN_ATTR; 98798b9484cSchristos #define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) ((attrs)->bool_ & (1 << CGEN_INSN_ALIAS)) 98898b9484cSchristos #endif 98998b9484cSchristos 99098b9484cSchristos /* This struct defines each entry in the instruction table. */ 99198b9484cSchristos 99298b9484cSchristos typedef struct 99398b9484cSchristos { 99498b9484cSchristos /* Each real instruction is enumerated. */ 99598b9484cSchristos /* ??? This may go away in time. */ 99698b9484cSchristos int num; 99798b9484cSchristos #define CGEN_INSN_NUM(insn) ((insn)->base->num) 99898b9484cSchristos 99998b9484cSchristos /* Name of entry (that distinguishes it from all other entries). */ 100098b9484cSchristos /* ??? If mnemonics have operands, try to print full mnemonic. */ 100198b9484cSchristos const char *name; 100298b9484cSchristos #define CGEN_INSN_NAME(insn) ((insn)->base->name) 100398b9484cSchristos 100498b9484cSchristos /* Mnemonic. This is used when parsing and printing the insn. 100598b9484cSchristos In the case of insns that have operands on the mnemonics, this is 100698b9484cSchristos only the constant part. E.g. for conditional execution of an `add' insn, 100798b9484cSchristos where the full mnemonic is addeq, addne, etc., and the condition is 100898b9484cSchristos treated as an operand, this is only "add". */ 100998b9484cSchristos const char *mnemonic; 101098b9484cSchristos #define CGEN_INSN_MNEMONIC(insn) ((insn)->base->mnemonic) 101198b9484cSchristos 101298b9484cSchristos /* Total length of instruction, in bits. */ 101398b9484cSchristos int bitsize; 101498b9484cSchristos #define CGEN_INSN_BITSIZE(insn) ((insn)->base->bitsize) 101598b9484cSchristos 101698b9484cSchristos #if 0 /* ??? Disabled for now as there is a problem with embedded newlines 101798b9484cSchristos and the table is already pretty big. Should perhaps be moved 101898b9484cSchristos to a file of its own. */ 101998b9484cSchristos /* Semantics, as RTL. */ 102098b9484cSchristos /* ??? Plain text or bytecodes? */ 102198b9484cSchristos /* ??? Note that the operand instance table could be computed at run-time 102298b9484cSchristos if we parse this and cache the results. Something to eventually do. */ 102398b9484cSchristos const char *rtx; 102498b9484cSchristos #define CGEN_INSN_RTX(insn) ((insn)->base->rtx) 102598b9484cSchristos #endif 102698b9484cSchristos 102798b9484cSchristos /* Attributes. 102898b9484cSchristos This must appear last. It is a variable sized array in that one 102998b9484cSchristos architecture may have 1 nonbool attribute and another may have more. 103098b9484cSchristos Having this last means the non-architecture specific code needn't 103198b9484cSchristos care. The goal is to eventually record attributes in their raw form, 103298b9484cSchristos evaluate them at run-time, and cache the values, so this worry will go 103398b9484cSchristos away anyway. */ 103498b9484cSchristos CGEN_INSN_ATTR_TYPE attrs; 103598b9484cSchristos #define CGEN_INSN_ATTRS(insn) (&(insn)->base->attrs) 103698b9484cSchristos /* Return value of attribute ATTR in INSN. */ 103798b9484cSchristos #define CGEN_INSN_ATTR_VALUE(insn, attr) \ 103898b9484cSchristos CGEN_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 103998b9484cSchristos #define CGEN_INSN_BITSET_ATTR_VALUE(insn, attr) \ 104098b9484cSchristos CGEN_BITSET_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr)) 104198b9484cSchristos } CGEN_IBASE; 104298b9484cSchristos 104398b9484cSchristos /* Return non-zero if INSN is the "invalid" insn marker. */ 104498b9484cSchristos 104598b9484cSchristos #define CGEN_INSN_INVALID_P(insn) (CGEN_INSN_MNEMONIC (insn) == 0) 104698b9484cSchristos 104798b9484cSchristos /* Main struct contain instruction information. 104898b9484cSchristos BASE is always present, the rest is present only if asked for. */ 104998b9484cSchristos 105098b9484cSchristos struct cgen_insn 105198b9484cSchristos { 105298b9484cSchristos /* ??? May be of use to put a type indicator here. 105398b9484cSchristos Then this struct could different info for different classes of insns. */ 105498b9484cSchristos /* ??? A speedup can be had by moving `base' into this struct. 105598b9484cSchristos Maybe later. */ 105698b9484cSchristos const CGEN_IBASE *base; 105798b9484cSchristos const CGEN_OPCODE *opcode; 105898b9484cSchristos const CGEN_OPINST *opinst; 105998b9484cSchristos 106098b9484cSchristos /* Regex to disambiguate overloaded opcodes */ 106198b9484cSchristos void *rx; 106298b9484cSchristos #define CGEN_INSN_RX(insn) ((insn)->rx) 106398b9484cSchristos #define CGEN_MAX_RX_ELEMENTS (CGEN_MAX_SYNTAX_ELEMENTS * 5) 106498b9484cSchristos }; 106598b9484cSchristos 106698b9484cSchristos /* Instruction lists. 106798b9484cSchristos This is used for adding new entries and for creating the hash lists. */ 106898b9484cSchristos 106998b9484cSchristos typedef struct cgen_insn_list 107098b9484cSchristos { 107198b9484cSchristos struct cgen_insn_list *next; 107298b9484cSchristos const CGEN_INSN *insn; 107398b9484cSchristos } CGEN_INSN_LIST; 107498b9484cSchristos 107598b9484cSchristos /* Table of instructions. */ 107698b9484cSchristos 107798b9484cSchristos typedef struct 107898b9484cSchristos { 107998b9484cSchristos const CGEN_INSN *init_entries; 108098b9484cSchristos unsigned int entry_size; /* since the attribute member is variable sized */ 108198b9484cSchristos unsigned int num_init_entries; 108298b9484cSchristos CGEN_INSN_LIST *new_entries; 108398b9484cSchristos } CGEN_INSN_TABLE; 108498b9484cSchristos 108598b9484cSchristos /* Return number of instructions. This includes any added at run-time. */ 108698b9484cSchristos 108798b9484cSchristos extern int cgen_insn_count (CGEN_CPU_DESC); 108898b9484cSchristos extern int cgen_macro_insn_count (CGEN_CPU_DESC); 108998b9484cSchristos 109098b9484cSchristos /* Macros to access the other insn elements not recorded in CGEN_IBASE. */ 109198b9484cSchristos 109298b9484cSchristos /* Fetch INSN's operand instance table. */ 109398b9484cSchristos /* ??? Doesn't handle insns added at runtime. */ 109498b9484cSchristos #define CGEN_INSN_OPERANDS(insn) ((insn)->opinst) 109598b9484cSchristos 109698b9484cSchristos /* Return INSN's opcode table entry. */ 109798b9484cSchristos #define CGEN_INSN_OPCODE(insn) ((insn)->opcode) 109898b9484cSchristos 109998b9484cSchristos /* Return INSN's handler data. */ 110098b9484cSchristos #define CGEN_INSN_HANDLERS(insn) CGEN_OPCODE_HANDLERS (CGEN_INSN_OPCODE (insn)) 110198b9484cSchristos 110298b9484cSchristos /* Return INSN's syntax. */ 110398b9484cSchristos #define CGEN_INSN_SYNTAX(insn) CGEN_OPCODE_SYNTAX (CGEN_INSN_OPCODE (insn)) 110498b9484cSchristos 110598b9484cSchristos /* Return size of base mask in bits. */ 110698b9484cSchristos #define CGEN_INSN_MASK_BITSIZE(insn) \ 110798b9484cSchristos CGEN_OPCODE_MASK_BITSIZE (CGEN_INSN_OPCODE (insn)) 110898b9484cSchristos 110998b9484cSchristos /* Return mask of base part of INSN. */ 111098b9484cSchristos #define CGEN_INSN_BASE_MASK(insn) \ 111198b9484cSchristos CGEN_OPCODE_BASE_MASK (CGEN_INSN_OPCODE (insn)) 111298b9484cSchristos 111398b9484cSchristos /* Return value of base part of INSN. */ 111498b9484cSchristos #define CGEN_INSN_BASE_VALUE(insn) \ 111598b9484cSchristos CGEN_OPCODE_BASE_VALUE (CGEN_INSN_OPCODE (insn)) 111698b9484cSchristos 111798b9484cSchristos /* Standard way to test whether INSN is supported by MACH. 111898b9484cSchristos MACH is one of enum mach_attr. 111998b9484cSchristos The "|1" is because the base mach is always selected. */ 112098b9484cSchristos #define CGEN_INSN_MACH_HAS_P(insn, mach) \ 112198b9484cSchristos ((CGEN_INSN_ATTR_VALUE ((insn), CGEN_INSN_MACH) & ((1 << (mach)) | 1)) != 0) 112298b9484cSchristos 112398b9484cSchristos /* Macro instructions. 112498b9484cSchristos Macro insns aren't real insns, they map to one or more real insns. 112598b9484cSchristos E.g. An architecture's "nop" insn may actually be an "mv r0,r0" or 112698b9484cSchristos some such. 112798b9484cSchristos 112898b9484cSchristos Macro insns can expand to nothing (e.g. a nop that is optimized away). 112998b9484cSchristos This is useful in multi-insn macros that build a constant in a register. 113098b9484cSchristos Of course this isn't the default behaviour and must be explicitly enabled. 113198b9484cSchristos 113298b9484cSchristos Assembly of macro-insns is relatively straightforward. Disassembly isn't. 113398b9484cSchristos However, disassembly of at least some kinds of macro insns is important 113498b9484cSchristos in order that the disassembled code preserve the readability of the original 113598b9484cSchristos insn. What is attempted here is to disassemble all "simple" macro-insns, 113698b9484cSchristos where "simple" is currently defined to mean "expands to one real insn". 113798b9484cSchristos 113898b9484cSchristos Simple macro-insns are handled specially. They are emitted as ALIAS's 113998b9484cSchristos of real insns. This simplifies their handling since there's usually more 114098b9484cSchristos of them than any other kind of macro-insn, and proper disassembly of them 114198b9484cSchristos falls out for free. */ 114298b9484cSchristos 114398b9484cSchristos /* For each macro-insn there may be multiple expansion possibilities, 114498b9484cSchristos depending on the arguments. This structure is accessed via the `data' 114598b9484cSchristos member of CGEN_INSN. */ 114698b9484cSchristos 114798b9484cSchristos typedef struct cgen_minsn_expansion { 114898b9484cSchristos /* Function to do the expansion. 114998b9484cSchristos If the expansion fails (e.g. "no match") NULL is returned. 115098b9484cSchristos Space for the expansion is obtained with malloc. 115198b9484cSchristos It is up to the caller to free it. */ 115298b9484cSchristos const char * (* fn) 115398b9484cSchristos (const struct cgen_minsn_expansion *, 115498b9484cSchristos const char *, const char **, int *, 115598b9484cSchristos CGEN_OPERAND **); 115698b9484cSchristos #define CGEN_MIEXPN_FN(ex) ((ex)->fn) 115798b9484cSchristos 115898b9484cSchristos /* Instruction(s) the macro expands to. 115998b9484cSchristos The format of STR is defined by FN. 116098b9484cSchristos It is typically the assembly code of the real insn, but it could also be 116198b9484cSchristos the original Scheme expression or a tokenized form of it (with FN being 116298b9484cSchristos an appropriate interpreter). */ 116398b9484cSchristos const char * str; 116498b9484cSchristos #define CGEN_MIEXPN_STR(ex) ((ex)->str) 116598b9484cSchristos } CGEN_MINSN_EXPANSION; 116698b9484cSchristos 116798b9484cSchristos /* Normal expander. 116898b9484cSchristos When supported, this function will convert the input string to another 116998b9484cSchristos string and the parser will be invoked recursively. The output string 117098b9484cSchristos may contain further macro invocations. */ 117198b9484cSchristos 117298b9484cSchristos extern const char * cgen_expand_macro_insn 117398b9484cSchristos (CGEN_CPU_DESC, const struct cgen_minsn_expansion *, 117498b9484cSchristos const char *, const char **, int *, CGEN_OPERAND **); 117598b9484cSchristos 117698b9484cSchristos /* The assembler insn table is hashed based on some function of the mnemonic 117798b9484cSchristos (the actually hashing done is up to the target, but we provide a few 117898b9484cSchristos examples like the first letter or a function of the entire mnemonic). */ 117998b9484cSchristos 118098b9484cSchristos extern CGEN_INSN_LIST * cgen_asm_lookup_insn 118198b9484cSchristos (CGEN_CPU_DESC, const char *); 118298b9484cSchristos #define CGEN_ASM_LOOKUP_INSN(cd, string) cgen_asm_lookup_insn ((cd), (string)) 118398b9484cSchristos #define CGEN_ASM_NEXT_INSN(insn) ((insn)->next) 118498b9484cSchristos 118598b9484cSchristos /* The disassembler insn table is hashed based on some function of machine 118698b9484cSchristos instruction (the actually hashing done is up to the target). */ 118798b9484cSchristos 118898b9484cSchristos extern CGEN_INSN_LIST * cgen_dis_lookup_insn 118998b9484cSchristos (CGEN_CPU_DESC, const char *, CGEN_INSN_INT); 119098b9484cSchristos /* FIXME: delete these two */ 119198b9484cSchristos #define CGEN_DIS_LOOKUP_INSN(cd, buf, value) cgen_dis_lookup_insn ((cd), (buf), (value)) 119298b9484cSchristos #define CGEN_DIS_NEXT_INSN(insn) ((insn)->next) 119398b9484cSchristos 119498b9484cSchristos /* The CPU description. 119598b9484cSchristos A copy of this is created when the cpu table is "opened". 119698b9484cSchristos All global state information is recorded here. 119798b9484cSchristos Access macros are provided for "public" members. */ 119898b9484cSchristos 119998b9484cSchristos typedef struct cgen_cpu_desc 120098b9484cSchristos { 120198b9484cSchristos /* Bitmap of selected machine(s) (a la BFD machine number). */ 120298b9484cSchristos int machs; 120398b9484cSchristos 120498b9484cSchristos /* Bitmap of selected isa(s). */ 120598b9484cSchristos CGEN_BITSET *isas; 120698b9484cSchristos #define CGEN_CPU_ISAS(cd) ((cd)->isas) 120798b9484cSchristos 120898b9484cSchristos /* Current endian. */ 120998b9484cSchristos enum cgen_endian endian; 121098b9484cSchristos #define CGEN_CPU_ENDIAN(cd) ((cd)->endian) 121198b9484cSchristos 121298b9484cSchristos /* Current insn endian. */ 121398b9484cSchristos enum cgen_endian insn_endian; 121498b9484cSchristos #define CGEN_CPU_INSN_ENDIAN(cd) ((cd)->insn_endian) 121598b9484cSchristos 121698b9484cSchristos /* Word size (in bits). */ 121798b9484cSchristos /* ??? Or maybe maximum word size - might we ever need to allow a cpu table 121898b9484cSchristos to be opened for both sparc32/sparc64? 121998b9484cSchristos ??? Another alternative is to create a table of selected machs and 122098b9484cSchristos lazily fetch the data from there. */ 122198b9484cSchristos unsigned int word_bitsize; 122298b9484cSchristos 122398b9484cSchristos /* Instruction chunk size (in bits), for purposes of endianness 122498b9484cSchristos conversion. */ 122598b9484cSchristos unsigned int insn_chunk_bitsize; 122698b9484cSchristos 122798b9484cSchristos /* Indicator if sizes are unknown. 122898b9484cSchristos This is used by default_insn_bitsize,base_insn_bitsize if there is a 122998b9484cSchristos difference between the selected isa's. */ 123098b9484cSchristos #define CGEN_SIZE_UNKNOWN 65535 123198b9484cSchristos 123298b9484cSchristos /* Default instruction size (in bits). 123398b9484cSchristos This is used by the assembler when it encounters an unknown insn. */ 123498b9484cSchristos unsigned int default_insn_bitsize; 123598b9484cSchristos 123698b9484cSchristos /* Base instruction size (in bits). 123798b9484cSchristos For non-LIW cpus this is generally the length of the smallest insn. 123898b9484cSchristos For LIW cpus its wip (work-in-progress). For the m32r its 32. */ 123998b9484cSchristos unsigned int base_insn_bitsize; 124098b9484cSchristos 124198b9484cSchristos /* Minimum/maximum instruction size (in bits). */ 124298b9484cSchristos unsigned int min_insn_bitsize; 124398b9484cSchristos unsigned int max_insn_bitsize; 124498b9484cSchristos 124598b9484cSchristos /* Instruction set variants. */ 124698b9484cSchristos const CGEN_ISA *isa_table; 124798b9484cSchristos 124898b9484cSchristos /* Machine variants. */ 124998b9484cSchristos const CGEN_MACH *mach_table; 125098b9484cSchristos 125198b9484cSchristos /* Hardware elements. */ 125298b9484cSchristos CGEN_HW_TABLE hw_table; 125398b9484cSchristos 125498b9484cSchristos /* Instruction fields. */ 125598b9484cSchristos const CGEN_IFLD *ifld_table; 125698b9484cSchristos 125798b9484cSchristos /* Operands. */ 125898b9484cSchristos CGEN_OPERAND_TABLE operand_table; 125998b9484cSchristos 126098b9484cSchristos /* Main instruction table. */ 126198b9484cSchristos CGEN_INSN_TABLE insn_table; 126298b9484cSchristos #define CGEN_CPU_INSN_TABLE(cd) (& (cd)->insn_table) 126398b9484cSchristos 126498b9484cSchristos /* Macro instructions are defined separately and are combined with real 126598b9484cSchristos insns during hash table computation. */ 126698b9484cSchristos CGEN_INSN_TABLE macro_insn_table; 126798b9484cSchristos 126898b9484cSchristos /* Copy of CGEN_INT_INSN_P. */ 126998b9484cSchristos int int_insn_p; 127098b9484cSchristos 127198b9484cSchristos /* Called to rebuild the tables after something has changed. */ 127298b9484cSchristos void (*rebuild_tables) (CGEN_CPU_DESC); 127398b9484cSchristos 127498b9484cSchristos /* Operand parser callback. */ 127598b9484cSchristos cgen_parse_operand_fn * parse_operand_fn; 127698b9484cSchristos 127798b9484cSchristos /* Parse/insert/extract/print cover fns for operands. */ 127898b9484cSchristos const char * (*parse_operand) 127998b9484cSchristos (CGEN_CPU_DESC, int opindex_, const char **, CGEN_FIELDS *fields_); 128098b9484cSchristos #ifdef __BFD_H_SEEN__ 128198b9484cSchristos const char * (*insert_operand) 128298b9484cSchristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, 128398b9484cSchristos CGEN_INSN_BYTES_PTR, bfd_vma pc_); 128498b9484cSchristos int (*extract_operand) 128598b9484cSchristos (CGEN_CPU_DESC, int opindex_, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, 128698b9484cSchristos CGEN_FIELDS *fields_, bfd_vma pc_); 128798b9484cSchristos void (*print_operand) 128898b9484cSchristos (CGEN_CPU_DESC, int opindex_, void * info_, CGEN_FIELDS * fields_, 128998b9484cSchristos void const *attrs_, bfd_vma pc_, int length_); 129098b9484cSchristos #else 129198b9484cSchristos const char * (*insert_operand) (); 129298b9484cSchristos int (*extract_operand) (); 129398b9484cSchristos void (*print_operand) (); 129498b9484cSchristos #endif 129598b9484cSchristos #define CGEN_CPU_PARSE_OPERAND(cd) ((cd)->parse_operand) 129698b9484cSchristos #define CGEN_CPU_INSERT_OPERAND(cd) ((cd)->insert_operand) 129798b9484cSchristos #define CGEN_CPU_EXTRACT_OPERAND(cd) ((cd)->extract_operand) 129898b9484cSchristos #define CGEN_CPU_PRINT_OPERAND(cd) ((cd)->print_operand) 129998b9484cSchristos 130098b9484cSchristos /* Size of CGEN_FIELDS struct. */ 130198b9484cSchristos unsigned int sizeof_fields; 130298b9484cSchristos #define CGEN_CPU_SIZEOF_FIELDS(cd) ((cd)->sizeof_fields) 130398b9484cSchristos 130498b9484cSchristos /* Set the bitsize field. */ 130598b9484cSchristos void (*set_fields_bitsize) (CGEN_FIELDS *fields_, int size_); 130698b9484cSchristos #define CGEN_CPU_SET_FIELDS_BITSIZE(cd) ((cd)->set_fields_bitsize) 130798b9484cSchristos 130898b9484cSchristos /* CGEN_FIELDS accessors. */ 130998b9484cSchristos int (*get_int_operand) 131098b9484cSchristos (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 131198b9484cSchristos void (*set_int_operand) 131298b9484cSchristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, int value_); 131398b9484cSchristos #ifdef __BFD_H_SEEN__ 131498b9484cSchristos bfd_vma (*get_vma_operand) 131598b9484cSchristos (CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_); 131698b9484cSchristos void (*set_vma_operand) 131798b9484cSchristos (CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, bfd_vma value_); 131898b9484cSchristos #else 131998b9484cSchristos long (*get_vma_operand) (); 132098b9484cSchristos void (*set_vma_operand) (); 132198b9484cSchristos #endif 132298b9484cSchristos #define CGEN_CPU_GET_INT_OPERAND(cd) ((cd)->get_int_operand) 132398b9484cSchristos #define CGEN_CPU_SET_INT_OPERAND(cd) ((cd)->set_int_operand) 132498b9484cSchristos #define CGEN_CPU_GET_VMA_OPERAND(cd) ((cd)->get_vma_operand) 132598b9484cSchristos #define CGEN_CPU_SET_VMA_OPERAND(cd) ((cd)->set_vma_operand) 132698b9484cSchristos 132798b9484cSchristos /* Instruction parse/insert/extract/print handlers. */ 132898b9484cSchristos /* FIXME: make these types uppercase. */ 132998b9484cSchristos cgen_parse_fn * const *parse_handlers; 133098b9484cSchristos cgen_insert_fn * const *insert_handlers; 133198b9484cSchristos cgen_extract_fn * const *extract_handlers; 133298b9484cSchristos cgen_print_fn * const *print_handlers; 133398b9484cSchristos #define CGEN_PARSE_FN(cd, insn) (cd->parse_handlers[(insn)->opcode->handlers.parse]) 133498b9484cSchristos #define CGEN_INSERT_FN(cd, insn) (cd->insert_handlers[(insn)->opcode->handlers.insert]) 133598b9484cSchristos #define CGEN_EXTRACT_FN(cd, insn) (cd->extract_handlers[(insn)->opcode->handlers.extract]) 133698b9484cSchristos #define CGEN_PRINT_FN(cd, insn) (cd->print_handlers[(insn)->opcode->handlers.print]) 133798b9484cSchristos 133898b9484cSchristos /* Return non-zero if insn should be added to hash table. */ 133998b9484cSchristos int (* asm_hash_p) (const CGEN_INSN *); 134098b9484cSchristos 134198b9484cSchristos /* Assembler hash function. */ 134298b9484cSchristos unsigned int (* asm_hash) (const char *); 134398b9484cSchristos 134498b9484cSchristos /* Number of entries in assembler hash table. */ 134598b9484cSchristos unsigned int asm_hash_size; 134698b9484cSchristos 134798b9484cSchristos /* Return non-zero if insn should be added to hash table. */ 134898b9484cSchristos int (* dis_hash_p) (const CGEN_INSN *); 134998b9484cSchristos 135098b9484cSchristos /* Disassembler hash function. */ 135198b9484cSchristos unsigned int (* dis_hash) (const char *, CGEN_INSN_INT); 135298b9484cSchristos 135398b9484cSchristos /* Number of entries in disassembler hash table. */ 135498b9484cSchristos unsigned int dis_hash_size; 135598b9484cSchristos 135698b9484cSchristos /* Assembler instruction hash table. */ 135798b9484cSchristos CGEN_INSN_LIST **asm_hash_table; 135898b9484cSchristos CGEN_INSN_LIST *asm_hash_table_entries; 135998b9484cSchristos 136098b9484cSchristos /* Disassembler instruction hash table. */ 136198b9484cSchristos CGEN_INSN_LIST **dis_hash_table; 136298b9484cSchristos CGEN_INSN_LIST *dis_hash_table_entries; 136398b9484cSchristos 136498b9484cSchristos /* This field could be turned into a bitfield if room for other flags is needed. */ 136598b9484cSchristos unsigned int signed_overflow_ok_p; 136698b9484cSchristos 136798b9484cSchristos } CGEN_CPU_TABLE; 136898b9484cSchristos 136998b9484cSchristos /* wip */ 137098b9484cSchristos #ifndef CGEN_WORD_ENDIAN 137198b9484cSchristos #define CGEN_WORD_ENDIAN(cd) CGEN_CPU_ENDIAN (cd) 137298b9484cSchristos #endif 137398b9484cSchristos #ifndef CGEN_INSN_WORD_ENDIAN 137498b9484cSchristos #define CGEN_INSN_WORD_ENDIAN(cd) CGEN_CPU_INSN_ENDIAN (cd) 137598b9484cSchristos #endif 137698b9484cSchristos 137798b9484cSchristos /* Prototypes of major functions. */ 137898b9484cSchristos /* FIXME: Move more CGEN_SYM-defined functions into CGEN_CPU_DESC. 137998b9484cSchristos Not the init fns though, as that would drag in things that mightn't be 138098b9484cSchristos used and might not even exist. */ 138198b9484cSchristos 138298b9484cSchristos /* Argument types to cpu_open. */ 138398b9484cSchristos 138498b9484cSchristos enum cgen_cpu_open_arg { 138598b9484cSchristos CGEN_CPU_OPEN_END, 138698b9484cSchristos /* Select instruction set(s), arg is bitmap or 0 meaning "unspecified". */ 138798b9484cSchristos CGEN_CPU_OPEN_ISAS, 138898b9484cSchristos /* Select machine(s), arg is bitmap or 0 meaning "unspecified". */ 138998b9484cSchristos CGEN_CPU_OPEN_MACHS, 139098b9484cSchristos /* Select machine, arg is mach's bfd name. 139198b9484cSchristos Multiple machines can be specified by repeated use. */ 139298b9484cSchristos CGEN_CPU_OPEN_BFDMACH, 139398b9484cSchristos /* Select endian, arg is CGEN_ENDIAN_*. */ 13948dffb485Schristos CGEN_CPU_OPEN_ENDIAN, 13958dffb485Schristos /* Select instruction endian, arg is CGEN_ENDIAN_*. */ 13968dffb485Schristos CGEN_CPU_OPEN_INSN_ENDIAN, 139798b9484cSchristos }; 139898b9484cSchristos 139998b9484cSchristos /* Open a cpu descriptor table for use. 140098b9484cSchristos ??? We only support ISO C stdargs here, not K&R. 140198b9484cSchristos Laziness, plus experiment to see if anything requires K&R - eventually 140298b9484cSchristos K&R will no longer be supported - e.g. GDB is currently trying this. */ 140398b9484cSchristos 140498b9484cSchristos extern CGEN_CPU_DESC CGEN_SYM (cpu_open) (enum cgen_cpu_open_arg, ...); 140598b9484cSchristos 140698b9484cSchristos /* Cover fn to handle simple case. */ 140798b9484cSchristos 140898b9484cSchristos extern CGEN_CPU_DESC CGEN_SYM (cpu_open_1) 140998b9484cSchristos (const char *mach_name_, enum cgen_endian endian_); 141098b9484cSchristos 141198b9484cSchristos /* Close it. */ 141298b9484cSchristos 141398b9484cSchristos extern void CGEN_SYM (cpu_close) (CGEN_CPU_DESC); 141498b9484cSchristos 141598b9484cSchristos /* Initialize the opcode table for use. 141698b9484cSchristos Called by init_asm/init_dis. */ 141798b9484cSchristos 141898b9484cSchristos extern void CGEN_SYM (init_opcode_table) (CGEN_CPU_DESC cd_); 141998b9484cSchristos 142098b9484cSchristos /* build the insn selection regex. 142198b9484cSchristos called by init_opcode_table */ 142298b9484cSchristos 142398b9484cSchristos extern char * CGEN_SYM(build_insn_regex) (CGEN_INSN *insn_); 142498b9484cSchristos 142598b9484cSchristos /* Initialize the ibld table for use. 142698b9484cSchristos Called by init_asm/init_dis. */ 142798b9484cSchristos 142898b9484cSchristos extern void CGEN_SYM (init_ibld_table) (CGEN_CPU_DESC cd_); 142998b9484cSchristos 143098b9484cSchristos /* Initialize an cpu table for assembler or disassembler use. 143198b9484cSchristos These must be called immediately after cpu_open. */ 143298b9484cSchristos 143398b9484cSchristos extern void CGEN_SYM (init_asm) (CGEN_CPU_DESC); 143498b9484cSchristos extern void CGEN_SYM (init_dis) (CGEN_CPU_DESC); 143598b9484cSchristos 143698b9484cSchristos /* Initialize the operand instance table for use. */ 143798b9484cSchristos 143898b9484cSchristos extern void CGEN_SYM (init_opinst_table) (CGEN_CPU_DESC cd_); 143998b9484cSchristos 144098b9484cSchristos /* Assemble an instruction. */ 144198b9484cSchristos 144298b9484cSchristos extern const CGEN_INSN * CGEN_SYM (assemble_insn) 144398b9484cSchristos (CGEN_CPU_DESC, const char *, CGEN_FIELDS *, 144498b9484cSchristos CGEN_INSN_BYTES_PTR, char **); 144598b9484cSchristos 144698b9484cSchristos extern const CGEN_KEYWORD CGEN_SYM (operand_mach); 144798b9484cSchristos extern int CGEN_SYM (get_mach) (const char *); 144898b9484cSchristos 144998b9484cSchristos /* Operand index computation. */ 145098b9484cSchristos extern const CGEN_INSN * cgen_lookup_insn 145198b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN * insn_, 145298b9484cSchristos CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 145398b9484cSchristos int length_, CGEN_FIELDS *fields_, int alias_p_); 145498b9484cSchristos extern void cgen_get_insn_operands 145598b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN * insn_, 145698b9484cSchristos const CGEN_FIELDS *fields_, int *indices_); 145798b9484cSchristos extern const CGEN_INSN * cgen_lookup_get_insn_operands 145898b9484cSchristos (CGEN_CPU_DESC, const CGEN_INSN *insn_, 145998b9484cSchristos CGEN_INSN_INT int_value_, unsigned char *bytes_value_, 146098b9484cSchristos int length_, int *indices_, CGEN_FIELDS *fields_); 146198b9484cSchristos 146298b9484cSchristos /* Cover fns to bfd_get/set. */ 146398b9484cSchristos 146498b9484cSchristos extern CGEN_INSN_INT cgen_get_insn_value 14658dffb485Schristos (CGEN_CPU_DESC, unsigned char *, int, int); 146698b9484cSchristos extern void cgen_put_insn_value 14678dffb485Schristos (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT, int); 14688dffb485Schristos 14698dffb485Schristos extern CGEN_INSN_INT cgen_get_base_insn_value 14708dffb485Schristos (CGEN_CPU_DESC, unsigned char *, int); 14718dffb485Schristos extern void cgen_put_base_insn_value 147298b9484cSchristos (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT); 147398b9484cSchristos 147498b9484cSchristos /* Read in a cpu description file. 147598b9484cSchristos ??? For future concerns, including adding instructions to the assembler/ 147698b9484cSchristos disassembler at run-time. */ 147798b9484cSchristos 147898b9484cSchristos extern const char * cgen_read_cpu_file (CGEN_CPU_DESC, const char * filename_); 147998b9484cSchristos 148098b9484cSchristos /* Allow signed overflow of instruction fields. */ 148198b9484cSchristos extern void cgen_set_signed_overflow_ok (CGEN_CPU_DESC); 148298b9484cSchristos 148398b9484cSchristos /* Generate an error message if a signed field in an instruction overflows. */ 148498b9484cSchristos extern void cgen_clear_signed_overflow_ok (CGEN_CPU_DESC); 148598b9484cSchristos 148698b9484cSchristos /* Will an error message be generated if a signed field in an instruction overflows ? */ 148798b9484cSchristos extern unsigned int cgen_signed_overflow_ok_p (CGEN_CPU_DESC); 148898b9484cSchristos 1489212397c6Schristos #ifdef __cplusplus 1490212397c6Schristos } 1491212397c6Schristos #endif 1492212397c6Schristos 149398b9484cSchristos #endif /* OPCODE_CGEN_H */ 1494