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