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