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