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