1ed0d50c3Schristos /* Internal definitions for configurable Xtensa ISA support. 2*b88e3e88Schristos Copyright (C) 2003-2020 Free Software Foundation, Inc. 3ed0d50c3Schristos 4ed0d50c3Schristos This file is part of BFD, the Binary File Descriptor library. 5ed0d50c3Schristos 6ed0d50c3Schristos This program is free software; you can redistribute it and/or modify 7ed0d50c3Schristos it under the terms of the GNU General Public License as published by 8ed0d50c3Schristos the Free Software Foundation; either version 3 of the License, or 9ed0d50c3Schristos (at your option) any later version. 10ed0d50c3Schristos 11ed0d50c3Schristos This program is distributed in the hope that it will be useful, 12ed0d50c3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 13ed0d50c3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14ed0d50c3Schristos GNU General Public License for more details. 15ed0d50c3Schristos 16ed0d50c3Schristos You should have received a copy of the GNU General Public License 17ed0d50c3Schristos along with this program; if not, write to the Free Software 18ed0d50c3Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 19ed0d50c3Schristos USA. */ 20ed0d50c3Schristos 21ed0d50c3Schristos #ifndef XTENSA_ISA_INTERNAL_H 22ed0d50c3Schristos #define XTENSA_ISA_INTERNAL_H 23ed0d50c3Schristos 24ed0d50c3Schristos /* Flags. */ 25ed0d50c3Schristos 26ed0d50c3Schristos #define XTENSA_OPERAND_IS_REGISTER 0x00000001 27ed0d50c3Schristos #define XTENSA_OPERAND_IS_PCRELATIVE 0x00000002 28ed0d50c3Schristos #define XTENSA_OPERAND_IS_INVISIBLE 0x00000004 29ed0d50c3Schristos #define XTENSA_OPERAND_IS_UNKNOWN 0x00000008 30ed0d50c3Schristos 31ed0d50c3Schristos #define XTENSA_OPCODE_IS_BRANCH 0x00000001 32ed0d50c3Schristos #define XTENSA_OPCODE_IS_JUMP 0x00000002 33ed0d50c3Schristos #define XTENSA_OPCODE_IS_LOOP 0x00000004 34ed0d50c3Schristos #define XTENSA_OPCODE_IS_CALL 0x00000008 35ed0d50c3Schristos 36ed0d50c3Schristos #define XTENSA_STATE_IS_EXPORTED 0x00000001 37ed0d50c3Schristos #define XTENSA_STATE_IS_SHARED_OR 0x00000002 38ed0d50c3Schristos 39ed0d50c3Schristos #define XTENSA_INTERFACE_HAS_SIDE_EFFECT 0x00000001 40ed0d50c3Schristos 41ed0d50c3Schristos /* Function pointer typedefs */ 42ed0d50c3Schristos typedef void (*xtensa_format_encode_fn) (xtensa_insnbuf); 43ed0d50c3Schristos typedef void (*xtensa_get_slot_fn) (const xtensa_insnbuf, xtensa_insnbuf); 44ed0d50c3Schristos typedef void (*xtensa_set_slot_fn) (xtensa_insnbuf, const xtensa_insnbuf); 45ed0d50c3Schristos typedef int (*xtensa_opcode_decode_fn) (const xtensa_insnbuf); 46ed0d50c3Schristos typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf); 47ed0d50c3Schristos typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32); 48ed0d50c3Schristos typedef int (*xtensa_immed_decode_fn) (uint32 *); 49ed0d50c3Schristos typedef int (*xtensa_immed_encode_fn) (uint32 *); 50ed0d50c3Schristos typedef int (*xtensa_do_reloc_fn) (uint32 *, uint32); 51ed0d50c3Schristos typedef int (*xtensa_undo_reloc_fn) (uint32 *, uint32); 52ed0d50c3Schristos typedef void (*xtensa_opcode_encode_fn) (xtensa_insnbuf); 53ed0d50c3Schristos typedef int (*xtensa_format_decode_fn) (const xtensa_insnbuf); 54ed0d50c3Schristos typedef int (*xtensa_length_decode_fn) (const unsigned char *); 55ed0d50c3Schristos 56ed0d50c3Schristos typedef struct xtensa_format_internal_struct 57ed0d50c3Schristos { 58ed0d50c3Schristos const char *name; /* Instruction format name. */ 59ed0d50c3Schristos int length; /* Instruction length in bytes. */ 60ed0d50c3Schristos xtensa_format_encode_fn encode_fn; 61ed0d50c3Schristos int num_slots; 62ed0d50c3Schristos int *slot_id; /* Array[num_slots] of slot IDs. */ 63ed0d50c3Schristos } xtensa_format_internal; 64ed0d50c3Schristos 65ed0d50c3Schristos typedef struct xtensa_slot_internal_struct 66ed0d50c3Schristos { 67ed0d50c3Schristos const char *name; /* Not necessarily unique. */ 68ed0d50c3Schristos const char *format; 69ed0d50c3Schristos int position; 70ed0d50c3Schristos xtensa_get_slot_fn get_fn; 71ed0d50c3Schristos xtensa_set_slot_fn set_fn; 72ed0d50c3Schristos xtensa_get_field_fn *get_field_fns; /* Array[field_id]. */ 73ed0d50c3Schristos xtensa_set_field_fn *set_field_fns; /* Array[field_id]. */ 74ed0d50c3Schristos xtensa_opcode_decode_fn opcode_decode_fn; 75ed0d50c3Schristos const char *nop_name; 76ed0d50c3Schristos } xtensa_slot_internal; 77ed0d50c3Schristos 78ed0d50c3Schristos typedef struct xtensa_operand_internal_struct 79ed0d50c3Schristos { 80ed0d50c3Schristos const char *name; 81ed0d50c3Schristos int field_id; 82ed0d50c3Schristos xtensa_regfile regfile; /* Register file. */ 83ed0d50c3Schristos int num_regs; /* Usually 1; 2 for reg pairs, etc. */ 84ed0d50c3Schristos uint32 flags; /* See XTENSA_OPERAND_* flags. */ 85ed0d50c3Schristos xtensa_immed_encode_fn encode; /* Encode the operand value. */ 86ed0d50c3Schristos xtensa_immed_decode_fn decode; /* Decode the value from the field. */ 87ed0d50c3Schristos xtensa_do_reloc_fn do_reloc; /* Perform a PC-relative reloc. */ 88ed0d50c3Schristos xtensa_undo_reloc_fn undo_reloc; /* Undo a PC-relative relocation. */ 89ed0d50c3Schristos } xtensa_operand_internal; 90ed0d50c3Schristos 91ed0d50c3Schristos typedef struct xtensa_arg_internal_struct 92ed0d50c3Schristos { 93ed0d50c3Schristos union { 94ed0d50c3Schristos int operand_id; /* For normal operands. */ 95ed0d50c3Schristos xtensa_state state; /* For stateOperands. */ 96ed0d50c3Schristos } u; 97ed0d50c3Schristos char inout; /* Direction: 'i', 'o', or 'm'. */ 98ed0d50c3Schristos } xtensa_arg_internal; 99ed0d50c3Schristos 100ed0d50c3Schristos typedef struct xtensa_iclass_internal_struct 101ed0d50c3Schristos { 102ed0d50c3Schristos int num_operands; /* Size of "operands" array. */ 103ed0d50c3Schristos xtensa_arg_internal *operands; /* Array[num_operands]. */ 104ed0d50c3Schristos 105ed0d50c3Schristos int num_stateOperands; /* Size of "stateOperands" array. */ 106ed0d50c3Schristos xtensa_arg_internal *stateOperands; /* Array[num_stateOperands]. */ 107ed0d50c3Schristos 108ed0d50c3Schristos int num_interfaceOperands; /* Size of "interfaceOperands". */ 109ed0d50c3Schristos xtensa_interface *interfaceOperands; /* Array[num_interfaceOperands]. */ 110ed0d50c3Schristos } xtensa_iclass_internal; 111ed0d50c3Schristos 112ed0d50c3Schristos typedef struct xtensa_opcode_internal_struct 113ed0d50c3Schristos { 114ed0d50c3Schristos const char *name; /* Opcode mnemonic. */ 115ed0d50c3Schristos int iclass_id; /* Iclass for this opcode. */ 116ed0d50c3Schristos uint32 flags; /* See XTENSA_OPCODE_* flags. */ 117ed0d50c3Schristos xtensa_opcode_encode_fn *encode_fns; /* Array[slot_id]. */ 118ed0d50c3Schristos int num_funcUnit_uses; /* Number of funcUnit_use entries. */ 119ed0d50c3Schristos xtensa_funcUnit_use *funcUnit_uses; /* Array[num_funcUnit_uses]. */ 120ed0d50c3Schristos } xtensa_opcode_internal; 121ed0d50c3Schristos 122ed0d50c3Schristos typedef struct xtensa_regfile_internal_struct 123ed0d50c3Schristos { 124ed0d50c3Schristos const char *name; /* Full name of the regfile. */ 125ed0d50c3Schristos const char *shortname; /* Abbreviated name. */ 126ed0d50c3Schristos xtensa_regfile parent; /* View parent (or identity). */ 127ed0d50c3Schristos int num_bits; /* Width of the registers. */ 128ed0d50c3Schristos int num_entries; /* Number of registers. */ 129ed0d50c3Schristos } xtensa_regfile_internal; 130ed0d50c3Schristos 131ed0d50c3Schristos typedef struct xtensa_interface_internal_struct 132ed0d50c3Schristos { 133ed0d50c3Schristos const char *name; /* Interface name. */ 134ed0d50c3Schristos int num_bits; /* Width of the interface. */ 135ed0d50c3Schristos uint32 flags; /* See XTENSA_INTERFACE_* flags. */ 136ed0d50c3Schristos int class_id; /* Class of related interfaces. */ 137ed0d50c3Schristos char inout; /* "i" or "o". */ 138ed0d50c3Schristos } xtensa_interface_internal; 139ed0d50c3Schristos 140ed0d50c3Schristos typedef struct xtensa_funcUnit_internal_struct 141ed0d50c3Schristos { 142ed0d50c3Schristos const char *name; /* Functional unit name. */ 143ed0d50c3Schristos int num_copies; /* Number of instances. */ 144ed0d50c3Schristos } xtensa_funcUnit_internal; 145ed0d50c3Schristos 146ed0d50c3Schristos typedef struct xtensa_state_internal_struct 147ed0d50c3Schristos { 148ed0d50c3Schristos const char *name; /* State name. */ 149ed0d50c3Schristos int num_bits; /* Number of state bits. */ 150ed0d50c3Schristos uint32 flags; /* See XTENSA_STATE_* flags. */ 151ed0d50c3Schristos } xtensa_state_internal; 152ed0d50c3Schristos 153ed0d50c3Schristos typedef struct xtensa_sysreg_internal_struct 154ed0d50c3Schristos { 155ed0d50c3Schristos const char *name; /* Register name. */ 156ed0d50c3Schristos int number; /* Register number. */ 157ed0d50c3Schristos int is_user; /* Non-zero if a "user register". */ 158ed0d50c3Schristos } xtensa_sysreg_internal; 159ed0d50c3Schristos 160ed0d50c3Schristos typedef struct xtensa_lookup_entry_struct 161ed0d50c3Schristos { 162ed0d50c3Schristos const char *key; 163ed0d50c3Schristos union 164ed0d50c3Schristos { 165ed0d50c3Schristos xtensa_opcode opcode; /* Internal opcode number. */ 166ed0d50c3Schristos xtensa_sysreg sysreg; /* Internal sysreg number. */ 167ed0d50c3Schristos xtensa_state state; /* Internal state number. */ 168ed0d50c3Schristos xtensa_interface intf; /* Internal interface number. */ 169ed0d50c3Schristos xtensa_funcUnit fun; /* Internal funcUnit number. */ 170ed0d50c3Schristos } u; 171ed0d50c3Schristos } xtensa_lookup_entry; 172ed0d50c3Schristos 173ed0d50c3Schristos typedef struct xtensa_isa_internal_struct 174ed0d50c3Schristos { 175ed0d50c3Schristos int is_big_endian; /* Endianness. */ 176ed0d50c3Schristos int insn_size; /* Maximum length in bytes. */ 177ed0d50c3Schristos int insnbuf_size; /* Number of insnbuf_words. */ 178ed0d50c3Schristos 179ed0d50c3Schristos int num_formats; 180ed0d50c3Schristos xtensa_format_internal *formats; 181ed0d50c3Schristos xtensa_format_decode_fn format_decode_fn; 182ed0d50c3Schristos xtensa_length_decode_fn length_decode_fn; 183ed0d50c3Schristos 184ed0d50c3Schristos int num_slots; 185ed0d50c3Schristos xtensa_slot_internal *slots; 186ed0d50c3Schristos 187ed0d50c3Schristos int num_fields; 188ed0d50c3Schristos 189ed0d50c3Schristos int num_operands; 190ed0d50c3Schristos xtensa_operand_internal *operands; 191ed0d50c3Schristos 192ed0d50c3Schristos int num_iclasses; 193ed0d50c3Schristos xtensa_iclass_internal *iclasses; 194ed0d50c3Schristos 195ed0d50c3Schristos int num_opcodes; 196ed0d50c3Schristos xtensa_opcode_internal *opcodes; 197ed0d50c3Schristos xtensa_lookup_entry *opname_lookup_table; 198ed0d50c3Schristos 199ed0d50c3Schristos int num_regfiles; 200ed0d50c3Schristos xtensa_regfile_internal *regfiles; 201ed0d50c3Schristos 202ed0d50c3Schristos int num_states; 203ed0d50c3Schristos xtensa_state_internal *states; 204ed0d50c3Schristos xtensa_lookup_entry *state_lookup_table; 205ed0d50c3Schristos 206ed0d50c3Schristos int num_sysregs; 207ed0d50c3Schristos xtensa_sysreg_internal *sysregs; 208ed0d50c3Schristos xtensa_lookup_entry *sysreg_lookup_table; 209ed0d50c3Schristos 210ed0d50c3Schristos /* The current Xtensa ISA only supports 256 of each kind of sysreg so 211ed0d50c3Schristos we can get away with implementing lookups with tables indexed by 212ed0d50c3Schristos the register numbers. If we ever allow larger sysreg numbers, this 213ed0d50c3Schristos may have to be reimplemented. The first entry in the following 214ed0d50c3Schristos arrays corresponds to "special" registers and the second to "user" 215ed0d50c3Schristos registers. */ 216ed0d50c3Schristos int max_sysreg_num[2]; 217ed0d50c3Schristos xtensa_sysreg *sysreg_table[2]; 218ed0d50c3Schristos 219ed0d50c3Schristos int num_interfaces; 220ed0d50c3Schristos xtensa_interface_internal *interfaces; 221ed0d50c3Schristos xtensa_lookup_entry *interface_lookup_table; 222ed0d50c3Schristos 223ed0d50c3Schristos int num_funcUnits; 224ed0d50c3Schristos xtensa_funcUnit_internal *funcUnits; 225ed0d50c3Schristos xtensa_lookup_entry *funcUnit_lookup_table; 226ed0d50c3Schristos 227ed0d50c3Schristos } xtensa_isa_internal; 228ed0d50c3Schristos 229ed0d50c3Schristos extern int xtensa_isa_name_compare (const void *, const void *); 230ed0d50c3Schristos 231ed0d50c3Schristos extern xtensa_isa_status xtisa_errno; 232ed0d50c3Schristos extern char xtisa_error_msg[]; 233ed0d50c3Schristos 234ed0d50c3Schristos #endif /* !XTENSA_ISA_INTERNAL_H */ 235