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