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