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