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