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