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