1 /* Configurable Xtensa ISA support.
2    Copyright (C) 2003-2016 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
xtensa_isa_errno(xtensa_isa isa)32 xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
33 {
34   return xtisa_errno;
35 }
36 
37 
38 char *
xtensa_isa_error_msg(xtensa_isa isa)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 
69 /* Instruction buffers.  */
70 
71 int
xtensa_insnbuf_size(xtensa_isa isa)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
xtensa_insnbuf_alloc(xtensa_isa isa)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
xtensa_insnbuf_free(xtensa_isa isa,xtensa_insnbuf buf)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
byte_to_word_index(int byte_index)102 byte_to_word_index (int byte_index)
103 {
104   return byte_index / sizeof (xtensa_insnbuf_word);
105 }
106 
107 
108 static inline int
byte_to_bit_index(int byte_index)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
xtensa_insnbuf_to_chars(xtensa_isa isa,const xtensa_insnbuf insn,unsigned char * cp,int num_chars)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
xtensa_insnbuf_from_chars(xtensa_isa isa,xtensa_insnbuf insn,const unsigned char * cp,int num_chars)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 
232 /* ISA information.  */
233 
234 extern xtensa_isa_internal xtensa_modules;
235 
236 xtensa_isa
xtensa_isa_init(xtensa_isa_status * errno_p,char ** error_msg_p)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
xtensa_isa_free(xtensa_isa isa)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
xtensa_isa_name_compare(const void * v1,const void * v2)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
xtensa_isa_maxlength(xtensa_isa isa)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
xtensa_isa_length_from_chars(xtensa_isa isa,const unsigned char * cp)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
xtensa_isa_num_pipe_stages(xtensa_isa isa)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
xtensa_isa_num_formats(xtensa_isa isa)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
xtensa_isa_num_opcodes(xtensa_isa isa)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
xtensa_isa_num_regfiles(xtensa_isa isa)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
xtensa_isa_num_states(xtensa_isa isa)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
xtensa_isa_num_sysregs(xtensa_isa isa)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
xtensa_isa_num_interfaces(xtensa_isa isa)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
xtensa_isa_num_funcUnits(xtensa_isa isa)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 
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 *
xtensa_format_name(xtensa_isa isa,xtensa_format fmt)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
xtensa_format_lookup(xtensa_isa isa,const char * fmtname)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
xtensa_format_decode(xtensa_isa isa,const xtensa_insnbuf insn)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
xtensa_format_encode(xtensa_isa isa,xtensa_format fmt,xtensa_insnbuf insn)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
xtensa_format_length(xtensa_isa isa,xtensa_format fmt)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
xtensa_format_num_slots(xtensa_isa isa,xtensa_format fmt)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
xtensa_format_slot_nop_opcode(xtensa_isa isa,xtensa_format fmt,int slot)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
xtensa_format_get_slot(xtensa_isa isa,xtensa_format fmt,int slot,const xtensa_insnbuf insn,xtensa_insnbuf slotbuf)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
xtensa_format_set_slot(xtensa_isa isa,xtensa_format fmt,int slot,xtensa_insnbuf insn,const xtensa_insnbuf slotbuf)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 
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
xtensa_opcode_lookup(xtensa_isa isa,const char * opname)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
xtensa_opcode_decode(xtensa_isa isa,xtensa_format fmt,int slot,const xtensa_insnbuf slotbuf)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
xtensa_opcode_encode(xtensa_isa isa,xtensa_format fmt,int slot,xtensa_insnbuf slotbuf,xtensa_opcode opc)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 *
xtensa_opcode_name(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_is_branch(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_is_jump(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_is_loop(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_is_call(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_num_operands(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_num_stateOperands(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_num_interfaceOperands(xtensa_isa isa,xtensa_opcode opc)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
xtensa_opcode_num_funcUnit_uses(xtensa_isa isa,xtensa_opcode opc)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 *
xtensa_opcode_funcUnit_use(xtensa_isa isa,xtensa_opcode opc,int u)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 
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 *
get_operand(xtensa_isa_internal * intisa,xtensa_opcode opc,int opnd)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 *
xtensa_operand_name(xtensa_isa isa,xtensa_opcode opc,int opnd)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
xtensa_operand_is_visible(xtensa_isa isa,xtensa_opcode opc,int opnd)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
xtensa_operand_inout(xtensa_isa isa,xtensa_opcode opc,int opnd)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
xtensa_operand_get_field(xtensa_isa isa,xtensa_opcode opc,int opnd,xtensa_format fmt,int slot,const xtensa_insnbuf slotbuf,uint32 * valp)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
xtensa_operand_set_field(xtensa_isa isa,xtensa_opcode opc,int opnd,xtensa_format fmt,int slot,xtensa_insnbuf slotbuf,uint32 val)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
xtensa_operand_encode(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp)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)
1032     return -1;
1033 
1034   if (!intop->encode)
1035     {
1036       /* This is a default operand for a field.  How can we tell if the
1037 	 value fits in the field?  Write the value into the field,
1038 	 read it back, and then make sure we get the same value.  */
1039       static xtensa_insnbuf tmpbuf = 0;
1040       int slot_id;
1041 
1042       if (!tmpbuf)
1043 	{
1044 	  tmpbuf = xtensa_insnbuf_alloc (isa);
1045 	  CHECK_ALLOC (tmpbuf, -1);
1046 	}
1047 
1048       /* A default operand is always associated with a field,
1049 	 but check just to be sure....  */
1050       if (intop->field_id == XTENSA_UNDEFINED)
1051 	{
1052 	  xtisa_errno = xtensa_isa_internal_error;
1053 	  strcpy (xtisa_error_msg, "operand has no field");
1054 	  return -1;
1055 	}
1056 
1057       /* Find some slot that includes the field.  */
1058       for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1059 	{
1060 	  xtensa_get_field_fn get_fn =
1061 	    intisa->slots[slot_id].get_field_fns[intop->field_id];
1062 	  xtensa_set_field_fn set_fn =
1063 	    intisa->slots[slot_id].set_field_fns[intop->field_id];
1064 
1065 	  if (get_fn && set_fn)
1066 	    {
1067 	      (*set_fn) (tmpbuf, *valp);
1068 	      return ((*get_fn) (tmpbuf) != *valp);
1069 	    }
1070 	}
1071 
1072       /* Couldn't find any slot containing the field....  */
1073       xtisa_errno = xtensa_isa_no_field;
1074       strcpy (xtisa_error_msg, "field does not exist in any slot");
1075       return -1;
1076     }
1077 
1078   /* Encode the value.  In some cases, the encoding function may detect
1079      errors, but most of the time the only way to determine if the value
1080      was successfully encoded is to decode it and check if it matches
1081      the original value.  */
1082   orig_val = *valp;
1083   if ((*intop->encode) (valp)
1084       || (test_val = *valp, (*intop->decode) (&test_val))
1085       || test_val != orig_val)
1086     {
1087       xtisa_errno = xtensa_isa_bad_value;
1088       sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1089       return -1;
1090     }
1091 
1092   return 0;
1093 }
1094 
1095 
1096 int
xtensa_operand_decode(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp)1097 xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1098 		       uint32 *valp)
1099 {
1100   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1101   xtensa_operand_internal *intop;
1102 
1103   intop = get_operand (intisa, opc, opnd);
1104   if (!intop) return -1;
1105 
1106   /* Use identity function for "default" operands.  */
1107   if (!intop->decode)
1108     return 0;
1109 
1110   if ((*intop->decode) (valp))
1111     {
1112       xtisa_errno = xtensa_isa_bad_value;
1113       sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
1114       return -1;
1115     }
1116   return 0;
1117 }
1118 
1119 
1120 int
xtensa_operand_is_register(xtensa_isa isa,xtensa_opcode opc,int opnd)1121 xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1122 {
1123   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1124   xtensa_operand_internal *intop;
1125 
1126   intop = get_operand (intisa, opc, opnd);
1127   if (!intop) return XTENSA_UNDEFINED;
1128 
1129   if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1130     return 1;
1131   return 0;
1132 }
1133 
1134 
1135 xtensa_regfile
xtensa_operand_regfile(xtensa_isa isa,xtensa_opcode opc,int opnd)1136 xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1137 {
1138   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1139   xtensa_operand_internal *intop;
1140 
1141   intop = get_operand (intisa, opc, opnd);
1142   if (!intop) return XTENSA_UNDEFINED;
1143 
1144   return intop->regfile;
1145 }
1146 
1147 
1148 int
xtensa_operand_num_regs(xtensa_isa isa,xtensa_opcode opc,int opnd)1149 xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1150 {
1151   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1152   xtensa_operand_internal *intop;
1153 
1154   intop = get_operand (intisa, opc, opnd);
1155   if (!intop) return XTENSA_UNDEFINED;
1156 
1157   return intop->num_regs;
1158 }
1159 
1160 
1161 int
xtensa_operand_is_known_reg(xtensa_isa isa,xtensa_opcode opc,int opnd)1162 xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
1163 {
1164   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1165   xtensa_operand_internal *intop;
1166 
1167   intop = get_operand (intisa, opc, opnd);
1168   if (!intop) return XTENSA_UNDEFINED;
1169 
1170   if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
1171     return 1;
1172   return 0;
1173 }
1174 
1175 
1176 int
xtensa_operand_is_PCrelative(xtensa_isa isa,xtensa_opcode opc,int opnd)1177 xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
1178 {
1179   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1180   xtensa_operand_internal *intop;
1181 
1182   intop = get_operand (intisa, opc, opnd);
1183   if (!intop) return XTENSA_UNDEFINED;
1184 
1185   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1186     return 1;
1187   return 0;
1188 }
1189 
1190 
1191 int
xtensa_operand_do_reloc(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp,uint32 pc)1192 xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1193 			 uint32 *valp, uint32 pc)
1194 {
1195   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1196   xtensa_operand_internal *intop;
1197 
1198   intop = get_operand (intisa, opc, opnd);
1199   if (!intop) return -1;
1200 
1201   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1202     return 0;
1203 
1204   if (!intop->do_reloc)
1205     {
1206       xtisa_errno = xtensa_isa_internal_error;
1207       strcpy (xtisa_error_msg, "operand missing do_reloc function");
1208       return -1;
1209     }
1210 
1211   if ((*intop->do_reloc) (valp, pc))
1212     {
1213       xtisa_errno = xtensa_isa_bad_value;
1214       sprintf (xtisa_error_msg,
1215 	       "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1216       return -1;
1217     }
1218 
1219   return 0;
1220 }
1221 
1222 
1223 int
xtensa_operand_undo_reloc(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp,uint32 pc)1224 xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1225 			   uint32 *valp, uint32 pc)
1226 {
1227   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1228   xtensa_operand_internal *intop;
1229 
1230   intop = get_operand (intisa, opc, opnd);
1231   if (!intop) return -1;
1232 
1233   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1234     return 0;
1235 
1236   if (!intop->undo_reloc)
1237     {
1238       xtisa_errno = xtensa_isa_internal_error;
1239       strcpy (xtisa_error_msg, "operand missing undo_reloc function");
1240       return -1;
1241     }
1242 
1243   if ((*intop->undo_reloc) (valp, pc))
1244     {
1245       xtisa_errno = xtensa_isa_bad_value;
1246       sprintf (xtisa_error_msg,
1247 	       "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1248       return -1;
1249     }
1250 
1251   return 0;
1252 }
1253 
1254 
1255 
1256 /* State Operands.  */
1257 
1258 
1259 #define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
1260   do { \
1261     if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
1262       { \
1263 	xtisa_errno = xtensa_isa_bad_operand; \
1264 	sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
1265 		 "opcode \"%s\" has %d state operands", (STOP), \
1266 		 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
1267 	return (ERRVAL); \
1268       } \
1269   } while (0)
1270 
1271 
1272 xtensa_state
xtensa_stateOperand_state(xtensa_isa isa,xtensa_opcode opc,int stOp)1273 xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
1274 {
1275   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1276   xtensa_iclass_internal *iclass;
1277   int iclass_id;
1278 
1279   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1280   iclass_id = intisa->opcodes[opc].iclass_id;
1281   iclass = &intisa->iclasses[iclass_id];
1282   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
1283   return iclass->stateOperands[stOp].u.state;
1284 }
1285 
1286 
1287 char
xtensa_stateOperand_inout(xtensa_isa isa,xtensa_opcode opc,int stOp)1288 xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
1289 {
1290   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1291   xtensa_iclass_internal *iclass;
1292   int iclass_id;
1293 
1294   CHECK_OPCODE (intisa, opc, 0);
1295   iclass_id = intisa->opcodes[opc].iclass_id;
1296   iclass = &intisa->iclasses[iclass_id];
1297   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
1298   return iclass->stateOperands[stOp].inout;
1299 }
1300 
1301 
1302 
1303 /* Interface Operands.  */
1304 
1305 
1306 #define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
1307   do { \
1308     if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
1309       { \
1310 	xtisa_errno = xtensa_isa_bad_operand; \
1311 	sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
1312 		 "opcode \"%s\" has %d interface operands", (IFOP), \
1313 		 (INTISA)->opcodes[(OPC)].name, \
1314 		 (ICLASS)->num_interfaceOperands); \
1315 	return (ERRVAL); \
1316       } \
1317   } while (0)
1318 
1319 
1320 xtensa_interface
xtensa_interfaceOperand_interface(xtensa_isa isa,xtensa_opcode opc,int ifOp)1321 xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
1322 				   int ifOp)
1323 {
1324   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1325   xtensa_iclass_internal *iclass;
1326   int iclass_id;
1327 
1328   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1329   iclass_id = intisa->opcodes[opc].iclass_id;
1330   iclass = &intisa->iclasses[iclass_id];
1331   CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
1332   return iclass->interfaceOperands[ifOp];
1333 }
1334 
1335 
1336 
1337 /* Register Files.  */
1338 
1339 
1340 #define CHECK_REGFILE(INTISA,RF,ERRVAL) \
1341   do { \
1342     if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1343       { \
1344 	xtisa_errno = xtensa_isa_bad_regfile; \
1345 	strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1346 	return (ERRVAL); \
1347       } \
1348   } while (0)
1349 
1350 
1351 xtensa_regfile
xtensa_regfile_lookup(xtensa_isa isa,const char * name)1352 xtensa_regfile_lookup (xtensa_isa isa, const char *name)
1353 {
1354   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1355   int n;
1356 
1357   if (!name || !*name)
1358     {
1359       xtisa_errno = xtensa_isa_bad_regfile;
1360       strcpy (xtisa_error_msg, "invalid regfile name");
1361       return XTENSA_UNDEFINED;
1362     }
1363 
1364   /* The expected number of regfiles is small; use a linear search.  */
1365   for (n = 0; n < intisa->num_regfiles; n++)
1366     {
1367       if (!filename_cmp (intisa->regfiles[n].name, name))
1368 	return n;
1369     }
1370 
1371   xtisa_errno = xtensa_isa_bad_regfile;
1372   sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
1373   return XTENSA_UNDEFINED;
1374 }
1375 
1376 
1377 xtensa_regfile
xtensa_regfile_lookup_shortname(xtensa_isa isa,const char * shortname)1378 xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
1379 {
1380   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1381   int n;
1382 
1383   if (!shortname || !*shortname)
1384     {
1385       xtisa_errno = xtensa_isa_bad_regfile;
1386       strcpy (xtisa_error_msg, "invalid regfile shortname");
1387       return XTENSA_UNDEFINED;
1388     }
1389 
1390   /* The expected number of regfiles is small; use a linear search.  */
1391   for (n = 0; n < intisa->num_regfiles; n++)
1392     {
1393       /* Ignore regfile views since they always have the same shortnames
1394 	 as their parents.  */
1395       if (intisa->regfiles[n].parent != n)
1396 	continue;
1397       if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
1398 	return n;
1399     }
1400 
1401   xtisa_errno = xtensa_isa_bad_regfile;
1402   sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
1403 	   shortname);
1404   return XTENSA_UNDEFINED;
1405 }
1406 
1407 
1408 const char *
xtensa_regfile_name(xtensa_isa isa,xtensa_regfile rf)1409 xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
1410 {
1411   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1412   CHECK_REGFILE (intisa, rf, NULL);
1413   return intisa->regfiles[rf].name;
1414 }
1415 
1416 
1417 const char *
xtensa_regfile_shortname(xtensa_isa isa,xtensa_regfile rf)1418 xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
1419 {
1420   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1421   CHECK_REGFILE (intisa, rf, NULL);
1422   return intisa->regfiles[rf].shortname;
1423 }
1424 
1425 
1426 xtensa_regfile
xtensa_regfile_view_parent(xtensa_isa isa,xtensa_regfile rf)1427 xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
1428 {
1429   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1430   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1431   return intisa->regfiles[rf].parent;
1432 }
1433 
1434 
1435 int
xtensa_regfile_num_bits(xtensa_isa isa,xtensa_regfile rf)1436 xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
1437 {
1438   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1439   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1440   return intisa->regfiles[rf].num_bits;
1441 }
1442 
1443 
1444 int
xtensa_regfile_num_entries(xtensa_isa isa,xtensa_regfile rf)1445 xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
1446 {
1447   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1448   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1449   return intisa->regfiles[rf].num_entries;
1450 }
1451 
1452 
1453 
1454 /* Processor States.  */
1455 
1456 
1457 #define CHECK_STATE(INTISA,ST,ERRVAL) \
1458   do { \
1459     if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
1460       { \
1461 	xtisa_errno = xtensa_isa_bad_state; \
1462 	strcpy (xtisa_error_msg, "invalid state specifier"); \
1463 	return (ERRVAL); \
1464       } \
1465   } while (0)
1466 
1467 
1468 xtensa_state
xtensa_state_lookup(xtensa_isa isa,const char * name)1469 xtensa_state_lookup (xtensa_isa isa, const char *name)
1470 {
1471   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1472   xtensa_lookup_entry entry, *result = 0;
1473 
1474   if (!name || !*name)
1475     {
1476       xtisa_errno = xtensa_isa_bad_state;
1477       strcpy (xtisa_error_msg, "invalid state name");
1478       return XTENSA_UNDEFINED;
1479     }
1480 
1481   if (intisa->num_states != 0)
1482     {
1483       entry.key = name;
1484       result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
1485 			sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
1486     }
1487 
1488   if (!result)
1489     {
1490       xtisa_errno = xtensa_isa_bad_state;
1491       sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
1492       return XTENSA_UNDEFINED;
1493     }
1494 
1495   return result->u.state;
1496 }
1497 
1498 
1499 const char *
xtensa_state_name(xtensa_isa isa,xtensa_state st)1500 xtensa_state_name (xtensa_isa isa, xtensa_state st)
1501 {
1502   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1503   CHECK_STATE (intisa, st, NULL);
1504   return intisa->states[st].name;
1505 }
1506 
1507 
1508 int
xtensa_state_num_bits(xtensa_isa isa,xtensa_state st)1509 xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
1510 {
1511   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1512   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1513   return intisa->states[st].num_bits;
1514 }
1515 
1516 
1517 int
xtensa_state_is_exported(xtensa_isa isa,xtensa_state st)1518 xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
1519 {
1520   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1521   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1522   if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
1523     return 1;
1524   return 0;
1525 }
1526 
1527 
1528 int
xtensa_state_is_shared_or(xtensa_isa isa,xtensa_state st)1529 xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
1530 {
1531   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1532   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1533   if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
1534     return 1;
1535   return 0;
1536 }
1537 
1538 
1539 
1540 /* Sysregs.  */
1541 
1542 
1543 #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1544   do { \
1545     if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1546       { \
1547 	xtisa_errno = xtensa_isa_bad_sysreg; \
1548 	strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1549 	return (ERRVAL); \
1550       } \
1551   } while (0)
1552 
1553 
1554 xtensa_sysreg
xtensa_sysreg_lookup(xtensa_isa isa,int num,int is_user)1555 xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
1556 {
1557   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1558 
1559   if (is_user != 0)
1560     is_user = 1;
1561 
1562   if (num < 0 || num > intisa->max_sysreg_num[is_user]
1563       || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1564     {
1565       xtisa_errno = xtensa_isa_bad_sysreg;
1566       strcpy (xtisa_error_msg, "sysreg not recognized");
1567       return XTENSA_UNDEFINED;
1568     }
1569 
1570   return intisa->sysreg_table[is_user][num];
1571 }
1572 
1573 
1574 xtensa_sysreg
xtensa_sysreg_lookup_name(xtensa_isa isa,const char * name)1575 xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
1576 {
1577   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1578   xtensa_lookup_entry entry, *result = 0;
1579 
1580   if (!name || !*name)
1581     {
1582       xtisa_errno = xtensa_isa_bad_sysreg;
1583       strcpy (xtisa_error_msg, "invalid sysreg name");
1584       return XTENSA_UNDEFINED;
1585     }
1586 
1587   if (intisa->num_sysregs != 0)
1588     {
1589       entry.key = name;
1590       result = bsearch (&entry, intisa->sysreg_lookup_table,
1591 			intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1592 			xtensa_isa_name_compare);
1593     }
1594 
1595   if (!result)
1596     {
1597       xtisa_errno = xtensa_isa_bad_sysreg;
1598       sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1599       return XTENSA_UNDEFINED;
1600     }
1601 
1602   return result->u.sysreg;
1603 }
1604 
1605 
1606 const char *
xtensa_sysreg_name(xtensa_isa isa,xtensa_sysreg sysreg)1607 xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
1608 {
1609   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1610   CHECK_SYSREG (intisa, sysreg, NULL);
1611   return intisa->sysregs[sysreg].name;
1612 }
1613 
1614 
1615 int
xtensa_sysreg_number(xtensa_isa isa,xtensa_sysreg sysreg)1616 xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
1617 {
1618   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1619   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1620   return intisa->sysregs[sysreg].number;
1621 }
1622 
1623 
1624 int
xtensa_sysreg_is_user(xtensa_isa isa,xtensa_sysreg sysreg)1625 xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
1626 {
1627   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1628   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1629   if (intisa->sysregs[sysreg].is_user)
1630     return 1;
1631   return 0;
1632 }
1633 
1634 
1635 
1636 /* Interfaces.  */
1637 
1638 
1639 #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1640   do { \
1641     if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1642       { \
1643 	xtisa_errno = xtensa_isa_bad_interface; \
1644 	strcpy (xtisa_error_msg, "invalid interface specifier"); \
1645 	return (ERRVAL); \
1646       } \
1647   } while (0)
1648 
1649 
1650 xtensa_interface
xtensa_interface_lookup(xtensa_isa isa,const char * ifname)1651 xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
1652 {
1653   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1654   xtensa_lookup_entry entry, *result = 0;
1655 
1656   if (!ifname || !*ifname)
1657     {
1658       xtisa_errno = xtensa_isa_bad_interface;
1659       strcpy (xtisa_error_msg, "invalid interface name");
1660       return XTENSA_UNDEFINED;
1661     }
1662 
1663   if (intisa->num_interfaces != 0)
1664     {
1665       entry.key = ifname;
1666       result = bsearch (&entry, intisa->interface_lookup_table,
1667 			intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1668 			xtensa_isa_name_compare);
1669     }
1670 
1671   if (!result)
1672     {
1673       xtisa_errno = xtensa_isa_bad_interface;
1674       sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1675       return XTENSA_UNDEFINED;
1676     }
1677 
1678   return result->u.intf;
1679 }
1680 
1681 
1682 const char *
xtensa_interface_name(xtensa_isa isa,xtensa_interface intf)1683 xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1684 {
1685   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1686   CHECK_INTERFACE (intisa, intf, NULL);
1687   return intisa->interfaces[intf].name;
1688 }
1689 
1690 
1691 int
xtensa_interface_num_bits(xtensa_isa isa,xtensa_interface intf)1692 xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1693 {
1694   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1695   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1696   return intisa->interfaces[intf].num_bits;
1697 }
1698 
1699 
1700 char
xtensa_interface_inout(xtensa_isa isa,xtensa_interface intf)1701 xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
1702 {
1703   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1704   CHECK_INTERFACE (intisa, intf, 0);
1705   return intisa->interfaces[intf].inout;
1706 }
1707 
1708 
1709 int
xtensa_interface_has_side_effect(xtensa_isa isa,xtensa_interface intf)1710 xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1711 {
1712   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1713   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1714   if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1715     return 1;
1716   return 0;
1717 }
1718 
1719 
1720 int
xtensa_interface_class_id(xtensa_isa isa,xtensa_interface intf)1721 xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1722 {
1723   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1724   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1725   return intisa->interfaces[intf].class_id;
1726 }
1727 
1728 
1729 
1730 /* Functional Units.  */
1731 
1732 
1733 #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1734   do { \
1735     if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1736       { \
1737 	xtisa_errno = xtensa_isa_bad_funcUnit; \
1738 	strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1739 	return (ERRVAL); \
1740       } \
1741   } while (0)
1742 
1743 
1744 xtensa_funcUnit
xtensa_funcUnit_lookup(xtensa_isa isa,const char * fname)1745 xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1746 {
1747   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1748   xtensa_lookup_entry entry, *result = 0;
1749 
1750   if (!fname || !*fname)
1751     {
1752       xtisa_errno = xtensa_isa_bad_funcUnit;
1753       strcpy (xtisa_error_msg, "invalid functional unit name");
1754       return XTENSA_UNDEFINED;
1755     }
1756 
1757   if (intisa->num_funcUnits != 0)
1758     {
1759       entry.key = fname;
1760       result = bsearch (&entry, intisa->funcUnit_lookup_table,
1761 			intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1762 			xtensa_isa_name_compare);
1763     }
1764 
1765   if (!result)
1766     {
1767       xtisa_errno = xtensa_isa_bad_funcUnit;
1768       sprintf (xtisa_error_msg,
1769 	       "functional unit \"%s\" not recognized", fname);
1770       return XTENSA_UNDEFINED;
1771     }
1772 
1773   return result->u.fun;
1774 }
1775 
1776 
1777 const char *
xtensa_funcUnit_name(xtensa_isa isa,xtensa_funcUnit fun)1778 xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1779 {
1780   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1781   CHECK_FUNCUNIT (intisa, fun, NULL);
1782   return intisa->funcUnits[fun].name;
1783 }
1784 
1785 
1786 int
xtensa_funcUnit_num_copies(xtensa_isa isa,xtensa_funcUnit fun)1787 xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1788 {
1789   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1790   CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1791   return intisa->funcUnits[fun].num_copies;
1792 }
1793 
1794