bfd/
[external/binutils.git] / bfd / xtensa-isa.c
1 /* Configurable Xtensa ISA support.
2    Copyright 2003, 2004, 2005, 2007, 2008 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       isa->sysreg_table[is_user][sreg->number] = n;
296     }
297
298   /* Set up the interface lookup table.  */
299   isa->interface_lookup_table = 
300     bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
301   CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
302                         error_msg_p);
303   for (n = 0; n < isa->num_interfaces; n++)
304     {
305       isa->interface_lookup_table[n].key = isa->interfaces[n].name;
306       isa->interface_lookup_table[n].u.intf = n;
307     }
308   qsort (isa->interface_lookup_table, isa->num_interfaces,
309          sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
310
311   /* Set up the funcUnit lookup table.  */
312   isa->funcUnit_lookup_table = 
313     bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
314   CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
315                         error_msg_p);
316   for (n = 0; n < isa->num_funcUnits; n++)
317     {
318       isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
319       isa->funcUnit_lookup_table[n].u.fun = n;
320     }
321   qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
322          sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
323
324   isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
325                        sizeof (xtensa_insnbuf_word));
326
327   return (xtensa_isa) isa;
328 }
329
330
331 void
332 xtensa_isa_free (xtensa_isa isa)
333 {
334   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
335   int n;
336
337   /* With this version of the code, the xtensa_isa structure is not
338      dynamically allocated, so this function is not essential.  Free
339      the memory allocated by xtensa_isa_init and restore the xtensa_isa
340      structure to its initial state.  */
341
342   if (intisa->opname_lookup_table)
343     {
344       free (intisa->opname_lookup_table);
345       intisa->opname_lookup_table = 0;
346     }
347
348   if (intisa->state_lookup_table)
349     {
350       free (intisa->state_lookup_table);
351       intisa->state_lookup_table = 0;
352     }
353
354   if (intisa->sysreg_lookup_table)
355     {
356       free (intisa->sysreg_lookup_table);
357       intisa->sysreg_lookup_table = 0;
358     }
359   for (n = 0; n < 2; n++)
360     {
361       if (intisa->sysreg_table[n])
362         {
363           free (intisa->sysreg_table[n]);
364           intisa->sysreg_table[n] = 0;
365         }
366     }
367
368   if (intisa->interface_lookup_table)
369     {
370       free (intisa->interface_lookup_table);
371       intisa->interface_lookup_table = 0;
372     }
373
374   if (intisa->funcUnit_lookup_table)
375     {
376       free (intisa->funcUnit_lookup_table);
377       intisa->funcUnit_lookup_table = 0;
378     }
379 }
380
381
382 int
383 xtensa_isa_name_compare (const void *v1, const void *v2)
384 {
385   xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
386   xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
387
388   return strcasecmp (e1->key, e2->key);
389 }
390
391
392 int
393 xtensa_isa_maxlength (xtensa_isa isa)
394 {
395   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
396   return intisa->insn_size;
397 }
398
399
400 int
401 xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
402 {
403   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
404   return (intisa->length_decode_fn) (cp);
405 }
406
407
408 int
409 xtensa_isa_num_pipe_stages (xtensa_isa isa) 
410 {
411   xtensa_opcode opcode;
412   xtensa_funcUnit_use *use;
413   int num_opcodes, num_uses;
414   int i, stage;
415   static int max_stage = XTENSA_UNDEFINED;
416
417   /* Only compute the value once.  */
418   if (max_stage != XTENSA_UNDEFINED)
419     return max_stage + 1;
420
421   num_opcodes = xtensa_isa_num_opcodes (isa);
422   for (opcode = 0; opcode < num_opcodes; opcode++)
423     {
424       num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
425       for (i = 0; i < num_uses; i++)
426         {
427           use = xtensa_opcode_funcUnit_use (isa, opcode, i);
428           stage = use->stage;
429           if (stage > max_stage)
430             max_stage = stage;
431         }
432     }
433
434   return max_stage + 1;
435 }
436
437
438 int
439 xtensa_isa_num_formats (xtensa_isa isa)
440 {
441   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
442   return intisa->num_formats;
443 }
444
445
446 int
447 xtensa_isa_num_opcodes (xtensa_isa isa)
448 {
449   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
450   return intisa->num_opcodes;
451 }
452
453
454 int
455 xtensa_isa_num_regfiles (xtensa_isa isa)
456 {
457   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
458   return intisa->num_regfiles;
459 }
460
461
462 int
463 xtensa_isa_num_states (xtensa_isa isa)
464 {
465   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
466   return intisa->num_states;
467 }
468
469
470 int
471 xtensa_isa_num_sysregs (xtensa_isa isa)
472 {
473   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
474   return intisa->num_sysregs;
475 }
476
477
478 int
479 xtensa_isa_num_interfaces (xtensa_isa isa)
480 {
481   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
482   return intisa->num_interfaces;
483 }
484
485
486 int
487 xtensa_isa_num_funcUnits (xtensa_isa isa)
488 {
489   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
490   return intisa->num_funcUnits;
491 }
492
493
494 \f
495 /* Instruction formats.  */
496
497
498 #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
499   do { \
500     if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
501       { \
502         xtisa_errno = xtensa_isa_bad_format; \
503         strcpy (xtisa_error_msg, "invalid format specifier"); \
504         return (ERRVAL); \
505       } \
506   } while (0)
507
508
509 #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
510   do { \
511     if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
512       { \
513         xtisa_errno = xtensa_isa_bad_slot; \
514         strcpy (xtisa_error_msg, "invalid slot specifier"); \
515         return (ERRVAL); \
516       } \
517   } while (0)
518
519
520 const char *
521 xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
522 {
523   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
524   CHECK_FORMAT (intisa, fmt, NULL);
525   return intisa->formats[fmt].name;
526 }
527
528
529 xtensa_format
530 xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
531 {
532   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
533   int fmt;
534
535   if (!fmtname || !*fmtname)
536     {
537       xtisa_errno = xtensa_isa_bad_format;
538       strcpy (xtisa_error_msg, "invalid format name");
539       return XTENSA_UNDEFINED;
540     }
541
542   for (fmt = 0; fmt < intisa->num_formats; fmt++)
543     {
544       if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
545         return fmt;
546     }
547   
548   xtisa_errno = xtensa_isa_bad_format;
549   sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
550   return XTENSA_UNDEFINED;
551 }
552
553
554 xtensa_format
555 xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
556 {
557   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
558   xtensa_format fmt;
559
560   fmt = (intisa->format_decode_fn) (insn);
561   if (fmt != XTENSA_UNDEFINED)
562     return fmt;
563
564   xtisa_errno = xtensa_isa_bad_format;
565   strcpy (xtisa_error_msg, "cannot decode instruction format");
566   return XTENSA_UNDEFINED;
567 }
568
569
570 int
571 xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
572 {
573   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
574   CHECK_FORMAT (intisa, fmt, -1);
575   (*intisa->formats[fmt].encode_fn) (insn);
576   return 0;
577 }
578
579
580 int
581 xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
582 {
583   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
584   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
585   return intisa->formats[fmt].length;
586 }
587
588
589 int
590 xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
591 {
592   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
593   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
594   return intisa->formats[fmt].num_slots;
595 }
596
597
598 xtensa_opcode
599 xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
600 {
601   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
602   int slot_id;
603
604   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
605   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
606
607   slot_id = intisa->formats[fmt].slot_id[slot];
608   return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
609 }
610
611
612 int
613 xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
614                         const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
615 {
616   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
617   int slot_id;
618
619   CHECK_FORMAT (intisa, fmt, -1);
620   CHECK_SLOT (intisa, fmt, slot, -1);
621
622   slot_id = intisa->formats[fmt].slot_id[slot];
623   (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
624   return 0;
625 }
626
627
628 int
629 xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
630                         xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
631 {
632   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
633   int slot_id;
634
635   CHECK_FORMAT (intisa, fmt, -1);
636   CHECK_SLOT (intisa, fmt, slot, -1);
637
638   slot_id = intisa->formats[fmt].slot_id[slot];
639   (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
640   return 0;
641 }
642
643
644 \f
645 /* Opcode information.  */
646
647
648 #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
649   do { \
650     if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
651       { \
652         xtisa_errno = xtensa_isa_bad_opcode; \
653         strcpy (xtisa_error_msg, "invalid opcode specifier"); \
654         return (ERRVAL); \
655       } \
656   } while (0)
657
658
659 xtensa_opcode
660 xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
661 {
662   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
663   xtensa_lookup_entry entry, *result = 0;
664
665   if (!opname || !*opname)
666     {
667       xtisa_errno = xtensa_isa_bad_opcode;
668       strcpy (xtisa_error_msg, "invalid opcode name");
669       return XTENSA_UNDEFINED;
670     }
671
672   if (intisa->num_opcodes != 0)
673     {
674       entry.key = opname;
675       result = bsearch (&entry, intisa->opname_lookup_table,
676                         intisa->num_opcodes, sizeof (xtensa_lookup_entry),
677                         xtensa_isa_name_compare);
678     }
679
680   if (!result)
681     {
682       xtisa_errno = xtensa_isa_bad_opcode;
683       sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
684       return XTENSA_UNDEFINED;
685     }
686
687   return result->u.opcode;
688 }
689
690
691 xtensa_opcode
692 xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
693                       const xtensa_insnbuf slotbuf)
694 {
695   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
696   int slot_id;
697   xtensa_opcode opc;
698
699   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
700   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
701
702   slot_id = intisa->formats[fmt].slot_id[slot];
703
704   opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
705   if (opc != XTENSA_UNDEFINED)
706     return opc;
707
708   xtisa_errno = xtensa_isa_bad_opcode;
709   strcpy (xtisa_error_msg, "cannot decode opcode");
710   return XTENSA_UNDEFINED;
711 }
712
713
714 int
715 xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
716                       xtensa_insnbuf slotbuf, xtensa_opcode opc)
717 {
718   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
719   int slot_id;
720   xtensa_opcode_encode_fn encode_fn;
721
722   CHECK_FORMAT (intisa, fmt, -1);
723   CHECK_SLOT (intisa, fmt, slot, -1);
724   CHECK_OPCODE (intisa, opc, -1);
725
726   slot_id = intisa->formats[fmt].slot_id[slot];
727   encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
728   if (!encode_fn)
729     {
730       xtisa_errno = xtensa_isa_wrong_slot;
731       sprintf (xtisa_error_msg,
732                "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
733                intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
734       return -1;
735     }
736   (*encode_fn) (slotbuf);
737   return 0;
738 }
739
740
741 const char *
742 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
743 {
744   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
745   CHECK_OPCODE (intisa, opc, NULL);
746   return intisa->opcodes[opc].name;
747 }
748
749
750 int
751 xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
752 {
753   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
754   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
755   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
756     return 1;
757   return 0;
758 }
759
760
761 int
762 xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
763 {
764   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
765   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
766   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
767     return 1;
768   return 0;
769 }
770
771
772 int
773 xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
774 {
775   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
776   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
777   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
778     return 1;
779   return 0;
780 }
781
782
783 int
784 xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
785 {
786   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
787   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
788   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
789     return 1;
790   return 0;
791 }
792
793
794 int
795 xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
796 {
797   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
798   int iclass_id;
799
800   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
801   iclass_id = intisa->opcodes[opc].iclass_id;
802   return intisa->iclasses[iclass_id].num_operands;
803 }
804
805
806 int
807 xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
808 {
809   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
810   int iclass_id;
811
812   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
813   iclass_id = intisa->opcodes[opc].iclass_id;
814   return intisa->iclasses[iclass_id].num_stateOperands;
815 }
816
817
818 int
819 xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
820 {
821   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
822   int iclass_id;
823
824   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
825   iclass_id = intisa->opcodes[opc].iclass_id;
826   return intisa->iclasses[iclass_id].num_interfaceOperands;
827 }
828
829
830 int
831 xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
832 {
833   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
834   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
835   return intisa->opcodes[opc].num_funcUnit_uses;
836 }
837
838
839 xtensa_funcUnit_use *
840 xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
841 {
842   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
843   CHECK_OPCODE (intisa, opc, NULL);
844   if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
845     {
846       xtisa_errno = xtensa_isa_bad_funcUnit;
847       sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
848                "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
849                intisa->opcodes[opc].num_funcUnit_uses);
850       return NULL;
851     }
852   return &intisa->opcodes[opc].funcUnit_uses[u];
853 }
854
855
856 \f
857 /* Operand information.  */
858
859
860 #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
861   do { \
862     if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
863       { \
864         xtisa_errno = xtensa_isa_bad_operand; \
865         sprintf (xtisa_error_msg, "invalid operand number (%d); " \
866                  "opcode \"%s\" has %d operands", (OPND), \
867                  (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
868         return (ERRVAL); \
869       } \
870   } while (0)
871
872
873 static xtensa_operand_internal *
874 get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
875 {
876   xtensa_iclass_internal *iclass;
877   int iclass_id, operand_id;
878
879   CHECK_OPCODE (intisa, opc, NULL);
880   iclass_id = intisa->opcodes[opc].iclass_id;
881   iclass = &intisa->iclasses[iclass_id];
882   CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
883   operand_id = iclass->operands[opnd].u.operand_id;
884   return &intisa->operands[operand_id];
885 }
886
887
888 const char *
889 xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
890 {
891   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
892   xtensa_operand_internal *intop;
893
894   intop = get_operand (intisa, opc, opnd);
895   if (!intop) return NULL;
896   return intop->name;
897 }
898
899
900 int
901 xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
902 {
903   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
904   xtensa_iclass_internal *iclass;
905   int iclass_id, operand_id;
906   xtensa_operand_internal *intop;
907
908   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
909   iclass_id = intisa->opcodes[opc].iclass_id;
910   iclass = &intisa->iclasses[iclass_id];
911   CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
912
913   /* Special case for "sout" operands.  */
914   if (iclass->operands[opnd].inout == 's')
915     return 0;
916
917   operand_id = iclass->operands[opnd].u.operand_id;
918   intop = &intisa->operands[operand_id];
919
920   if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
921     return 1;
922   return 0;
923 }
924
925
926 char
927 xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
928 {
929   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
930   xtensa_iclass_internal *iclass;
931   int iclass_id;
932   char inout;
933
934   CHECK_OPCODE (intisa, opc, 0);
935   iclass_id = intisa->opcodes[opc].iclass_id;
936   iclass = &intisa->iclasses[iclass_id];
937   CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
938   inout = iclass->operands[opnd].inout;
939
940   /* Special case for "sout" operands.  */
941   if (inout == 's')
942     return 'o';
943
944   return inout;
945 }
946
947
948 int
949 xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
950                           xtensa_format fmt, int slot,
951                           const xtensa_insnbuf slotbuf, uint32 *valp)
952 {
953   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
954   xtensa_operand_internal *intop;
955   int slot_id;
956   xtensa_get_field_fn get_fn;
957
958   intop = get_operand (intisa, opc, opnd);
959   if (!intop) return -1;
960
961   CHECK_FORMAT (intisa, fmt, -1);
962   CHECK_SLOT (intisa, fmt, slot, -1);
963
964   slot_id = intisa->formats[fmt].slot_id[slot];
965   if (intop->field_id == XTENSA_UNDEFINED)
966     {
967       xtisa_errno = xtensa_isa_no_field;
968       strcpy (xtisa_error_msg, "implicit operand has no field");
969       return -1;
970     }
971   get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
972   if (!get_fn)
973     {
974       xtisa_errno = xtensa_isa_wrong_slot;
975       sprintf (xtisa_error_msg,
976                "operand \"%s\" does not exist in slot %d of format \"%s\"",
977                intop->name, slot, intisa->formats[fmt].name);
978       return -1;
979     }
980   *valp = (*get_fn) (slotbuf);
981   return 0;
982 }
983
984
985 int
986 xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
987                           xtensa_format fmt, int slot,
988                           xtensa_insnbuf slotbuf, uint32 val)
989 {
990   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
991   xtensa_operand_internal *intop;
992   int slot_id;
993   xtensa_set_field_fn set_fn;
994
995   intop = get_operand (intisa, opc, opnd);
996   if (!intop) return -1;
997
998   CHECK_FORMAT (intisa, fmt, -1);
999   CHECK_SLOT (intisa, fmt, slot, -1);
1000
1001   slot_id = intisa->formats[fmt].slot_id[slot];
1002   if (intop->field_id == XTENSA_UNDEFINED)
1003     {
1004       xtisa_errno = xtensa_isa_no_field;
1005       strcpy (xtisa_error_msg, "implicit operand has no field");
1006       return -1;
1007     }
1008   set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1009   if (!set_fn)
1010     {
1011       xtisa_errno = xtensa_isa_wrong_slot;
1012       sprintf (xtisa_error_msg,
1013                "operand \"%s\" does not exist in slot %d of format \"%s\"",
1014                intop->name, slot, intisa->formats[fmt].name);
1015       return -1;
1016     }
1017   (*set_fn) (slotbuf, val);
1018   return 0;
1019 }
1020
1021
1022 int
1023 xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1024                        uint32 *valp)
1025 {
1026   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1027   xtensa_operand_internal *intop;
1028   uint32 test_val, orig_val;
1029
1030   intop = get_operand (intisa, opc, opnd);
1031   if (!intop) return -1;
1032
1033   if (!intop->encode)
1034     {
1035       /* This is a default operand for a field.  How can we tell if the
1036          value fits in the field?  Write the value into the field,
1037          read it back, and then make sure we get the same value.  */
1038
1039       xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
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 (!strcmp (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 (!strcmp (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 \f
1530 /* Sysregs.  */
1531
1532
1533 #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1534   do { \
1535     if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1536       { \
1537         xtisa_errno = xtensa_isa_bad_sysreg; \
1538         strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1539         return (ERRVAL); \
1540       } \
1541   } while (0)
1542
1543
1544 xtensa_sysreg
1545 xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
1546 {
1547   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1548
1549   if (is_user != 0)
1550     is_user = 1;
1551
1552   if (num < 0 || num > intisa->max_sysreg_num[is_user]
1553       || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1554     {
1555       xtisa_errno = xtensa_isa_bad_sysreg;
1556       strcpy (xtisa_error_msg, "sysreg not recognized");
1557       return XTENSA_UNDEFINED;
1558     }
1559
1560   return intisa->sysreg_table[is_user][num];
1561 }
1562
1563
1564 xtensa_sysreg
1565 xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
1566 {
1567   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1568   xtensa_lookup_entry entry, *result = 0;
1569
1570   if (!name || !*name)
1571     {
1572       xtisa_errno = xtensa_isa_bad_sysreg;
1573       strcpy (xtisa_error_msg, "invalid sysreg name");
1574       return XTENSA_UNDEFINED;
1575     }
1576
1577   if (intisa->num_sysregs != 0)
1578     {
1579       entry.key = name;
1580       result = bsearch (&entry, intisa->sysreg_lookup_table,
1581                         intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1582                         xtensa_isa_name_compare);
1583     }
1584
1585   if (!result)
1586     {
1587       xtisa_errno = xtensa_isa_bad_sysreg;
1588       sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1589       return XTENSA_UNDEFINED;
1590     }
1591
1592   return result->u.sysreg;
1593 }
1594
1595
1596 const char *
1597 xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
1598 {
1599   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1600   CHECK_SYSREG (intisa, sysreg, NULL);
1601   return intisa->sysregs[sysreg].name;
1602 }
1603
1604
1605 int
1606 xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
1607 {
1608   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1609   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1610   return intisa->sysregs[sysreg].number;
1611 }
1612
1613
1614 int
1615 xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
1616 {
1617   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1618   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1619   if (intisa->sysregs[sysreg].is_user)
1620     return 1;
1621   return 0;
1622 }
1623
1624
1625 \f
1626 /* Interfaces.  */
1627
1628
1629 #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1630   do { \
1631     if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1632       { \
1633         xtisa_errno = xtensa_isa_bad_interface; \
1634         strcpy (xtisa_error_msg, "invalid interface specifier"); \
1635         return (ERRVAL); \
1636       } \
1637   } while (0)
1638
1639
1640 xtensa_interface
1641 xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
1642 {
1643   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1644   xtensa_lookup_entry entry, *result = 0;
1645
1646   if (!ifname || !*ifname)
1647     {
1648       xtisa_errno = xtensa_isa_bad_interface;
1649       strcpy (xtisa_error_msg, "invalid interface name");
1650       return XTENSA_UNDEFINED;
1651     }
1652
1653   if (intisa->num_interfaces != 0)
1654     {
1655       entry.key = ifname;
1656       result = bsearch (&entry, intisa->interface_lookup_table,
1657                         intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1658                         xtensa_isa_name_compare);
1659     }
1660
1661   if (!result)
1662     {
1663       xtisa_errno = xtensa_isa_bad_interface;
1664       sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1665       return XTENSA_UNDEFINED;
1666     }
1667
1668   return result->u.intf;
1669 }
1670
1671
1672 const char *
1673 xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1674 {
1675   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1676   CHECK_INTERFACE (intisa, intf, NULL);
1677   return intisa->interfaces[intf].name;
1678 }
1679
1680
1681 int
1682 xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1683 {
1684   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1685   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1686   return intisa->interfaces[intf].num_bits;
1687 }
1688
1689
1690 char
1691 xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
1692 {
1693   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1694   CHECK_INTERFACE (intisa, intf, 0);
1695   return intisa->interfaces[intf].inout;
1696 }
1697
1698
1699 int
1700 xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1701 {
1702   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1703   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1704   if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1705     return 1;
1706   return 0;
1707 }
1708
1709
1710 int
1711 xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1712 {
1713   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1714   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1715   return intisa->interfaces[intf].class_id;
1716 }
1717
1718
1719 \f
1720 /* Functional Units.  */
1721
1722
1723 #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1724   do { \
1725     if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1726       { \
1727         xtisa_errno = xtensa_isa_bad_funcUnit; \
1728         strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1729         return (ERRVAL); \
1730       } \
1731   } while (0)
1732
1733
1734 xtensa_funcUnit
1735 xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1736 {
1737   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1738   xtensa_lookup_entry entry, *result = 0;
1739
1740   if (!fname || !*fname)
1741     {
1742       xtisa_errno = xtensa_isa_bad_funcUnit;
1743       strcpy (xtisa_error_msg, "invalid functional unit name");
1744       return XTENSA_UNDEFINED;
1745     }
1746
1747   if (intisa->num_funcUnits != 0)
1748     {
1749       entry.key = fname;
1750       result = bsearch (&entry, intisa->funcUnit_lookup_table,
1751                         intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1752                         xtensa_isa_name_compare);
1753     }
1754
1755   if (!result)
1756     {
1757       xtisa_errno = xtensa_isa_bad_funcUnit;
1758       sprintf (xtisa_error_msg,
1759                "functional unit \"%s\" not recognized", fname);
1760       return XTENSA_UNDEFINED;
1761     }
1762
1763   return result->u.fun;
1764 }
1765
1766
1767 const char *
1768 xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1769 {
1770   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1771   CHECK_FUNCUNIT (intisa, fun, NULL);
1772   return intisa->funcUnits[fun].name;
1773 }
1774
1775
1776 int
1777 xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1778 {
1779   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1780   CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1781   return intisa->funcUnits[fun].num_copies;
1782 }
1783