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