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