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