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