xref: /netbsd-src/external/gpl3/gdb/dist/include/opcode/cgen.h (revision 02f41505626a9ceb584d30d0789203495760ac88)
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