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