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