]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/xtensa-isa.c
elf: Skip the archive if the symbol isn't referenced
[thirdparty/binutils-gdb.git] / bfd / xtensa-isa.c
CommitLineData
e0001a05 1/* Configurable Xtensa ISA support.
fd67aa11 2 Copyright (C) 2003-2024 Free Software Foundation, Inc.
e0001a05
NC
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
e0001a05
NC
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
e0001a05 20
43cd72b9 21#include "sysdep.h"
3db64b00 22#include "bfd.h"
43cd72b9 23#include "libbfd.h"
e0001a05
NC
24#include "xtensa-isa.h"
25#include "xtensa-isa-internal.h"
d0a2cfbd 26#include "xtensa-dynconfig.h"
e0001a05 27
3fafa2e2
AM
28static xtensa_isa_status xtisa_errno;
29static char xtisa_error_msg[1024];
43cd72b9
BW
30
31
32xtensa_isa_status
33xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
34{
35 return xtisa_errno;
36}
37
e0001a05 38
43cd72b9
BW
39char *
40xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
e0001a05 41{
43cd72b9
BW
42 return xtisa_error_msg;
43}
e0001a05 44
43cd72b9
BW
45
46#define CHECK_ALLOC(MEM,ERRVAL) \
47 do { \
48 if ((MEM) == 0) \
49 { \
50 xtisa_errno = xtensa_isa_out_of_memory; \
51 strcpy (xtisa_error_msg, "out of memory"); \
52 return (ERRVAL); \
53 } \
54 } while (0)
55
56#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
57 do { \
58 if ((MEM) == 0) \
59 { \
60 xtisa_errno = xtensa_isa_out_of_memory; \
61 strcpy (xtisa_error_msg, "out of memory"); \
62 if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
63 if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
64 return (ERRVAL); \
65 } \
66 } while (0)
67
1fbc7e7a 68
43cd72b9
BW
69\f
70/* Instruction buffers. */
71
72int
73xtensa_insnbuf_size (xtensa_isa isa)
74{
75 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
76 return intisa->insnbuf_size;
e0001a05
NC
77}
78
79
43cd72b9
BW
80xtensa_insnbuf
81xtensa_insnbuf_alloc (xtensa_isa isa)
82{
83 xtensa_insnbuf result = (xtensa_insnbuf)
84 malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
85 CHECK_ALLOC (result, 0);
86 return result;
87}
88
89
90void
91xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
92 xtensa_insnbuf buf)
93{
94 free (buf);
95}
96
97
98/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
99 internal representation of a xtensa instruction word, return the index of
100 its word and the bit index of its low order byte in the xtensa_insnbuf. */
101
102static inline int
103byte_to_word_index (int byte_index)
104{
105 return byte_index / sizeof (xtensa_insnbuf_word);
106}
107
108
109static inline int
110byte_to_bit_index (int byte_index)
111{
112 return (byte_index & 0x3) * 8;
113}
114
115
116/* Copy an instruction in the 32-bit words pointed at by "insn" to
117 characters pointed at by "cp". This is more complicated than you
118 might think because we want 16-bit instructions in bytes 2 & 3 for
119 big-endian configurations. This function allows us to specify
120 which byte in "insn" to start with and which way to increment,
121 allowing trivial implementation for both big- and little-endian
122 configurations....and it seems to make pretty good code for
123 both. */
124
125int
f075ee0c
AM
126xtensa_insnbuf_to_chars (xtensa_isa isa,
127 const xtensa_insnbuf insn,
128 unsigned char *cp,
43cd72b9
BW
129 int num_chars)
130{
131 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
132 int insn_size = xtensa_isa_maxlength (isa);
133 int fence_post, start, increment, i, byte_count;
134 xtensa_format fmt;
135
136 if (num_chars == 0)
137 num_chars = insn_size;
138
139 if (intisa->is_big_endian)
140 {
141 start = insn_size - 1;
142 increment = -1;
143 }
144 else
145 {
146 start = 0;
147 increment = 1;
148 }
149
150 /* Find the instruction format. Do nothing if the buffer does not contain
151 a valid instruction since we need to know how many bytes to copy. */
152 fmt = xtensa_format_decode (isa, insn);
153 if (fmt == XTENSA_UNDEFINED)
154 return XTENSA_UNDEFINED;
155
156 byte_count = xtensa_format_length (isa, fmt);
157 if (byte_count == XTENSA_UNDEFINED)
158 return XTENSA_UNDEFINED;
159
160 if (byte_count > num_chars)
161 {
162 xtisa_errno = xtensa_isa_buffer_overflow;
163 strcpy (xtisa_error_msg, "output buffer too small for instruction");
164 return XTENSA_UNDEFINED;
165 }
166
167 fence_post = start + (byte_count * increment);
168
169 for (i = start; i != fence_post; i += increment, ++cp)
170 {
171 int word_inx = byte_to_word_index (i);
172 int bit_inx = byte_to_bit_index (i);
173
174 *cp = (insn[word_inx] >> bit_inx) & 0xff;
175 }
176
177 return byte_count;
178}
179
180
181/* Inward conversion from byte stream to xtensa_insnbuf. See
182 xtensa_insnbuf_to_chars for a discussion of why this is complicated
183 by endianness. */
68ffbac6 184
43cd72b9 185void
f075ee0c
AM
186xtensa_insnbuf_from_chars (xtensa_isa isa,
187 xtensa_insnbuf insn,
188 const unsigned char *cp,
43cd72b9
BW
189 int num_chars)
190{
191 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
192 int max_size, insn_size, fence_post, start, increment, i;
193
194 max_size = xtensa_isa_maxlength (isa);
195
196 /* Decode the instruction length so we know how many bytes to read. */
197 insn_size = (intisa->length_decode_fn) (cp);
198 if (insn_size == XTENSA_UNDEFINED)
199 {
200 /* This should never happen when the byte stream contains a
201 valid instruction. Just read the maximum number of bytes.... */
202 insn_size = max_size;
203 }
204
205 if (num_chars == 0 || num_chars > insn_size)
206 num_chars = insn_size;
207
208 if (intisa->is_big_endian)
209 {
210 start = max_size - 1;
211 increment = -1;
212 }
213 else
214 {
215 start = 0;
216 increment = 1;
217 }
218
219 fence_post = start + (num_chars * increment);
220 memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
221
222 for (i = start; i != fence_post; i += increment, ++cp)
223 {
224 int word_inx = byte_to_word_index (i);
225 int bit_inx = byte_to_bit_index (i);
226
e76832f1 227 insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx;
43cd72b9
BW
228 }
229}
230
43cd72b9
BW
231\f
232/* ISA information. */
233
234extern xtensa_isa_internal xtensa_modules;
235
d0a2cfbd
MF
236static xtensa_isa_internal *xtensa_get_modules (void)
237{
238 static xtensa_isa_internal *modules;
239
240 if (!modules)
241 modules = (xtensa_isa_internal *) xtensa_load_config ("xtensa_modules",
242 &xtensa_modules,
243 NULL);
244 return modules;
245}
246
e0001a05 247xtensa_isa
43cd72b9 248xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
e0001a05 249{
d0a2cfbd 250 xtensa_isa_internal *isa = xtensa_get_modules ();
43cd72b9
BW
251 int n, is_user;
252
253 /* Set up the opcode name lookup table. */
254 isa->opname_lookup_table =
255 bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
256 CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
257 for (n = 0; n < isa->num_opcodes; n++)
258 {
259 isa->opname_lookup_table[n].key = isa->opcodes[n].name;
260 isa->opname_lookup_table[n].u.opcode = n;
261 }
262 qsort (isa->opname_lookup_table, isa->num_opcodes,
263 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
e0001a05 264
43cd72b9
BW
265 /* Set up the state name lookup table. */
266 isa->state_lookup_table =
267 bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
268 CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
269 for (n = 0; n < isa->num_states; n++)
e0001a05 270 {
43cd72b9
BW
271 isa->state_lookup_table[n].key = isa->states[n].name;
272 isa->state_lookup_table[n].u.state = n;
273 }
274 qsort (isa->state_lookup_table, isa->num_states,
275 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
276
277 /* Set up the sysreg name lookup table. */
278 isa->sysreg_lookup_table =
279 bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
280 CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
281 for (n = 0; n < isa->num_sysregs; n++)
282 {
283 isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
284 isa->sysreg_lookup_table[n].u.sysreg = n;
285 }
286 qsort (isa->sysreg_lookup_table, isa->num_sysregs,
287 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
288
289 /* Set up the user & system sysreg number tables. */
290 for (is_user = 0; is_user < 2; is_user++)
291 {
292 isa->sysreg_table[is_user] =
293 bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
294 * sizeof (xtensa_sysreg));
295 CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
296 errno_p, error_msg_p);
297
298 for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
299 isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
300 }
301 for (n = 0; n < isa->num_sysregs; n++)
302 {
303 xtensa_sysreg_internal *sreg = &isa->sysregs[n];
304 is_user = sreg->is_user;
305
d84ed528
MF
306 if (sreg->number >= 0)
307 isa->sysreg_table[is_user][sreg->number] = n;
43cd72b9
BW
308 }
309
310 /* Set up the interface lookup table. */
68ffbac6 311 isa->interface_lookup_table =
43cd72b9
BW
312 bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
313 CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
314 error_msg_p);
315 for (n = 0; n < isa->num_interfaces; n++)
316 {
317 isa->interface_lookup_table[n].key = isa->interfaces[n].name;
318 isa->interface_lookup_table[n].u.intf = n;
319 }
320 qsort (isa->interface_lookup_table, isa->num_interfaces,
321 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
322
323 /* Set up the funcUnit lookup table. */
68ffbac6 324 isa->funcUnit_lookup_table =
43cd72b9
BW
325 bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
326 CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
327 error_msg_p);
328 for (n = 0; n < isa->num_funcUnits; n++)
329 {
330 isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
331 isa->funcUnit_lookup_table[n].u.fun = n;
332 }
333 qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
334 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
335
336 isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
337 sizeof (xtensa_insnbuf_word));
338
339 return (xtensa_isa) isa;
340}
341
342
343void
344xtensa_isa_free (xtensa_isa isa)
345{
346 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
347 int n;
348
349 /* With this version of the code, the xtensa_isa structure is not
350 dynamically allocated, so this function is not essential. Free
351 the memory allocated by xtensa_isa_init and restore the xtensa_isa
352 structure to its initial state. */
353
c9594989
AM
354 free (intisa->opname_lookup_table);
355 intisa->opname_lookup_table = 0;
e0001a05 356
c9594989
AM
357 free (intisa->state_lookup_table);
358 intisa->state_lookup_table = 0;
359
360 free (intisa->sysreg_lookup_table);
361 intisa->sysreg_lookup_table = 0;
43cd72b9 362
43cd72b9
BW
363 for (n = 0; n < 2; n++)
364 {
c9594989
AM
365 free (intisa->sysreg_table[n]);
366 intisa->sysreg_table[n] = 0;
e0001a05 367 }
43cd72b9 368
c9594989
AM
369 free (intisa->interface_lookup_table);
370 intisa->interface_lookup_table = 0;
43cd72b9 371
c9594989
AM
372 free (intisa->funcUnit_lookup_table);
373 intisa->funcUnit_lookup_table = 0;
43cd72b9
BW
374}
375
376
377int
378xtensa_isa_name_compare (const void *v1, const void *v2)
379{
380 xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
381 xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
382
383 return strcasecmp (e1->key, e2->key);
384}
385
386
387int
388xtensa_isa_maxlength (xtensa_isa isa)
389{
390 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
391 return intisa->insn_size;
392}
393
394
395int
f075ee0c 396xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
43cd72b9
BW
397{
398 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
399 return (intisa->length_decode_fn) (cp);
400}
401
402
403int
68ffbac6 404xtensa_isa_num_pipe_stages (xtensa_isa isa)
43cd72b9 405{
43cd72b9
BW
406 xtensa_opcode opcode;
407 xtensa_funcUnit_use *use;
1fbc7e7a 408 int num_opcodes, num_uses;
77cba8a3
BW
409 int i, stage;
410 static int max_stage = XTENSA_UNDEFINED;
411
412 /* Only compute the value once. */
413 if (max_stage != XTENSA_UNDEFINED)
414 return max_stage + 1;
43cd72b9
BW
415
416 num_opcodes = xtensa_isa_num_opcodes (isa);
417 for (opcode = 0; opcode < num_opcodes; opcode++)
418 {
419 num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
420 for (i = 0; i < num_uses; i++)
421 {
422 use = xtensa_opcode_funcUnit_use (isa, opcode, i);
423 stage = use->stage;
424 if (stage > max_stage)
425 max_stage = stage;
426 }
427 }
428
429 return max_stage + 1;
430}
431
432
433int
434xtensa_isa_num_formats (xtensa_isa isa)
435{
436 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
437 return intisa->num_formats;
438}
439
440
441int
442xtensa_isa_num_opcodes (xtensa_isa isa)
443{
444 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
445 return intisa->num_opcodes;
446}
447
448
449int
450xtensa_isa_num_regfiles (xtensa_isa isa)
451{
452 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
453 return intisa->num_regfiles;
454}
455
456
457int
458xtensa_isa_num_states (xtensa_isa isa)
459{
460 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
461 return intisa->num_states;
462}
463
464
465int
466xtensa_isa_num_sysregs (xtensa_isa isa)
467{
468 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
469 return intisa->num_sysregs;
470}
471
472
473int
474xtensa_isa_num_interfaces (xtensa_isa isa)
475{
476 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
477 return intisa->num_interfaces;
478}
479
480
481int
482xtensa_isa_num_funcUnits (xtensa_isa isa)
483{
484 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
485 return intisa->num_funcUnits;
486}
487
488
489\f
490/* Instruction formats. */
491
492
493#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
494 do { \
495 if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
496 { \
497 xtisa_errno = xtensa_isa_bad_format; \
498 strcpy (xtisa_error_msg, "invalid format specifier"); \
499 return (ERRVAL); \
500 } \
501 } while (0)
502
503
504#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
505 do { \
506 if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
507 { \
508 xtisa_errno = xtensa_isa_bad_slot; \
509 strcpy (xtisa_error_msg, "invalid slot specifier"); \
510 return (ERRVAL); \
511 } \
512 } while (0)
513
514
515const char *
516xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
517{
518 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
519 CHECK_FORMAT (intisa, fmt, NULL);
520 return intisa->formats[fmt].name;
521}
522
523
524xtensa_format
525xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
526{
527 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
528 int fmt;
529
530 if (!fmtname || !*fmtname)
531 {
532 xtisa_errno = xtensa_isa_bad_format;
533 strcpy (xtisa_error_msg, "invalid format name");
534 return XTENSA_UNDEFINED;
535 }
536
537 for (fmt = 0; fmt < intisa->num_formats; fmt++)
538 {
539 if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
540 return fmt;
541 }
68ffbac6 542
43cd72b9
BW
543 xtisa_errno = xtensa_isa_bad_format;
544 sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
545 return XTENSA_UNDEFINED;
546}
547
548
549xtensa_format
550xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
551{
552 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
553 xtensa_format fmt;
554
555 fmt = (intisa->format_decode_fn) (insn);
556 if (fmt != XTENSA_UNDEFINED)
557 return fmt;
558
559 xtisa_errno = xtensa_isa_bad_format;
560 strcpy (xtisa_error_msg, "cannot decode instruction format");
561 return XTENSA_UNDEFINED;
562}
563
564
565int
566xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
567{
568 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
569 CHECK_FORMAT (intisa, fmt, -1);
570 (*intisa->formats[fmt].encode_fn) (insn);
571 return 0;
572}
573
574
575int
576xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
577{
578 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
579 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
580 return intisa->formats[fmt].length;
581}
582
583
584int
585xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
586{
587 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
588 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589 return intisa->formats[fmt].num_slots;
590}
591
592
593xtensa_opcode
594xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
595{
596 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
597 int slot_id;
598
599 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
600 CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
601
602 slot_id = intisa->formats[fmt].slot_id[slot];
603 return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
604}
605
606
607int
608xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
609 const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
610{
611 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
612 int slot_id;
613
614 CHECK_FORMAT (intisa, fmt, -1);
615 CHECK_SLOT (intisa, fmt, slot, -1);
616
617 slot_id = intisa->formats[fmt].slot_id[slot];
618 (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
619 return 0;
620}
621
622
623int
624xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
625 xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
626{
627 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
628 int slot_id;
629
630 CHECK_FORMAT (intisa, fmt, -1);
631 CHECK_SLOT (intisa, fmt, slot, -1);
632
633 slot_id = intisa->formats[fmt].slot_id[slot];
634 (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
635 return 0;
636}
637
638
639\f
640/* Opcode information. */
641
642
643#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
644 do { \
645 if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
646 { \
647 xtisa_errno = xtensa_isa_bad_opcode; \
648 strcpy (xtisa_error_msg, "invalid opcode specifier"); \
649 return (ERRVAL); \
650 } \
651 } while (0)
652
653
654xtensa_opcode
655xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
656{
657 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1fbc7e7a 658 xtensa_lookup_entry entry, *result = 0;
43cd72b9
BW
659
660 if (!opname || !*opname)
661 {
662 xtisa_errno = xtensa_isa_bad_opcode;
663 strcpy (xtisa_error_msg, "invalid opcode name");
664 return XTENSA_UNDEFINED;
665 }
666
1fbc7e7a
BW
667 if (intisa->num_opcodes != 0)
668 {
669 entry.key = opname;
670 result = bsearch (&entry, intisa->opname_lookup_table,
671 intisa->num_opcodes, sizeof (xtensa_lookup_entry),
672 xtensa_isa_name_compare);
673 }
43cd72b9
BW
674
675 if (!result)
676 {
677 xtisa_errno = xtensa_isa_bad_opcode;
678 sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
679 return XTENSA_UNDEFINED;
680 }
681
682 return result->u.opcode;
683}
684
685
686xtensa_opcode
687xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
688 const xtensa_insnbuf slotbuf)
689{
690 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
691 int slot_id;
692 xtensa_opcode opc;
693
694 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
695 CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
696
697 slot_id = intisa->formats[fmt].slot_id[slot];
698
699 opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
1fbc7e7a
BW
700 if (opc != XTENSA_UNDEFINED)
701 return opc;
702
703 xtisa_errno = xtensa_isa_bad_opcode;
704 strcpy (xtisa_error_msg, "cannot decode opcode");
705 return XTENSA_UNDEFINED;
43cd72b9
BW
706}
707
708
709int
710xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
711 xtensa_insnbuf slotbuf, xtensa_opcode opc)
712{
713 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
714 int slot_id;
715 xtensa_opcode_encode_fn encode_fn;
716
717 CHECK_FORMAT (intisa, fmt, -1);
718 CHECK_SLOT (intisa, fmt, slot, -1);
719 CHECK_OPCODE (intisa, opc, -1);
720
721 slot_id = intisa->formats[fmt].slot_id[slot];
722 encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
723 if (!encode_fn)
724 {
725 xtisa_errno = xtensa_isa_wrong_slot;
726 sprintf (xtisa_error_msg,
727 "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
728 intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
729 return -1;
730 }
731 (*encode_fn) (slotbuf);
732 return 0;
733}
734
735
736const char *
737xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
738{
739 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
740 CHECK_OPCODE (intisa, opc, NULL);
741 return intisa->opcodes[opc].name;
742}
743
744
745int
746xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
747{
748 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
751 return 1;
752 return 0;
753}
754
755
756int
757xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
758{
759 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
762 return 1;
763 return 0;
764}
765
766
767int
768xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
769{
770 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
771 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
772 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
773 return 1;
774 return 0;
775}
776
777
778int
779xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
780{
781 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
783 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
784 return 1;
785 return 0;
786}
787
788
789int
790xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
791{
792 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
793 int iclass_id;
794
795 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
796 iclass_id = intisa->opcodes[opc].iclass_id;
797 return intisa->iclasses[iclass_id].num_operands;
798}
799
800
801int
802xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
803{
804 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
805 int iclass_id;
806
807 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
808 iclass_id = intisa->opcodes[opc].iclass_id;
809 return intisa->iclasses[iclass_id].num_stateOperands;
810}
811
812
813int
814xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
815{
816 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
817 int iclass_id;
818
819 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
820 iclass_id = intisa->opcodes[opc].iclass_id;
821 return intisa->iclasses[iclass_id].num_interfaceOperands;
822}
823
824
825int
826xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
827{
828 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
829 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
830 return intisa->opcodes[opc].num_funcUnit_uses;
831}
832
833
834xtensa_funcUnit_use *
835xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
836{
837 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
838 CHECK_OPCODE (intisa, opc, NULL);
839 if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
840 {
841 xtisa_errno = xtensa_isa_bad_funcUnit;
842 sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
843 "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
844 intisa->opcodes[opc].num_funcUnit_uses);
845 return NULL;
846 }
847 return &intisa->opcodes[opc].funcUnit_uses[u];
848}
849
850
851\f
852/* Operand information. */
853
854
855#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
856 do { \
857 if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
858 { \
859 xtisa_errno = xtensa_isa_bad_operand; \
860 sprintf (xtisa_error_msg, "invalid operand number (%d); " \
861 "opcode \"%s\" has %d operands", (OPND), \
862 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
863 return (ERRVAL); \
864 } \
865 } while (0)
866
867
868static xtensa_operand_internal *
869get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
870{
871 xtensa_iclass_internal *iclass;
872 int iclass_id, operand_id;
873
874 CHECK_OPCODE (intisa, opc, NULL);
875 iclass_id = intisa->opcodes[opc].iclass_id;
876 iclass = &intisa->iclasses[iclass_id];
877 CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
878 operand_id = iclass->operands[opnd].u.operand_id;
879 return &intisa->operands[operand_id];
880}
881
882
883const char *
884xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
885{
886 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
887 xtensa_operand_internal *intop;
888
889 intop = get_operand (intisa, opc, opnd);
890 if (!intop) return NULL;
891 return intop->name;
892}
893
894
895int
896xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
897{
898 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
899 xtensa_iclass_internal *iclass;
900 int iclass_id, operand_id;
901 xtensa_operand_internal *intop;
902
903 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
904 iclass_id = intisa->opcodes[opc].iclass_id;
905 iclass = &intisa->iclasses[iclass_id];
906 CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
907
908 /* Special case for "sout" operands. */
909 if (iclass->operands[opnd].inout == 's')
910 return 0;
911
912 operand_id = iclass->operands[opnd].u.operand_id;
913 intop = &intisa->operands[operand_id];
914
915 if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
916 return 1;
917 return 0;
918}
919
920
921char
922xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
923{
924 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
925 xtensa_iclass_internal *iclass;
926 int iclass_id;
927 char inout;
928
929 CHECK_OPCODE (intisa, opc, 0);
930 iclass_id = intisa->opcodes[opc].iclass_id;
931 iclass = &intisa->iclasses[iclass_id];
932 CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
933 inout = iclass->operands[opnd].inout;
934
935 /* Special case for "sout" operands. */
936 if (inout == 's')
937 return 'o';
938
939 return inout;
940}
941
942
943int
944xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
945 xtensa_format fmt, int slot,
946 const xtensa_insnbuf slotbuf, uint32 *valp)
947{
948 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
949 xtensa_operand_internal *intop;
950 int slot_id;
951 xtensa_get_field_fn get_fn;
952
953 intop = get_operand (intisa, opc, opnd);
954 if (!intop) return -1;
955
956 CHECK_FORMAT (intisa, fmt, -1);
957 CHECK_SLOT (intisa, fmt, slot, -1);
958
959 slot_id = intisa->formats[fmt].slot_id[slot];
960 if (intop->field_id == XTENSA_UNDEFINED)
961 {
962 xtisa_errno = xtensa_isa_no_field;
963 strcpy (xtisa_error_msg, "implicit operand has no field");
964 return -1;
965 }
966 get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
967 if (!get_fn)
968 {
969 xtisa_errno = xtensa_isa_wrong_slot;
970 sprintf (xtisa_error_msg,
971 "operand \"%s\" does not exist in slot %d of format \"%s\"",
972 intop->name, slot, intisa->formats[fmt].name);
973 return -1;
974 }
975 *valp = (*get_fn) (slotbuf);
976 return 0;
977}
978
979
980int
981xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
982 xtensa_format fmt, int slot,
983 xtensa_insnbuf slotbuf, uint32 val)
984{
985 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
986 xtensa_operand_internal *intop;
987 int slot_id;
988 xtensa_set_field_fn set_fn;
989
990 intop = get_operand (intisa, opc, opnd);
991 if (!intop) return -1;
992
993 CHECK_FORMAT (intisa, fmt, -1);
994 CHECK_SLOT (intisa, fmt, slot, -1);
995
996 slot_id = intisa->formats[fmt].slot_id[slot];
997 if (intop->field_id == XTENSA_UNDEFINED)
998 {
999 xtisa_errno = xtensa_isa_no_field;
1000 strcpy (xtisa_error_msg, "implicit operand has no field");
1001 return -1;
1002 }
1003 set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1004 if (!set_fn)
1005 {
1006 xtisa_errno = xtensa_isa_wrong_slot;
1007 sprintf (xtisa_error_msg,
1008 "operand \"%s\" does not exist in slot %d of format \"%s\"",
1009 intop->name, slot, intisa->formats[fmt].name);
1010 return -1;
1011 }
1012 (*set_fn) (slotbuf, val);
1013 return 0;
e0001a05
NC
1014}
1015
e0001a05 1016
43cd72b9
BW
1017int
1018xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1019 uint32 *valp)
e0001a05 1020{
43cd72b9
BW
1021 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1022 xtensa_operand_internal *intop;
1023 uint32 test_val, orig_val;
e0001a05 1024
43cd72b9 1025 intop = get_operand (intisa, opc, opnd);
91d6fa6a
NC
1026 if (!intop)
1027 return -1;
e0001a05 1028
43cd72b9 1029 if (!intop->encode)
e0001a05 1030 {
43cd72b9
BW
1031 /* This is a default operand for a field. How can we tell if the
1032 value fits in the field? Write the value into the field,
1033 read it back, and then make sure we get the same value. */
43cd72b9
BW
1034 static xtensa_insnbuf tmpbuf = 0;
1035 int slot_id;
e0001a05 1036
43cd72b9 1037 if (!tmpbuf)
e0001a05 1038 {
43cd72b9
BW
1039 tmpbuf = xtensa_insnbuf_alloc (isa);
1040 CHECK_ALLOC (tmpbuf, -1);
e0001a05 1041 }
43cd72b9
BW
1042
1043 /* A default operand is always associated with a field,
1044 but check just to be sure.... */
1045 if (intop->field_id == XTENSA_UNDEFINED)
e0001a05 1046 {
43cd72b9
BW
1047 xtisa_errno = xtensa_isa_internal_error;
1048 strcpy (xtisa_error_msg, "operand has no field");
1049 return -1;
e0001a05
NC
1050 }
1051
43cd72b9
BW
1052 /* Find some slot that includes the field. */
1053 for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
e0001a05 1054 {
43cd72b9
BW
1055 xtensa_get_field_fn get_fn =
1056 intisa->slots[slot_id].get_field_fns[intop->field_id];
1057 xtensa_set_field_fn set_fn =
1058 intisa->slots[slot_id].set_field_fns[intop->field_id];
1059
1060 if (get_fn && set_fn)
e0001a05 1061 {
43cd72b9
BW
1062 (*set_fn) (tmpbuf, *valp);
1063 return ((*get_fn) (tmpbuf) != *valp);
e0001a05
NC
1064 }
1065 }
43cd72b9
BW
1066
1067 /* Couldn't find any slot containing the field.... */
1068 xtisa_errno = xtensa_isa_no_field;
1069 strcpy (xtisa_error_msg, "field does not exist in any slot");
1070 return -1;
1071 }
1072
1073 /* Encode the value. In some cases, the encoding function may detect
1074 errors, but most of the time the only way to determine if the value
1075 was successfully encoded is to decode it and check if it matches
1076 the original value. */
1077 orig_val = *valp;
91d6fa6a
NC
1078 if ((*intop->encode) (valp)
1079 || (test_val = *valp, (*intop->decode) (&test_val))
1080 || test_val != orig_val)
43cd72b9
BW
1081 {
1082 xtisa_errno = xtensa_isa_bad_value;
1083 sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1084 return -1;
e0001a05
NC
1085 }
1086
43cd72b9 1087 return 0;
e0001a05
NC
1088}
1089
1090
43cd72b9
BW
1091int
1092xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1093 uint32 *valp)
e0001a05 1094{
43cd72b9
BW
1095 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1096 xtensa_operand_internal *intop;
e0001a05 1097
43cd72b9
BW
1098 intop = get_operand (intisa, opc, opnd);
1099 if (!intop) return -1;
e0001a05 1100
43cd72b9
BW
1101 /* Use identity function for "default" operands. */
1102 if (!intop->decode)
e0001a05
NC
1103 return 0;
1104
43cd72b9 1105 if ((*intop->decode) (valp))
e0001a05 1106 {
43cd72b9
BW
1107 xtisa_errno = xtensa_isa_bad_value;
1108 sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
1109 return -1;
e0001a05 1110 }
43cd72b9
BW
1111 return 0;
1112}
e0001a05 1113
e0001a05 1114
43cd72b9
BW
1115int
1116xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1117{
1118 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1119 xtensa_operand_internal *intop;
e0001a05 1120
43cd72b9
BW
1121 intop = get_operand (intisa, opc, opnd);
1122 if (!intop) return XTENSA_UNDEFINED;
e0001a05 1123
43cd72b9
BW
1124 if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1125 return 1;
1126 return 0;
1127}
e0001a05 1128
e0001a05 1129
43cd72b9
BW
1130xtensa_regfile
1131xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1132{
1133 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1134 xtensa_operand_internal *intop;
e0001a05 1135
43cd72b9
BW
1136 intop = get_operand (intisa, opc, opnd);
1137 if (!intop) return XTENSA_UNDEFINED;
e0001a05 1138
43cd72b9 1139 return intop->regfile;
e0001a05
NC
1140}
1141
1142
43cd72b9
BW
1143int
1144xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
e0001a05 1145{
43cd72b9
BW
1146 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1147 xtensa_operand_internal *intop;
e0001a05 1148
43cd72b9
BW
1149 intop = get_operand (intisa, opc, opnd);
1150 if (!intop) return XTENSA_UNDEFINED;
1151
1152 return intop->num_regs;
e0001a05
NC
1153}
1154
1155
1156int
43cd72b9 1157xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
e0001a05
NC
1158{
1159 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1160 xtensa_operand_internal *intop;
1161
1162 intop = get_operand (intisa, opc, opnd);
1163 if (!intop) return XTENSA_UNDEFINED;
1164
1165 if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
1166 return 1;
1167 return 0;
e0001a05
NC
1168}
1169
1170
43cd72b9
BW
1171int
1172xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
e0001a05
NC
1173{
1174 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1175 xtensa_operand_internal *intop;
1176
1177 intop = get_operand (intisa, opc, opnd);
1178 if (!intop) return XTENSA_UNDEFINED;
1179
1180 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1181 return 1;
1182 return 0;
e0001a05
NC
1183}
1184
1185
1186int
43cd72b9
BW
1187xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1188 uint32 *valp, uint32 pc)
e0001a05
NC
1189{
1190 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1191 xtensa_operand_internal *intop;
1192
1193 intop = get_operand (intisa, opc, opnd);
1194 if (!intop) return -1;
1195
1196 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1197 return 0;
1198
1199 if (!intop->do_reloc)
1200 {
1201 xtisa_errno = xtensa_isa_internal_error;
1202 strcpy (xtisa_error_msg, "operand missing do_reloc function");
1203 return -1;
1204 }
1205
1206 if ((*intop->do_reloc) (valp, pc))
1207 {
1208 xtisa_errno = xtensa_isa_bad_value;
1209 sprintf (xtisa_error_msg,
1210 "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1211 return -1;
1212 }
1213
1214 return 0;
e0001a05
NC
1215}
1216
1217
1218int
43cd72b9
BW
1219xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1220 uint32 *valp, uint32 pc)
e0001a05 1221{
43cd72b9
BW
1222 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1223 xtensa_operand_internal *intop;
1224
1225 intop = get_operand (intisa, opc, opnd);
1226 if (!intop) return -1;
1227
1228 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1229 return 0;
1230
1231 if (!intop->undo_reloc)
1232 {
1233 xtisa_errno = xtensa_isa_internal_error;
1234 strcpy (xtisa_error_msg, "operand missing undo_reloc function");
1235 return -1;
1236 }
1237
1238 if ((*intop->undo_reloc) (valp, pc))
1239 {
1240 xtisa_errno = xtensa_isa_bad_value;
1241 sprintf (xtisa_error_msg,
1242 "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1243 return -1;
1244 }
1245
1246 return 0;
e0001a05
NC
1247}
1248
1249
43cd72b9
BW
1250\f
1251/* State Operands. */
1252
1253
1254#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
1255 do { \
1256 if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
1257 { \
1258 xtisa_errno = xtensa_isa_bad_operand; \
1259 sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
1260 "opcode \"%s\" has %d state operands", (STOP), \
1261 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
1262 return (ERRVAL); \
1263 } \
1264 } while (0)
1265
1266
1267xtensa_state
1268xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
e0001a05
NC
1269{
1270 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1271 xtensa_iclass_internal *iclass;
1272 int iclass_id;
1273
1274 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1275 iclass_id = intisa->opcodes[opc].iclass_id;
1276 iclass = &intisa->iclasses[iclass_id];
1277 CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
1278 return iclass->stateOperands[stOp].u.state;
e0001a05
NC
1279}
1280
1281
43cd72b9
BW
1282char
1283xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
e0001a05
NC
1284{
1285 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1286 xtensa_iclass_internal *iclass;
1287 int iclass_id;
1288
1289 CHECK_OPCODE (intisa, opc, 0);
1290 iclass_id = intisa->opcodes[opc].iclass_id;
1291 iclass = &intisa->iclasses[iclass_id];
1292 CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
1293 return iclass->stateOperands[stOp].inout;
1294}
e0001a05 1295
1fbc7e7a 1296
43cd72b9
BW
1297\f
1298/* Interface Operands. */
1299
1300
1301#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
1302 do { \
1303 if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
1304 { \
1305 xtisa_errno = xtensa_isa_bad_operand; \
1306 sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
1307 "opcode \"%s\" has %d interface operands", (IFOP), \
1308 (INTISA)->opcodes[(OPC)].name, \
1309 (ICLASS)->num_interfaceOperands); \
1310 return (ERRVAL); \
1311 } \
1312 } while (0)
1313
1314
1315xtensa_interface
1316xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
1317 int ifOp)
1318{
1319 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1320 xtensa_iclass_internal *iclass;
1321 int iclass_id;
1322
1323 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1324 iclass_id = intisa->opcodes[opc].iclass_id;
1325 iclass = &intisa->iclasses[iclass_id];
1326 CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
1327 return iclass->interfaceOperands[ifOp];
e0001a05
NC
1328}
1329
1330
43cd72b9
BW
1331\f
1332/* Register Files. */
1333
1334
1335#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
1336 do { \
1337 if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1338 { \
1339 xtisa_errno = xtensa_isa_bad_regfile; \
1340 strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1341 return (ERRVAL); \
1342 } \
1343 } while (0)
1344
1345
1346xtensa_regfile
1347xtensa_regfile_lookup (xtensa_isa isa, const char *name)
e0001a05
NC
1348{
1349 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1350 int n;
1351
1352 if (!name || !*name)
1353 {
1354 xtisa_errno = xtensa_isa_bad_regfile;
1355 strcpy (xtisa_error_msg, "invalid regfile name");
1356 return XTENSA_UNDEFINED;
1357 }
1358
1359 /* The expected number of regfiles is small; use a linear search. */
1360 for (n = 0; n < intisa->num_regfiles; n++)
1361 {
007d6189 1362 if (!filename_cmp (intisa->regfiles[n].name, name))
43cd72b9
BW
1363 return n;
1364 }
1365
1366 xtisa_errno = xtensa_isa_bad_regfile;
1367 sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
e0001a05
NC
1368 return XTENSA_UNDEFINED;
1369}
1370
1371
43cd72b9
BW
1372xtensa_regfile
1373xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
e0001a05
NC
1374{
1375 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
e0001a05
NC
1376 int n;
1377
43cd72b9
BW
1378 if (!shortname || !*shortname)
1379 {
1380 xtisa_errno = xtensa_isa_bad_regfile;
1381 strcpy (xtisa_error_msg, "invalid regfile shortname");
1382 return XTENSA_UNDEFINED;
1383 }
e0001a05 1384
43cd72b9
BW
1385 /* The expected number of regfiles is small; use a linear search. */
1386 for (n = 0; n < intisa->num_regfiles; n++)
1387 {
1388 /* Ignore regfile views since they always have the same shortnames
1389 as their parents. */
1390 if (intisa->regfiles[n].parent != n)
1391 continue;
007d6189 1392 if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
43cd72b9
BW
1393 return n;
1394 }
e0001a05 1395
43cd72b9
BW
1396 xtisa_errno = xtensa_isa_bad_regfile;
1397 sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
1398 shortname);
1399 return XTENSA_UNDEFINED;
e0001a05
NC
1400}
1401
1402
1403const char *
43cd72b9 1404xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
e0001a05
NC
1405{
1406 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1407 CHECK_REGFILE (intisa, rf, NULL);
1408 return intisa->regfiles[rf].name;
e0001a05
NC
1409}
1410
1411
43cd72b9
BW
1412const char *
1413xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
e0001a05
NC
1414{
1415 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1416 CHECK_REGFILE (intisa, rf, NULL);
1417 return intisa->regfiles[rf].shortname;
e0001a05
NC
1418}
1419
1420
43cd72b9
BW
1421xtensa_regfile
1422xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
e0001a05
NC
1423{
1424 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1425 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1426 return intisa->regfiles[rf].parent;
e0001a05
NC
1427}
1428
1429
1430int
43cd72b9 1431xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
e0001a05
NC
1432{
1433 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1434 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1435 return intisa->regfiles[rf].num_bits;
e0001a05
NC
1436}
1437
1438
43cd72b9
BW
1439int
1440xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
e0001a05
NC
1441{
1442 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1443 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1444 return intisa->regfiles[rf].num_entries;
e0001a05
NC
1445}
1446
1fbc7e7a 1447
43cd72b9
BW
1448\f
1449/* Processor States. */
e0001a05 1450
e0001a05 1451
43cd72b9
BW
1452#define CHECK_STATE(INTISA,ST,ERRVAL) \
1453 do { \
1454 if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
1455 { \
1456 xtisa_errno = xtensa_isa_bad_state; \
1457 strcpy (xtisa_error_msg, "invalid state specifier"); \
1458 return (ERRVAL); \
1459 } \
1460 } while (0)
e0001a05
NC
1461
1462
43cd72b9
BW
1463xtensa_state
1464xtensa_state_lookup (xtensa_isa isa, const char *name)
e0001a05 1465{
43cd72b9 1466 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1fbc7e7a 1467 xtensa_lookup_entry entry, *result = 0;
e0001a05 1468
43cd72b9
BW
1469 if (!name || !*name)
1470 {
1471 xtisa_errno = xtensa_isa_bad_state;
1472 strcpy (xtisa_error_msg, "invalid state name");
1473 return XTENSA_UNDEFINED;
1474 }
e0001a05 1475
1fbc7e7a
BW
1476 if (intisa->num_states != 0)
1477 {
1478 entry.key = name;
1479 result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
1480 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
1481 }
e0001a05 1482
43cd72b9
BW
1483 if (!result)
1484 {
1485 xtisa_errno = xtensa_isa_bad_state;
1486 sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
1487 return XTENSA_UNDEFINED;
1488 }
e0001a05 1489
43cd72b9 1490 return result->u.state;
e0001a05
NC
1491}
1492
1493
43cd72b9
BW
1494const char *
1495xtensa_state_name (xtensa_isa isa, xtensa_state st)
e0001a05 1496{
43cd72b9
BW
1497 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1498 CHECK_STATE (intisa, st, NULL);
1499 return intisa->states[st].name;
e0001a05
NC
1500}
1501
1502
43cd72b9
BW
1503int
1504xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
e0001a05 1505{
43cd72b9
BW
1506 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1507 CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1508 return intisa->states[st].num_bits;
e0001a05
NC
1509}
1510
1511
1512int
43cd72b9 1513xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
e0001a05 1514{
43cd72b9
BW
1515 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1516 CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1517 if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
1518 return 1;
1519 return 0;
e0001a05
NC
1520}
1521
1fbc7e7a 1522
1fa3cd83
SA
1523int
1524xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
1525{
1526 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1527 CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1528 if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
1529 return 1;
1530 return 0;
1531}
1532
1533
43cd72b9
BW
1534\f
1535/* Sysregs. */
1536
1537
1538#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1539 do { \
1540 if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1541 { \
1542 xtisa_errno = xtensa_isa_bad_sysreg; \
1543 strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1544 return (ERRVAL); \
1545 } \
1546 } while (0)
e0001a05 1547
43cd72b9
BW
1548
1549xtensa_sysreg
1550xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
e0001a05 1551{
43cd72b9
BW
1552 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1553
1554 if (is_user != 0)
1555 is_user = 1;
1556
1557 if (num < 0 || num > intisa->max_sysreg_num[is_user]
1558 || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1559 {
1560 xtisa_errno = xtensa_isa_bad_sysreg;
1561 strcpy (xtisa_error_msg, "sysreg not recognized");
1562 return XTENSA_UNDEFINED;
1563 }
1564
1565 return intisa->sysreg_table[is_user][num];
e0001a05
NC
1566}
1567
1568
43cd72b9
BW
1569xtensa_sysreg
1570xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
e0001a05 1571{
43cd72b9 1572 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1fbc7e7a 1573 xtensa_lookup_entry entry, *result = 0;
e0001a05 1574
43cd72b9
BW
1575 if (!name || !*name)
1576 {
1577 xtisa_errno = xtensa_isa_bad_sysreg;
1578 strcpy (xtisa_error_msg, "invalid sysreg name");
1579 return XTENSA_UNDEFINED;
1580 }
e0001a05 1581
1fbc7e7a
BW
1582 if (intisa->num_sysregs != 0)
1583 {
1584 entry.key = name;
1585 result = bsearch (&entry, intisa->sysreg_lookup_table,
1586 intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1587 xtensa_isa_name_compare);
1588 }
e0001a05 1589
43cd72b9
BW
1590 if (!result)
1591 {
1592 xtisa_errno = xtensa_isa_bad_sysreg;
1593 sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1594 return XTENSA_UNDEFINED;
1595 }
1596
1597 return result->u.sysreg;
e0001a05
NC
1598}
1599
1600
43cd72b9
BW
1601const char *
1602xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
e0001a05 1603{
43cd72b9
BW
1604 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1605 CHECK_SYSREG (intisa, sysreg, NULL);
1606 return intisa->sysregs[sysreg].name;
e0001a05
NC
1607}
1608
1609
43cd72b9
BW
1610int
1611xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
e0001a05 1612{
43cd72b9
BW
1613 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1614 CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1615 return intisa->sysregs[sysreg].number;
e0001a05
NC
1616}
1617
1618
43cd72b9
BW
1619int
1620xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
e0001a05 1621{
43cd72b9
BW
1622 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1623 CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1624 if (intisa->sysregs[sysreg].is_user)
1625 return 1;
1626 return 0;
e0001a05
NC
1627}
1628
1fbc7e7a 1629
43cd72b9
BW
1630\f
1631/* Interfaces. */
e0001a05 1632
e0001a05 1633
43cd72b9
BW
1634#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1635 do { \
1636 if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1637 { \
1638 xtisa_errno = xtensa_isa_bad_interface; \
1639 strcpy (xtisa_error_msg, "invalid interface specifier"); \
1640 return (ERRVAL); \
1641 } \
1642 } while (0)
1643
1644
1645xtensa_interface
1646xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
e0001a05
NC
1647{
1648 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1fbc7e7a 1649 xtensa_lookup_entry entry, *result = 0;
e0001a05 1650
43cd72b9 1651 if (!ifname || !*ifname)
e0001a05 1652 {
43cd72b9
BW
1653 xtisa_errno = xtensa_isa_bad_interface;
1654 strcpy (xtisa_error_msg, "invalid interface name");
1655 return XTENSA_UNDEFINED;
e0001a05 1656 }
43cd72b9 1657
1fbc7e7a
BW
1658 if (intisa->num_interfaces != 0)
1659 {
1660 entry.key = ifname;
1661 result = bsearch (&entry, intisa->interface_lookup_table,
1662 intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1663 xtensa_isa_name_compare);
1664 }
43cd72b9
BW
1665
1666 if (!result)
e0001a05 1667 {
43cd72b9
BW
1668 xtisa_errno = xtensa_isa_bad_interface;
1669 sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1670 return XTENSA_UNDEFINED;
e0001a05
NC
1671 }
1672
43cd72b9
BW
1673 return result->u.intf;
1674}
e0001a05 1675
e0001a05 1676
43cd72b9
BW
1677const char *
1678xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1679{
1680 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1681 CHECK_INTERFACE (intisa, intf, NULL);
1682 return intisa->interfaces[intf].name;
1683}
e0001a05 1684
43cd72b9
BW
1685
1686int
1687xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1688{
1689 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1690 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1691 return intisa->interfaces[intf].num_bits;
e0001a05
NC
1692}
1693
43cd72b9
BW
1694
1695char
1696xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
e0001a05
NC
1697{
1698 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
43cd72b9
BW
1699 CHECK_INTERFACE (intisa, intf, 0);
1700 return intisa->interfaces[intf].inout;
1701}
e0001a05 1702
43cd72b9
BW
1703
1704int
1705xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1706{
1707 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1708 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1709 if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1710 return 1;
1711 return 0;
1712}
1713
a1ace8d8
BW
1714
1715int
1716xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1717{
1718 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1719 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1720 return intisa->interfaces[intf].class_id;
1721}
1722
1fbc7e7a 1723
43cd72b9
BW
1724\f
1725/* Functional Units. */
1726
1727
1728#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1729 do { \
1730 if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1731 { \
1732 xtisa_errno = xtensa_isa_bad_funcUnit; \
1733 strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1734 return (ERRVAL); \
1735 } \
1736 } while (0)
1737
1738
1739xtensa_funcUnit
1740xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1741{
1742 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1fbc7e7a 1743 xtensa_lookup_entry entry, *result = 0;
43cd72b9
BW
1744
1745 if (!fname || !*fname)
e0001a05 1746 {
43cd72b9
BW
1747 xtisa_errno = xtensa_isa_bad_funcUnit;
1748 strcpy (xtisa_error_msg, "invalid functional unit name");
1749 return XTENSA_UNDEFINED;
e0001a05 1750 }
43cd72b9 1751
1fbc7e7a
BW
1752 if (intisa->num_funcUnits != 0)
1753 {
1754 entry.key = fname;
1755 result = bsearch (&entry, intisa->funcUnit_lookup_table,
1756 intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1757 xtensa_isa_name_compare);
1758 }
43cd72b9
BW
1759
1760 if (!result)
e0001a05 1761 {
43cd72b9
BW
1762 xtisa_errno = xtensa_isa_bad_funcUnit;
1763 sprintf (xtisa_error_msg,
1764 "functional unit \"%s\" not recognized", fname);
1765 return XTENSA_UNDEFINED;
e0001a05
NC
1766 }
1767
43cd72b9
BW
1768 return result->u.fun;
1769}
e0001a05 1770
e0001a05 1771
43cd72b9
BW
1772const char *
1773xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1774{
1775 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1776 CHECK_FUNCUNIT (intisa, fun, NULL);
1777 return intisa->funcUnits[fun].name;
1778}
1779
1780
1781int
1782xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1783{
1784 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1785 CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1786 return intisa->funcUnits[fun].num_copies;
e0001a05
NC
1787}
1788