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