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