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