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