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