xref: /netbsd-src/external/gpl3/gdb/dist/include/xtensa-isa-internal.h (revision e663ba6e3a60083e70de702e9d54bf486a57b6a7)
198b9484cSchristos /* Internal definitions for configurable Xtensa ISA support.
2*e663ba6eSchristos    Copyright (C) 2003-2024 Free Software Foundation, Inc.
398b9484cSchristos 
498b9484cSchristos    This file is part of BFD, the Binary File Descriptor library.
598b9484cSchristos 
698b9484cSchristos    This program is free software; you can redistribute it and/or modify
798b9484cSchristos    it under the terms of the GNU General Public License as published by
898b9484cSchristos    the Free Software Foundation; either version 3 of the License, or
998b9484cSchristos    (at your option) any later version.
1098b9484cSchristos 
1198b9484cSchristos    This program is distributed in the hope that it will be useful,
1298b9484cSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1398b9484cSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1498b9484cSchristos    GNU General Public License for more details.
1598b9484cSchristos 
1698b9484cSchristos    You should have received a copy of the GNU General Public License
1798b9484cSchristos    along with this program; if not, write to the Free Software
1898b9484cSchristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
1998b9484cSchristos    USA.  */
2098b9484cSchristos 
2198b9484cSchristos #ifndef XTENSA_ISA_INTERNAL_H
2298b9484cSchristos #define XTENSA_ISA_INTERNAL_H
2398b9484cSchristos 
2498b9484cSchristos /* Flags.  */
2598b9484cSchristos 
2698b9484cSchristos #define XTENSA_OPERAND_IS_REGISTER	0x00000001
2798b9484cSchristos #define XTENSA_OPERAND_IS_PCRELATIVE	0x00000002
2898b9484cSchristos #define XTENSA_OPERAND_IS_INVISIBLE	0x00000004
2998b9484cSchristos #define XTENSA_OPERAND_IS_UNKNOWN	0x00000008
3098b9484cSchristos 
3198b9484cSchristos #define XTENSA_OPCODE_IS_BRANCH		0x00000001
3298b9484cSchristos #define XTENSA_OPCODE_IS_JUMP		0x00000002
3398b9484cSchristos #define XTENSA_OPCODE_IS_LOOP		0x00000004
3498b9484cSchristos #define XTENSA_OPCODE_IS_CALL		0x00000008
3598b9484cSchristos 
3698b9484cSchristos #define XTENSA_STATE_IS_EXPORTED	0x00000001
3798b9484cSchristos #define XTENSA_STATE_IS_SHARED_OR	0x00000002
3898b9484cSchristos 
3998b9484cSchristos #define XTENSA_INTERFACE_HAS_SIDE_EFFECT 0x00000001
4098b9484cSchristos 
4198b9484cSchristos /* Function pointer typedefs */
4298b9484cSchristos typedef void (*xtensa_format_encode_fn) (xtensa_insnbuf);
4398b9484cSchristos typedef void (*xtensa_get_slot_fn) (const xtensa_insnbuf, xtensa_insnbuf);
4498b9484cSchristos typedef void (*xtensa_set_slot_fn) (xtensa_insnbuf, const xtensa_insnbuf);
4598b9484cSchristos typedef int (*xtensa_opcode_decode_fn) (const xtensa_insnbuf);
4698b9484cSchristos typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf);
4798b9484cSchristos typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32);
4898b9484cSchristos typedef int (*xtensa_immed_decode_fn) (uint32 *);
4998b9484cSchristos typedef int (*xtensa_immed_encode_fn) (uint32 *);
5098b9484cSchristos typedef int (*xtensa_do_reloc_fn) (uint32 *, uint32);
5198b9484cSchristos typedef int (*xtensa_undo_reloc_fn) (uint32 *, uint32);
5298b9484cSchristos typedef void (*xtensa_opcode_encode_fn) (xtensa_insnbuf);
5398b9484cSchristos typedef int (*xtensa_format_decode_fn) (const xtensa_insnbuf);
5498b9484cSchristos typedef int (*xtensa_length_decode_fn) (const unsigned char *);
5598b9484cSchristos 
564b169a6bSchristos typedef const struct xtensa_format_internal_struct
5798b9484cSchristos {
5898b9484cSchristos   const char *name;			/* Instruction format name.  */
5998b9484cSchristos   int length;				/* Instruction length in bytes.  */
6098b9484cSchristos   xtensa_format_encode_fn encode_fn;
6198b9484cSchristos   int num_slots;
624b169a6bSchristos   const int *slot_id;			/* Array[num_slots] of slot IDs.  */
6398b9484cSchristos } xtensa_format_internal;
6498b9484cSchristos 
654b169a6bSchristos typedef const struct xtensa_slot_internal_struct
6698b9484cSchristos {
6798b9484cSchristos   const char *name;			/* Not necessarily unique.  */
6898b9484cSchristos   const char *format;
6998b9484cSchristos   int position;
7098b9484cSchristos   xtensa_get_slot_fn get_fn;
7198b9484cSchristos   xtensa_set_slot_fn set_fn;
724b169a6bSchristos   const xtensa_get_field_fn *get_field_fns; /* Array[field_id].  */
734b169a6bSchristos   const xtensa_set_field_fn *set_field_fns; /* Array[field_id].  */
7498b9484cSchristos   xtensa_opcode_decode_fn opcode_decode_fn;
7598b9484cSchristos   const char *nop_name;
7698b9484cSchristos } xtensa_slot_internal;
7798b9484cSchristos 
784b169a6bSchristos typedef const struct xtensa_operand_internal_struct
7998b9484cSchristos {
8098b9484cSchristos   const char *name;
8198b9484cSchristos   int field_id;
8298b9484cSchristos   xtensa_regfile regfile;		/* Register file.  */
8398b9484cSchristos   int num_regs;				/* Usually 1; 2 for reg pairs, etc.  */
8498b9484cSchristos   uint32 flags;				/* See XTENSA_OPERAND_* flags.  */
8598b9484cSchristos   xtensa_immed_encode_fn encode;	/* Encode the operand value.  */
8698b9484cSchristos   xtensa_immed_decode_fn decode;	/* Decode the value from the field.  */
8798b9484cSchristos   xtensa_do_reloc_fn do_reloc;		/* Perform a PC-relative reloc.  */
8898b9484cSchristos   xtensa_undo_reloc_fn undo_reloc;	/* Undo a PC-relative relocation.  */
8998b9484cSchristos } xtensa_operand_internal;
9098b9484cSchristos 
914b169a6bSchristos typedef const struct xtensa_arg_internal_struct
9298b9484cSchristos {
9398b9484cSchristos   union {
9498b9484cSchristos     int operand_id;			/* For normal operands.  */
9598b9484cSchristos     xtensa_state state;			/* For stateOperands.  */
9698b9484cSchristos   } u;
9798b9484cSchristos   char inout;				/* Direction: 'i', 'o', or 'm'.  */
9898b9484cSchristos } xtensa_arg_internal;
9998b9484cSchristos 
1004b169a6bSchristos typedef const struct xtensa_iclass_internal_struct
10198b9484cSchristos {
10298b9484cSchristos   int num_operands;			/* Size of "operands" array.  */
10398b9484cSchristos   xtensa_arg_internal *operands;	/* Array[num_operands].  */
10498b9484cSchristos 
10598b9484cSchristos   int num_stateOperands;		/* Size of "stateOperands" array.  */
10698b9484cSchristos   xtensa_arg_internal *stateOperands;	/* Array[num_stateOperands].  */
10798b9484cSchristos 
10898b9484cSchristos   int num_interfaceOperands;		/* Size of "interfaceOperands".  */
10998b9484cSchristos   xtensa_interface *interfaceOperands;	/* Array[num_interfaceOperands].  */
11098b9484cSchristos } xtensa_iclass_internal;
11198b9484cSchristos 
1124b169a6bSchristos typedef const struct xtensa_opcode_internal_struct
11398b9484cSchristos {
11498b9484cSchristos   const char *name;			/* Opcode mnemonic.  */
11598b9484cSchristos   int iclass_id;			/* Iclass for this opcode.  */
11698b9484cSchristos   uint32 flags;				/* See XTENSA_OPCODE_* flags.  */
1174b169a6bSchristos   const xtensa_opcode_encode_fn *encode_fns; /* Array[slot_id].  */
11898b9484cSchristos   int num_funcUnit_uses;		/* Number of funcUnit_use entries.  */
11998b9484cSchristos   xtensa_funcUnit_use *funcUnit_uses;	/* Array[num_funcUnit_uses].  */
12098b9484cSchristos } xtensa_opcode_internal;
12198b9484cSchristos 
1224b169a6bSchristos typedef const struct xtensa_regfile_internal_struct
12398b9484cSchristos {
12498b9484cSchristos   const char *name;			/* Full name of the regfile.  */
12598b9484cSchristos   const char *shortname;		/* Abbreviated name.  */
12698b9484cSchristos   xtensa_regfile parent;		/* View parent (or identity).  */
12798b9484cSchristos   int num_bits;				/* Width of the registers.  */
12898b9484cSchristos   int num_entries;			/* Number of registers.  */
12998b9484cSchristos } xtensa_regfile_internal;
13098b9484cSchristos 
1314b169a6bSchristos typedef const struct xtensa_interface_internal_struct
13298b9484cSchristos {
13398b9484cSchristos   const char *name;			/* Interface name.  */
13498b9484cSchristos   int num_bits;				/* Width of the interface.  */
13598b9484cSchristos   uint32 flags;				/* See XTENSA_INTERFACE_* flags.  */
13698b9484cSchristos   int class_id;				/* Class of related interfaces.  */
13798b9484cSchristos   char inout;				/* "i" or "o".  */
13898b9484cSchristos } xtensa_interface_internal;
13998b9484cSchristos 
1404b169a6bSchristos typedef const struct xtensa_funcUnit_internal_struct
14198b9484cSchristos {
14298b9484cSchristos   const char *name;			/* Functional unit name.  */
14398b9484cSchristos   int num_copies;			/* Number of instances.  */
14498b9484cSchristos } xtensa_funcUnit_internal;
14598b9484cSchristos 
1464b169a6bSchristos typedef const struct xtensa_state_internal_struct
14798b9484cSchristos {
14898b9484cSchristos   const char *name;			/* State name.  */
14998b9484cSchristos   int num_bits;				/* Number of state bits.  */
15098b9484cSchristos   uint32 flags;				/* See XTENSA_STATE_* flags.  */
15198b9484cSchristos } xtensa_state_internal;
15298b9484cSchristos 
1534b169a6bSchristos typedef const struct xtensa_sysreg_internal_struct
15498b9484cSchristos {
15598b9484cSchristos   const char *name;			/* Register name.  */
15698b9484cSchristos   int number;				/* Register number.  */
15798b9484cSchristos   int is_user;				/* Non-zero if a "user register".  */
15898b9484cSchristos } xtensa_sysreg_internal;
15998b9484cSchristos 
16098b9484cSchristos typedef struct xtensa_lookup_entry_struct
16198b9484cSchristos {
16298b9484cSchristos   const char *key;
16398b9484cSchristos   union
16498b9484cSchristos   {
16598b9484cSchristos     xtensa_opcode opcode;		/* Internal opcode number.  */
16698b9484cSchristos     xtensa_sysreg sysreg;		/* Internal sysreg number.  */
16798b9484cSchristos     xtensa_state state;			/* Internal state number.  */
16898b9484cSchristos     xtensa_interface intf;		/* Internal interface number.  */
16998b9484cSchristos     xtensa_funcUnit fun;		/* Internal funcUnit number.  */
17098b9484cSchristos   } u;
17198b9484cSchristos } xtensa_lookup_entry;
17298b9484cSchristos 
17398b9484cSchristos typedef struct xtensa_isa_internal_struct
17498b9484cSchristos {
17598b9484cSchristos   int is_big_endian;			/* Endianness.  */
17698b9484cSchristos   int insn_size;			/* Maximum length in bytes.  */
17798b9484cSchristos   int insnbuf_size;			/* Number of insnbuf_words.  */
17898b9484cSchristos 
17998b9484cSchristos   int num_formats;
18098b9484cSchristos   xtensa_format_internal *formats;
18198b9484cSchristos   xtensa_format_decode_fn format_decode_fn;
18298b9484cSchristos   xtensa_length_decode_fn length_decode_fn;
18398b9484cSchristos 
18498b9484cSchristos   int num_slots;
18598b9484cSchristos   xtensa_slot_internal *slots;
18698b9484cSchristos 
18798b9484cSchristos   int num_fields;
18898b9484cSchristos 
18998b9484cSchristos   int num_operands;
19098b9484cSchristos   xtensa_operand_internal *operands;
19198b9484cSchristos 
19298b9484cSchristos   int num_iclasses;
19398b9484cSchristos   xtensa_iclass_internal *iclasses;
19498b9484cSchristos 
19598b9484cSchristos   int num_opcodes;
19698b9484cSchristos   xtensa_opcode_internal *opcodes;
19798b9484cSchristos   xtensa_lookup_entry *opname_lookup_table;
19898b9484cSchristos 
19998b9484cSchristos   int num_regfiles;
20098b9484cSchristos   xtensa_regfile_internal *regfiles;
20198b9484cSchristos 
20298b9484cSchristos   int num_states;
20398b9484cSchristos   xtensa_state_internal *states;
20498b9484cSchristos   xtensa_lookup_entry *state_lookup_table;
20598b9484cSchristos 
20698b9484cSchristos   int num_sysregs;
20798b9484cSchristos   xtensa_sysreg_internal *sysregs;
20898b9484cSchristos   xtensa_lookup_entry *sysreg_lookup_table;
20998b9484cSchristos 
21098b9484cSchristos   /* The current Xtensa ISA only supports 256 of each kind of sysreg so
21198b9484cSchristos      we can get away with implementing lookups with tables indexed by
21298b9484cSchristos      the register numbers.  If we ever allow larger sysreg numbers, this
21398b9484cSchristos      may have to be reimplemented.  The first entry in the following
21498b9484cSchristos      arrays corresponds to "special" registers and the second to "user"
21598b9484cSchristos      registers.  */
21698b9484cSchristos   int max_sysreg_num[2];
21798b9484cSchristos   xtensa_sysreg *sysreg_table[2];
21898b9484cSchristos 
21998b9484cSchristos   int num_interfaces;
22098b9484cSchristos   xtensa_interface_internal *interfaces;
22198b9484cSchristos   xtensa_lookup_entry *interface_lookup_table;
22298b9484cSchristos 
22398b9484cSchristos   int num_funcUnits;
22498b9484cSchristos   xtensa_funcUnit_internal *funcUnits;
22598b9484cSchristos   xtensa_lookup_entry *funcUnit_lookup_table;
22698b9484cSchristos 
22798b9484cSchristos } xtensa_isa_internal;
22898b9484cSchristos 
22998b9484cSchristos extern int xtensa_isa_name_compare (const void *, const void *);
23098b9484cSchristos 
23198b9484cSchristos #endif /* !XTENSA_ISA_INTERNAL_H */
232