xref: /netbsd-src/external/gpl3/gdb.old/dist/bfd/xtensa-isa.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Configurable Xtensa ISA support.
2    Copyright (C) 2003-2022 Free Software Foundation, Inc.
3 
4    This file is part of BFD, the Binary File Descriptor library.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "libbfd.h"
24 #include "xtensa-isa.h"
25 #include "xtensa-isa-internal.h"
26 #include "xtensa-dynconfig.h"
27 
28 static xtensa_isa_status xtisa_errno;
29 static char xtisa_error_msg[1024];
30 
31 
32 xtensa_isa_status
33 xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
34 {
35   return xtisa_errno;
36 }
37 
38 
39 char *
40 xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
41 {
42   return xtisa_error_msg;
43 }
44 
45 
46 #define CHECK_ALLOC(MEM,ERRVAL) \
47   do { \
48     if ((MEM) == 0) \
49       { \
50 	xtisa_errno = xtensa_isa_out_of_memory; \
51 	strcpy (xtisa_error_msg, "out of memory"); \
52 	return (ERRVAL); \
53       } \
54   } while (0)
55 
56 #define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
57   do { \
58     if ((MEM) == 0) \
59       { \
60 	xtisa_errno = xtensa_isa_out_of_memory; \
61 	strcpy (xtisa_error_msg, "out of memory"); \
62 	if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
63 	if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
64 	return (ERRVAL); \
65       } \
66   } while (0)
67 
68 
69 
70 /* Instruction buffers.  */
71 
72 int
73 xtensa_insnbuf_size (xtensa_isa isa)
74 {
75   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
76   return intisa->insnbuf_size;
77 }
78 
79 
80 xtensa_insnbuf
81 xtensa_insnbuf_alloc (xtensa_isa isa)
82 {
83   xtensa_insnbuf result = (xtensa_insnbuf)
84     malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
85   CHECK_ALLOC (result, 0);
86   return result;
87 }
88 
89 
90 void
91 xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
92 		     xtensa_insnbuf buf)
93 {
94   free (buf);
95 }
96 
97 
98 /* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
99    internal representation of a xtensa instruction word, return the index of
100    its word and the bit index of its low order byte in the xtensa_insnbuf.  */
101 
102 static inline int
103 byte_to_word_index (int byte_index)
104 {
105   return byte_index / sizeof (xtensa_insnbuf_word);
106 }
107 
108 
109 static inline int
110 byte_to_bit_index (int byte_index)
111 {
112   return (byte_index & 0x3) * 8;
113 }
114 
115 
116 /* Copy an instruction in the 32-bit words pointed at by "insn" to
117    characters pointed at by "cp".  This is more complicated than you
118    might think because we want 16-bit instructions in bytes 2 & 3 for
119    big-endian configurations.  This function allows us to specify
120    which byte in "insn" to start with and which way to increment,
121    allowing trivial implementation for both big- and little-endian
122    configurations....and it seems to make pretty good code for
123    both.  */
124 
125 int
126 xtensa_insnbuf_to_chars (xtensa_isa isa,
127 			 const xtensa_insnbuf insn,
128 			 unsigned char *cp,
129 			 int num_chars)
130 {
131   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
132   int insn_size = xtensa_isa_maxlength (isa);
133   int fence_post, start, increment, i, byte_count;
134   xtensa_format fmt;
135 
136   if (num_chars == 0)
137     num_chars = insn_size;
138 
139   if (intisa->is_big_endian)
140     {
141       start = insn_size - 1;
142       increment = -1;
143     }
144   else
145     {
146       start = 0;
147       increment = 1;
148     }
149 
150   /* Find the instruction format.  Do nothing if the buffer does not contain
151      a valid instruction since we need to know how many bytes to copy.  */
152   fmt = xtensa_format_decode (isa, insn);
153   if (fmt == XTENSA_UNDEFINED)
154     return XTENSA_UNDEFINED;
155 
156   byte_count = xtensa_format_length (isa, fmt);
157   if (byte_count == XTENSA_UNDEFINED)
158     return XTENSA_UNDEFINED;
159 
160   if (byte_count > num_chars)
161     {
162       xtisa_errno = xtensa_isa_buffer_overflow;
163       strcpy (xtisa_error_msg, "output buffer too small for instruction");
164       return XTENSA_UNDEFINED;
165     }
166 
167   fence_post = start + (byte_count * increment);
168 
169   for (i = start; i != fence_post; i += increment, ++cp)
170     {
171       int word_inx = byte_to_word_index (i);
172       int bit_inx = byte_to_bit_index (i);
173 
174       *cp = (insn[word_inx] >> bit_inx) & 0xff;
175     }
176 
177   return byte_count;
178 }
179 
180 
181 /* Inward conversion from byte stream to xtensa_insnbuf.  See
182    xtensa_insnbuf_to_chars for a discussion of why this is complicated
183    by endianness.  */
184 
185 void
186 xtensa_insnbuf_from_chars (xtensa_isa isa,
187 			   xtensa_insnbuf insn,
188 			   const unsigned char *cp,
189 			   int num_chars)
190 {
191   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
192   int max_size, insn_size, fence_post, start, increment, i;
193 
194   max_size = xtensa_isa_maxlength (isa);
195 
196   /* Decode the instruction length so we know how many bytes to read.  */
197   insn_size = (intisa->length_decode_fn) (cp);
198   if (insn_size == XTENSA_UNDEFINED)
199     {
200       /* This should never happen when the byte stream contains a
201 	 valid instruction.  Just read the maximum number of bytes....  */
202       insn_size = max_size;
203     }
204 
205   if (num_chars == 0 || num_chars > insn_size)
206     num_chars = insn_size;
207 
208   if (intisa->is_big_endian)
209     {
210       start = max_size - 1;
211       increment = -1;
212     }
213   else
214     {
215       start = 0;
216       increment = 1;
217     }
218 
219   fence_post = start + (num_chars * increment);
220   memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
221 
222   for (i = start; i != fence_post; i += increment, ++cp)
223     {
224       int word_inx = byte_to_word_index (i);
225       int bit_inx = byte_to_bit_index (i);
226 
227       insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx;
228     }
229 }
230 
231 
232 /* ISA information.  */
233 
234 extern xtensa_isa_internal xtensa_modules;
235 
236 static xtensa_isa_internal *xtensa_get_modules (void)
237 {
238   static xtensa_isa_internal *modules;
239 
240   if (!modules)
241     modules = (xtensa_isa_internal *) xtensa_load_config ("xtensa_modules",
242 							  &xtensa_modules,
243 							  NULL);
244   return modules;
245 }
246 
247 xtensa_isa
248 xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
249 {
250   xtensa_isa_internal *isa = xtensa_get_modules ();
251   int n, is_user;
252 
253   /* Set up the opcode name lookup table.  */
254   isa->opname_lookup_table =
255     bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
256   CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
257   for (n = 0; n < isa->num_opcodes; n++)
258     {
259       isa->opname_lookup_table[n].key = isa->opcodes[n].name;
260       isa->opname_lookup_table[n].u.opcode = n;
261     }
262   qsort (isa->opname_lookup_table, isa->num_opcodes,
263 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
264 
265   /* Set up the state name lookup table.  */
266   isa->state_lookup_table =
267     bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
268   CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
269   for (n = 0; n < isa->num_states; n++)
270     {
271       isa->state_lookup_table[n].key = isa->states[n].name;
272       isa->state_lookup_table[n].u.state = n;
273     }
274   qsort (isa->state_lookup_table, isa->num_states,
275 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
276 
277   /* Set up the sysreg name lookup table.  */
278   isa->sysreg_lookup_table =
279     bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
280   CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
281   for (n = 0; n < isa->num_sysregs; n++)
282     {
283       isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
284       isa->sysreg_lookup_table[n].u.sysreg = n;
285     }
286   qsort (isa->sysreg_lookup_table, isa->num_sysregs,
287 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
288 
289   /* Set up the user & system sysreg number tables.  */
290   for (is_user = 0; is_user < 2; is_user++)
291     {
292       isa->sysreg_table[is_user] =
293 	bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
294 		    * sizeof (xtensa_sysreg));
295       CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
296 			    errno_p, error_msg_p);
297 
298       for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
299 	isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
300     }
301   for (n = 0; n < isa->num_sysregs; n++)
302     {
303       xtensa_sysreg_internal *sreg = &isa->sysregs[n];
304       is_user = sreg->is_user;
305 
306       if (sreg->number >= 0)
307 	isa->sysreg_table[is_user][sreg->number] = n;
308     }
309 
310   /* Set up the interface lookup table.  */
311   isa->interface_lookup_table =
312     bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
313   CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
314 			error_msg_p);
315   for (n = 0; n < isa->num_interfaces; n++)
316     {
317       isa->interface_lookup_table[n].key = isa->interfaces[n].name;
318       isa->interface_lookup_table[n].u.intf = n;
319     }
320   qsort (isa->interface_lookup_table, isa->num_interfaces,
321 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
322 
323   /* Set up the funcUnit lookup table.  */
324   isa->funcUnit_lookup_table =
325     bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
326   CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
327 			error_msg_p);
328   for (n = 0; n < isa->num_funcUnits; n++)
329     {
330       isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
331       isa->funcUnit_lookup_table[n].u.fun = n;
332     }
333   qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
334 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
335 
336   isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
337 		       sizeof (xtensa_insnbuf_word));
338 
339   return (xtensa_isa) isa;
340 }
341 
342 
343 void
344 xtensa_isa_free (xtensa_isa isa)
345 {
346   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
347   int n;
348 
349   /* With this version of the code, the xtensa_isa structure is not
350      dynamically allocated, so this function is not essential.  Free
351      the memory allocated by xtensa_isa_init and restore the xtensa_isa
352      structure to its initial state.  */
353 
354   free (intisa->opname_lookup_table);
355   intisa->opname_lookup_table = 0;
356 
357   free (intisa->state_lookup_table);
358   intisa->state_lookup_table = 0;
359 
360   free (intisa->sysreg_lookup_table);
361   intisa->sysreg_lookup_table = 0;
362 
363   for (n = 0; n < 2; n++)
364     {
365       free (intisa->sysreg_table[n]);
366       intisa->sysreg_table[n] = 0;
367     }
368 
369   free (intisa->interface_lookup_table);
370   intisa->interface_lookup_table = 0;
371 
372   free (intisa->funcUnit_lookup_table);
373   intisa->funcUnit_lookup_table = 0;
374 }
375 
376 
377 int
378 xtensa_isa_name_compare (const void *v1, const void *v2)
379 {
380   xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
381   xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
382 
383   return strcasecmp (e1->key, e2->key);
384 }
385 
386 
387 int
388 xtensa_isa_maxlength (xtensa_isa isa)
389 {
390   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
391   return intisa->insn_size;
392 }
393 
394 
395 int
396 xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
397 {
398   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
399   return (intisa->length_decode_fn) (cp);
400 }
401 
402 
403 int
404 xtensa_isa_num_pipe_stages (xtensa_isa isa)
405 {
406   xtensa_opcode opcode;
407   xtensa_funcUnit_use *use;
408   int num_opcodes, num_uses;
409   int i, stage;
410   static int max_stage = XTENSA_UNDEFINED;
411 
412   /* Only compute the value once.  */
413   if (max_stage != XTENSA_UNDEFINED)
414     return max_stage + 1;
415 
416   num_opcodes = xtensa_isa_num_opcodes (isa);
417   for (opcode = 0; opcode < num_opcodes; opcode++)
418     {
419       num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
420       for (i = 0; i < num_uses; i++)
421 	{
422 	  use = xtensa_opcode_funcUnit_use (isa, opcode, i);
423 	  stage = use->stage;
424 	  if (stage > max_stage)
425 	    max_stage = stage;
426 	}
427     }
428 
429   return max_stage + 1;
430 }
431 
432 
433 int
434 xtensa_isa_num_formats (xtensa_isa isa)
435 {
436   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
437   return intisa->num_formats;
438 }
439 
440 
441 int
442 xtensa_isa_num_opcodes (xtensa_isa isa)
443 {
444   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
445   return intisa->num_opcodes;
446 }
447 
448 
449 int
450 xtensa_isa_num_regfiles (xtensa_isa isa)
451 {
452   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
453   return intisa->num_regfiles;
454 }
455 
456 
457 int
458 xtensa_isa_num_states (xtensa_isa isa)
459 {
460   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
461   return intisa->num_states;
462 }
463 
464 
465 int
466 xtensa_isa_num_sysregs (xtensa_isa isa)
467 {
468   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
469   return intisa->num_sysregs;
470 }
471 
472 
473 int
474 xtensa_isa_num_interfaces (xtensa_isa isa)
475 {
476   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
477   return intisa->num_interfaces;
478 }
479 
480 
481 int
482 xtensa_isa_num_funcUnits (xtensa_isa isa)
483 {
484   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
485   return intisa->num_funcUnits;
486 }
487 
488 
489 
490 /* Instruction formats.  */
491 
492 
493 #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
494   do { \
495     if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
496       { \
497 	xtisa_errno = xtensa_isa_bad_format; \
498 	strcpy (xtisa_error_msg, "invalid format specifier"); \
499 	return (ERRVAL); \
500       } \
501   } while (0)
502 
503 
504 #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
505   do { \
506     if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
507       { \
508 	xtisa_errno = xtensa_isa_bad_slot; \
509 	strcpy (xtisa_error_msg, "invalid slot specifier"); \
510 	return (ERRVAL); \
511       } \
512   } while (0)
513 
514 
515 const char *
516 xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
517 {
518   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
519   CHECK_FORMAT (intisa, fmt, NULL);
520   return intisa->formats[fmt].name;
521 }
522 
523 
524 xtensa_format
525 xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
526 {
527   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
528   int fmt;
529 
530   if (!fmtname || !*fmtname)
531     {
532       xtisa_errno = xtensa_isa_bad_format;
533       strcpy (xtisa_error_msg, "invalid format name");
534       return XTENSA_UNDEFINED;
535     }
536 
537   for (fmt = 0; fmt < intisa->num_formats; fmt++)
538     {
539       if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
540 	return fmt;
541     }
542 
543   xtisa_errno = xtensa_isa_bad_format;
544   sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
545   return XTENSA_UNDEFINED;
546 }
547 
548 
549 xtensa_format
550 xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
551 {
552   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
553   xtensa_format fmt;
554 
555   fmt = (intisa->format_decode_fn) (insn);
556   if (fmt != XTENSA_UNDEFINED)
557     return fmt;
558 
559   xtisa_errno = xtensa_isa_bad_format;
560   strcpy (xtisa_error_msg, "cannot decode instruction format");
561   return XTENSA_UNDEFINED;
562 }
563 
564 
565 int
566 xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
567 {
568   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
569   CHECK_FORMAT (intisa, fmt, -1);
570   (*intisa->formats[fmt].encode_fn) (insn);
571   return 0;
572 }
573 
574 
575 int
576 xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
577 {
578   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
579   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
580   return intisa->formats[fmt].length;
581 }
582 
583 
584 int
585 xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
586 {
587   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
588   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589   return intisa->formats[fmt].num_slots;
590 }
591 
592 
593 xtensa_opcode
594 xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
595 {
596   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
597   int slot_id;
598 
599   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
600   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
601 
602   slot_id = intisa->formats[fmt].slot_id[slot];
603   return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
604 }
605 
606 
607 int
608 xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
609 			const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
610 {
611   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
612   int slot_id;
613 
614   CHECK_FORMAT (intisa, fmt, -1);
615   CHECK_SLOT (intisa, fmt, slot, -1);
616 
617   slot_id = intisa->formats[fmt].slot_id[slot];
618   (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
619   return 0;
620 }
621 
622 
623 int
624 xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
625 			xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
626 {
627   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
628   int slot_id;
629 
630   CHECK_FORMAT (intisa, fmt, -1);
631   CHECK_SLOT (intisa, fmt, slot, -1);
632 
633   slot_id = intisa->formats[fmt].slot_id[slot];
634   (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
635   return 0;
636 }
637 
638 
639 
640 /* Opcode information.  */
641 
642 
643 #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
644   do { \
645     if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
646       { \
647 	xtisa_errno = xtensa_isa_bad_opcode; \
648 	strcpy (xtisa_error_msg, "invalid opcode specifier"); \
649 	return (ERRVAL); \
650       } \
651   } while (0)
652 
653 
654 xtensa_opcode
655 xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
656 {
657   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
658   xtensa_lookup_entry entry, *result = 0;
659 
660   if (!opname || !*opname)
661     {
662       xtisa_errno = xtensa_isa_bad_opcode;
663       strcpy (xtisa_error_msg, "invalid opcode name");
664       return XTENSA_UNDEFINED;
665     }
666 
667   if (intisa->num_opcodes != 0)
668     {
669       entry.key = opname;
670       result = bsearch (&entry, intisa->opname_lookup_table,
671 			intisa->num_opcodes, sizeof (xtensa_lookup_entry),
672 			xtensa_isa_name_compare);
673     }
674 
675   if (!result)
676     {
677       xtisa_errno = xtensa_isa_bad_opcode;
678       sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
679       return XTENSA_UNDEFINED;
680     }
681 
682   return result->u.opcode;
683 }
684 
685 
686 xtensa_opcode
687 xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
688 		      const xtensa_insnbuf slotbuf)
689 {
690   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
691   int slot_id;
692   xtensa_opcode opc;
693 
694   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
695   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
696 
697   slot_id = intisa->formats[fmt].slot_id[slot];
698 
699   opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
700   if (opc != XTENSA_UNDEFINED)
701     return opc;
702 
703   xtisa_errno = xtensa_isa_bad_opcode;
704   strcpy (xtisa_error_msg, "cannot decode opcode");
705   return XTENSA_UNDEFINED;
706 }
707 
708 
709 int
710 xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
711 		      xtensa_insnbuf slotbuf, xtensa_opcode opc)
712 {
713   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
714   int slot_id;
715   xtensa_opcode_encode_fn encode_fn;
716 
717   CHECK_FORMAT (intisa, fmt, -1);
718   CHECK_SLOT (intisa, fmt, slot, -1);
719   CHECK_OPCODE (intisa, opc, -1);
720 
721   slot_id = intisa->formats[fmt].slot_id[slot];
722   encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
723   if (!encode_fn)
724     {
725       xtisa_errno = xtensa_isa_wrong_slot;
726       sprintf (xtisa_error_msg,
727 	       "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
728 	       intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
729       return -1;
730     }
731   (*encode_fn) (slotbuf);
732   return 0;
733 }
734 
735 
736 const char *
737 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
738 {
739   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
740   CHECK_OPCODE (intisa, opc, NULL);
741   return intisa->opcodes[opc].name;
742 }
743 
744 
745 int
746 xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
747 {
748   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
751     return 1;
752   return 0;
753 }
754 
755 
756 int
757 xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
758 {
759   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
762     return 1;
763   return 0;
764 }
765 
766 
767 int
768 xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
769 {
770   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
771   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
772   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
773     return 1;
774   return 0;
775 }
776 
777 
778 int
779 xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
780 {
781   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
783   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
784     return 1;
785   return 0;
786 }
787 
788 
789 int
790 xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
791 {
792   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
793   int iclass_id;
794 
795   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
796   iclass_id = intisa->opcodes[opc].iclass_id;
797   return intisa->iclasses[iclass_id].num_operands;
798 }
799 
800 
801 int
802 xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
803 {
804   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
805   int iclass_id;
806 
807   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
808   iclass_id = intisa->opcodes[opc].iclass_id;
809   return intisa->iclasses[iclass_id].num_stateOperands;
810 }
811 
812 
813 int
814 xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
815 {
816   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
817   int iclass_id;
818 
819   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
820   iclass_id = intisa->opcodes[opc].iclass_id;
821   return intisa->iclasses[iclass_id].num_interfaceOperands;
822 }
823 
824 
825 int
826 xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
827 {
828   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
829   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
830   return intisa->opcodes[opc].num_funcUnit_uses;
831 }
832 
833 
834 xtensa_funcUnit_use *
835 xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
836 {
837   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
838   CHECK_OPCODE (intisa, opc, NULL);
839   if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
840     {
841       xtisa_errno = xtensa_isa_bad_funcUnit;
842       sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
843 	       "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
844 	       intisa->opcodes[opc].num_funcUnit_uses);
845       return NULL;
846     }
847   return &intisa->opcodes[opc].funcUnit_uses[u];
848 }
849 
850 
851 
852 /* Operand information.  */
853 
854 
855 #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
856   do { \
857     if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
858       { \
859 	xtisa_errno = xtensa_isa_bad_operand; \
860 	sprintf (xtisa_error_msg, "invalid operand number (%d); " \
861 		 "opcode \"%s\" has %d operands", (OPND), \
862 		 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
863 	return (ERRVAL); \
864       } \
865   } while (0)
866 
867 
868 static xtensa_operand_internal *
869 get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
870 {
871   xtensa_iclass_internal *iclass;
872   int iclass_id, operand_id;
873 
874   CHECK_OPCODE (intisa, opc, NULL);
875   iclass_id = intisa->opcodes[opc].iclass_id;
876   iclass = &intisa->iclasses[iclass_id];
877   CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
878   operand_id = iclass->operands[opnd].u.operand_id;
879   return &intisa->operands[operand_id];
880 }
881 
882 
883 const char *
884 xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
885 {
886   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
887   xtensa_operand_internal *intop;
888 
889   intop = get_operand (intisa, opc, opnd);
890   if (!intop) return NULL;
891   return intop->name;
892 }
893 
894 
895 int
896 xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
897 {
898   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
899   xtensa_iclass_internal *iclass;
900   int iclass_id, operand_id;
901   xtensa_operand_internal *intop;
902 
903   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
904   iclass_id = intisa->opcodes[opc].iclass_id;
905   iclass = &intisa->iclasses[iclass_id];
906   CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
907 
908   /* Special case for "sout" operands.  */
909   if (iclass->operands[opnd].inout == 's')
910     return 0;
911 
912   operand_id = iclass->operands[opnd].u.operand_id;
913   intop = &intisa->operands[operand_id];
914 
915   if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
916     return 1;
917   return 0;
918 }
919 
920 
921 char
922 xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
923 {
924   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
925   xtensa_iclass_internal *iclass;
926   int iclass_id;
927   char inout;
928 
929   CHECK_OPCODE (intisa, opc, 0);
930   iclass_id = intisa->opcodes[opc].iclass_id;
931   iclass = &intisa->iclasses[iclass_id];
932   CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
933   inout = iclass->operands[opnd].inout;
934 
935   /* Special case for "sout" operands.  */
936   if (inout == 's')
937     return 'o';
938 
939   return inout;
940 }
941 
942 
943 int
944 xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
945 			  xtensa_format fmt, int slot,
946 			  const xtensa_insnbuf slotbuf, uint32 *valp)
947 {
948   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
949   xtensa_operand_internal *intop;
950   int slot_id;
951   xtensa_get_field_fn get_fn;
952 
953   intop = get_operand (intisa, opc, opnd);
954   if (!intop) return -1;
955 
956   CHECK_FORMAT (intisa, fmt, -1);
957   CHECK_SLOT (intisa, fmt, slot, -1);
958 
959   slot_id = intisa->formats[fmt].slot_id[slot];
960   if (intop->field_id == XTENSA_UNDEFINED)
961     {
962       xtisa_errno = xtensa_isa_no_field;
963       strcpy (xtisa_error_msg, "implicit operand has no field");
964       return -1;
965     }
966   get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
967   if (!get_fn)
968     {
969       xtisa_errno = xtensa_isa_wrong_slot;
970       sprintf (xtisa_error_msg,
971 	       "operand \"%s\" does not exist in slot %d of format \"%s\"",
972 	       intop->name, slot, intisa->formats[fmt].name);
973       return -1;
974     }
975   *valp = (*get_fn) (slotbuf);
976   return 0;
977 }
978 
979 
980 int
981 xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
982 			  xtensa_format fmt, int slot,
983 			  xtensa_insnbuf slotbuf, uint32 val)
984 {
985   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
986   xtensa_operand_internal *intop;
987   int slot_id;
988   xtensa_set_field_fn set_fn;
989 
990   intop = get_operand (intisa, opc, opnd);
991   if (!intop) return -1;
992 
993   CHECK_FORMAT (intisa, fmt, -1);
994   CHECK_SLOT (intisa, fmt, slot, -1);
995 
996   slot_id = intisa->formats[fmt].slot_id[slot];
997   if (intop->field_id == XTENSA_UNDEFINED)
998     {
999       xtisa_errno = xtensa_isa_no_field;
1000       strcpy (xtisa_error_msg, "implicit operand has no field");
1001       return -1;
1002     }
1003   set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1004   if (!set_fn)
1005     {
1006       xtisa_errno = xtensa_isa_wrong_slot;
1007       sprintf (xtisa_error_msg,
1008 	       "operand \"%s\" does not exist in slot %d of format \"%s\"",
1009 	       intop->name, slot, intisa->formats[fmt].name);
1010       return -1;
1011     }
1012   (*set_fn) (slotbuf, val);
1013   return 0;
1014 }
1015 
1016 
1017 int
1018 xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1019 		       uint32 *valp)
1020 {
1021   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1022   xtensa_operand_internal *intop;
1023   uint32 test_val, orig_val;
1024 
1025   intop = get_operand (intisa, opc, opnd);
1026   if (!intop)
1027     return -1;
1028 
1029   if (!intop->encode)
1030     {
1031       /* This is a default operand for a field.  How can we tell if the
1032 	 value fits in the field?  Write the value into the field,
1033 	 read it back, and then make sure we get the same value.  */
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 
1091 int
1092 xtensa_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 
1115 int
1116 xtensa_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 
1130 xtensa_regfile
1131 xtensa_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 
1143 int
1144 xtensa_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 
1156 int
1157 xtensa_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 
1171 int
1172 xtensa_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 
1186 int
1187 xtensa_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 
1218 int
1219 xtensa_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 
1267 xtensa_state
1268 xtensa_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 
1282 char
1283 xtensa_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 
1315 xtensa_interface
1316 xtensa_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 
1346 xtensa_regfile
1347 xtensa_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 (!filename_cmp (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 
1372 xtensa_regfile
1373 xtensa_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 (!filename_cmp (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 
1403 const char *
1404 xtensa_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 
1412 const char *
1413 xtensa_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 
1421 xtensa_regfile
1422 xtensa_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 
1430 int
1431 xtensa_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 
1439 int
1440 xtensa_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 
1463 xtensa_state
1464 xtensa_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 
1494 const char *
1495 xtensa_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 
1503 int
1504 xtensa_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 
1512 int
1513 xtensa_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 int
1524 xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
1525 {
1526   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1527   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1528   if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
1529     return 1;
1530   return 0;
1531 }
1532 
1533 
1534 
1535 /* Sysregs.  */
1536 
1537 
1538 #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1539   do { \
1540     if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1541       { \
1542 	xtisa_errno = xtensa_isa_bad_sysreg; \
1543 	strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1544 	return (ERRVAL); \
1545       } \
1546   } while (0)
1547 
1548 
1549 xtensa_sysreg
1550 xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
1551 {
1552   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1553 
1554   if (is_user != 0)
1555     is_user = 1;
1556 
1557   if (num < 0 || num > intisa->max_sysreg_num[is_user]
1558       || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1559     {
1560       xtisa_errno = xtensa_isa_bad_sysreg;
1561       strcpy (xtisa_error_msg, "sysreg not recognized");
1562       return XTENSA_UNDEFINED;
1563     }
1564 
1565   return intisa->sysreg_table[is_user][num];
1566 }
1567 
1568 
1569 xtensa_sysreg
1570 xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
1571 {
1572   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1573   xtensa_lookup_entry entry, *result = 0;
1574 
1575   if (!name || !*name)
1576     {
1577       xtisa_errno = xtensa_isa_bad_sysreg;
1578       strcpy (xtisa_error_msg, "invalid sysreg name");
1579       return XTENSA_UNDEFINED;
1580     }
1581 
1582   if (intisa->num_sysregs != 0)
1583     {
1584       entry.key = name;
1585       result = bsearch (&entry, intisa->sysreg_lookup_table,
1586 			intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1587 			xtensa_isa_name_compare);
1588     }
1589 
1590   if (!result)
1591     {
1592       xtisa_errno = xtensa_isa_bad_sysreg;
1593       sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1594       return XTENSA_UNDEFINED;
1595     }
1596 
1597   return result->u.sysreg;
1598 }
1599 
1600 
1601 const char *
1602 xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
1603 {
1604   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1605   CHECK_SYSREG (intisa, sysreg, NULL);
1606   return intisa->sysregs[sysreg].name;
1607 }
1608 
1609 
1610 int
1611 xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
1612 {
1613   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1614   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1615   return intisa->sysregs[sysreg].number;
1616 }
1617 
1618 
1619 int
1620 xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
1621 {
1622   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1623   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1624   if (intisa->sysregs[sysreg].is_user)
1625     return 1;
1626   return 0;
1627 }
1628 
1629 
1630 
1631 /* Interfaces.  */
1632 
1633 
1634 #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1635   do { \
1636     if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1637       { \
1638 	xtisa_errno = xtensa_isa_bad_interface; \
1639 	strcpy (xtisa_error_msg, "invalid interface specifier"); \
1640 	return (ERRVAL); \
1641       } \
1642   } while (0)
1643 
1644 
1645 xtensa_interface
1646 xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
1647 {
1648   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1649   xtensa_lookup_entry entry, *result = 0;
1650 
1651   if (!ifname || !*ifname)
1652     {
1653       xtisa_errno = xtensa_isa_bad_interface;
1654       strcpy (xtisa_error_msg, "invalid interface name");
1655       return XTENSA_UNDEFINED;
1656     }
1657 
1658   if (intisa->num_interfaces != 0)
1659     {
1660       entry.key = ifname;
1661       result = bsearch (&entry, intisa->interface_lookup_table,
1662 			intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1663 			xtensa_isa_name_compare);
1664     }
1665 
1666   if (!result)
1667     {
1668       xtisa_errno = xtensa_isa_bad_interface;
1669       sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1670       return XTENSA_UNDEFINED;
1671     }
1672 
1673   return result->u.intf;
1674 }
1675 
1676 
1677 const char *
1678 xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1679 {
1680   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1681   CHECK_INTERFACE (intisa, intf, NULL);
1682   return intisa->interfaces[intf].name;
1683 }
1684 
1685 
1686 int
1687 xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1688 {
1689   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1690   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1691   return intisa->interfaces[intf].num_bits;
1692 }
1693 
1694 
1695 char
1696 xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
1697 {
1698   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1699   CHECK_INTERFACE (intisa, intf, 0);
1700   return intisa->interfaces[intf].inout;
1701 }
1702 
1703 
1704 int
1705 xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1706 {
1707   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1708   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1709   if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1710     return 1;
1711   return 0;
1712 }
1713 
1714 
1715 int
1716 xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1717 {
1718   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1719   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1720   return intisa->interfaces[intf].class_id;
1721 }
1722 
1723 
1724 
1725 /* Functional Units.  */
1726 
1727 
1728 #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1729   do { \
1730     if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1731       { \
1732 	xtisa_errno = xtensa_isa_bad_funcUnit; \
1733 	strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1734 	return (ERRVAL); \
1735       } \
1736   } while (0)
1737 
1738 
1739 xtensa_funcUnit
1740 xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1741 {
1742   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1743   xtensa_lookup_entry entry, *result = 0;
1744 
1745   if (!fname || !*fname)
1746     {
1747       xtisa_errno = xtensa_isa_bad_funcUnit;
1748       strcpy (xtisa_error_msg, "invalid functional unit name");
1749       return XTENSA_UNDEFINED;
1750     }
1751 
1752   if (intisa->num_funcUnits != 0)
1753     {
1754       entry.key = fname;
1755       result = bsearch (&entry, intisa->funcUnit_lookup_table,
1756 			intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1757 			xtensa_isa_name_compare);
1758     }
1759 
1760   if (!result)
1761     {
1762       xtisa_errno = xtensa_isa_bad_funcUnit;
1763       sprintf (xtisa_error_msg,
1764 	       "functional unit \"%s\" not recognized", fname);
1765       return XTENSA_UNDEFINED;
1766     }
1767 
1768   return result->u.fun;
1769 }
1770 
1771 
1772 const char *
1773 xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1774 {
1775   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1776   CHECK_FUNCUNIT (intisa, fun, NULL);
1777   return intisa->funcUnits[fun].name;
1778 }
1779 
1780 
1781 int
1782 xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1783 {
1784   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1785   CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1786   return intisa->funcUnits[fun].num_copies;
1787 }
1788 
1789