1 /* Configurable Xtensa ISA support.
2    Copyright (C) 2003-2021 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 static xtensa_isa_status xtisa_errno;
28 static 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] |= (unsigned) (*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       if (sreg->number >= 0)
296 	isa->sysreg_table[is_user][sreg->number] = n;
297     }
298 
299   /* Set up the interface lookup table.  */
300   isa->interface_lookup_table =
301     bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
302   CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
303 			error_msg_p);
304   for (n = 0; n < isa->num_interfaces; n++)
305     {
306       isa->interface_lookup_table[n].key = isa->interfaces[n].name;
307       isa->interface_lookup_table[n].u.intf = n;
308     }
309   qsort (isa->interface_lookup_table, isa->num_interfaces,
310 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
311 
312   /* Set up the funcUnit lookup table.  */
313   isa->funcUnit_lookup_table =
314     bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
315   CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
316 			error_msg_p);
317   for (n = 0; n < isa->num_funcUnits; n++)
318     {
319       isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
320       isa->funcUnit_lookup_table[n].u.fun = n;
321     }
322   qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
323 	 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
324 
325   isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
326 		       sizeof (xtensa_insnbuf_word));
327 
328   return (xtensa_isa) isa;
329 }
330 
331 
332 void
xtensa_isa_free(xtensa_isa isa)333 xtensa_isa_free (xtensa_isa isa)
334 {
335   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
336   int n;
337 
338   /* With this version of the code, the xtensa_isa structure is not
339      dynamically allocated, so this function is not essential.  Free
340      the memory allocated by xtensa_isa_init and restore the xtensa_isa
341      structure to its initial state.  */
342 
343   free (intisa->opname_lookup_table);
344   intisa->opname_lookup_table = 0;
345 
346   free (intisa->state_lookup_table);
347   intisa->state_lookup_table = 0;
348 
349   free (intisa->sysreg_lookup_table);
350   intisa->sysreg_lookup_table = 0;
351 
352   for (n = 0; n < 2; n++)
353     {
354       free (intisa->sysreg_table[n]);
355       intisa->sysreg_table[n] = 0;
356     }
357 
358   free (intisa->interface_lookup_table);
359   intisa->interface_lookup_table = 0;
360 
361   free (intisa->funcUnit_lookup_table);
362   intisa->funcUnit_lookup_table = 0;
363 }
364 
365 
366 int
xtensa_isa_name_compare(const void * v1,const void * v2)367 xtensa_isa_name_compare (const void *v1, const void *v2)
368 {
369   xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
370   xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
371 
372   return strcasecmp (e1->key, e2->key);
373 }
374 
375 
376 int
xtensa_isa_maxlength(xtensa_isa isa)377 xtensa_isa_maxlength (xtensa_isa isa)
378 {
379   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
380   return intisa->insn_size;
381 }
382 
383 
384 int
xtensa_isa_length_from_chars(xtensa_isa isa,const unsigned char * cp)385 xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
386 {
387   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
388   return (intisa->length_decode_fn) (cp);
389 }
390 
391 
392 int
xtensa_isa_num_pipe_stages(xtensa_isa isa)393 xtensa_isa_num_pipe_stages (xtensa_isa isa)
394 {
395   xtensa_opcode opcode;
396   xtensa_funcUnit_use *use;
397   int num_opcodes, num_uses;
398   int i, stage;
399   static int max_stage = XTENSA_UNDEFINED;
400 
401   /* Only compute the value once.  */
402   if (max_stage != XTENSA_UNDEFINED)
403     return max_stage + 1;
404 
405   num_opcodes = xtensa_isa_num_opcodes (isa);
406   for (opcode = 0; opcode < num_opcodes; opcode++)
407     {
408       num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
409       for (i = 0; i < num_uses; i++)
410 	{
411 	  use = xtensa_opcode_funcUnit_use (isa, opcode, i);
412 	  stage = use->stage;
413 	  if (stage > max_stage)
414 	    max_stage = stage;
415 	}
416     }
417 
418   return max_stage + 1;
419 }
420 
421 
422 int
xtensa_isa_num_formats(xtensa_isa isa)423 xtensa_isa_num_formats (xtensa_isa isa)
424 {
425   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
426   return intisa->num_formats;
427 }
428 
429 
430 int
xtensa_isa_num_opcodes(xtensa_isa isa)431 xtensa_isa_num_opcodes (xtensa_isa isa)
432 {
433   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
434   return intisa->num_opcodes;
435 }
436 
437 
438 int
xtensa_isa_num_regfiles(xtensa_isa isa)439 xtensa_isa_num_regfiles (xtensa_isa isa)
440 {
441   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
442   return intisa->num_regfiles;
443 }
444 
445 
446 int
xtensa_isa_num_states(xtensa_isa isa)447 xtensa_isa_num_states (xtensa_isa isa)
448 {
449   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
450   return intisa->num_states;
451 }
452 
453 
454 int
xtensa_isa_num_sysregs(xtensa_isa isa)455 xtensa_isa_num_sysregs (xtensa_isa isa)
456 {
457   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
458   return intisa->num_sysregs;
459 }
460 
461 
462 int
xtensa_isa_num_interfaces(xtensa_isa isa)463 xtensa_isa_num_interfaces (xtensa_isa isa)
464 {
465   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
466   return intisa->num_interfaces;
467 }
468 
469 
470 int
xtensa_isa_num_funcUnits(xtensa_isa isa)471 xtensa_isa_num_funcUnits (xtensa_isa isa)
472 {
473   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
474   return intisa->num_funcUnits;
475 }
476 
477 
478 
479 /* Instruction formats.  */
480 
481 
482 #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
483   do { \
484     if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
485       { \
486 	xtisa_errno = xtensa_isa_bad_format; \
487 	strcpy (xtisa_error_msg, "invalid format specifier"); \
488 	return (ERRVAL); \
489       } \
490   } while (0)
491 
492 
493 #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
494   do { \
495     if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
496       { \
497 	xtisa_errno = xtensa_isa_bad_slot; \
498 	strcpy (xtisa_error_msg, "invalid slot specifier"); \
499 	return (ERRVAL); \
500       } \
501   } while (0)
502 
503 
504 const char *
xtensa_format_name(xtensa_isa isa,xtensa_format fmt)505 xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
506 {
507   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
508   CHECK_FORMAT (intisa, fmt, NULL);
509   return intisa->formats[fmt].name;
510 }
511 
512 
513 xtensa_format
xtensa_format_lookup(xtensa_isa isa,const char * fmtname)514 xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
515 {
516   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
517   int fmt;
518 
519   if (!fmtname || !*fmtname)
520     {
521       xtisa_errno = xtensa_isa_bad_format;
522       strcpy (xtisa_error_msg, "invalid format name");
523       return XTENSA_UNDEFINED;
524     }
525 
526   for (fmt = 0; fmt < intisa->num_formats; fmt++)
527     {
528       if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
529 	return fmt;
530     }
531 
532   xtisa_errno = xtensa_isa_bad_format;
533   sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
534   return XTENSA_UNDEFINED;
535 }
536 
537 
538 xtensa_format
xtensa_format_decode(xtensa_isa isa,const xtensa_insnbuf insn)539 xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
540 {
541   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
542   xtensa_format fmt;
543 
544   fmt = (intisa->format_decode_fn) (insn);
545   if (fmt != XTENSA_UNDEFINED)
546     return fmt;
547 
548   xtisa_errno = xtensa_isa_bad_format;
549   strcpy (xtisa_error_msg, "cannot decode instruction format");
550   return XTENSA_UNDEFINED;
551 }
552 
553 
554 int
xtensa_format_encode(xtensa_isa isa,xtensa_format fmt,xtensa_insnbuf insn)555 xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
556 {
557   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
558   CHECK_FORMAT (intisa, fmt, -1);
559   (*intisa->formats[fmt].encode_fn) (insn);
560   return 0;
561 }
562 
563 
564 int
xtensa_format_length(xtensa_isa isa,xtensa_format fmt)565 xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
566 {
567   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
568   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
569   return intisa->formats[fmt].length;
570 }
571 
572 
573 int
xtensa_format_num_slots(xtensa_isa isa,xtensa_format fmt)574 xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
575 {
576   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
577   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
578   return intisa->formats[fmt].num_slots;
579 }
580 
581 
582 xtensa_opcode
xtensa_format_slot_nop_opcode(xtensa_isa isa,xtensa_format fmt,int slot)583 xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
584 {
585   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
586   int slot_id;
587 
588   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
590 
591   slot_id = intisa->formats[fmt].slot_id[slot];
592   return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
593 }
594 
595 
596 int
xtensa_format_get_slot(xtensa_isa isa,xtensa_format fmt,int slot,const xtensa_insnbuf insn,xtensa_insnbuf slotbuf)597 xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
598 			const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
599 {
600   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
601   int slot_id;
602 
603   CHECK_FORMAT (intisa, fmt, -1);
604   CHECK_SLOT (intisa, fmt, slot, -1);
605 
606   slot_id = intisa->formats[fmt].slot_id[slot];
607   (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
608   return 0;
609 }
610 
611 
612 int
xtensa_format_set_slot(xtensa_isa isa,xtensa_format fmt,int slot,xtensa_insnbuf insn,const xtensa_insnbuf slotbuf)613 xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
614 			xtensa_insnbuf insn, const 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].set_fn) (insn, slotbuf);
624   return 0;
625 }
626 
627 
628 
629 /* Opcode information.  */
630 
631 
632 #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
633   do { \
634     if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
635       { \
636 	xtisa_errno = xtensa_isa_bad_opcode; \
637 	strcpy (xtisa_error_msg, "invalid opcode specifier"); \
638 	return (ERRVAL); \
639       } \
640   } while (0)
641 
642 
643 xtensa_opcode
xtensa_opcode_lookup(xtensa_isa isa,const char * opname)644 xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
645 {
646   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
647   xtensa_lookup_entry entry, *result = 0;
648 
649   if (!opname || !*opname)
650     {
651       xtisa_errno = xtensa_isa_bad_opcode;
652       strcpy (xtisa_error_msg, "invalid opcode name");
653       return XTENSA_UNDEFINED;
654     }
655 
656   if (intisa->num_opcodes != 0)
657     {
658       entry.key = opname;
659       result = bsearch (&entry, intisa->opname_lookup_table,
660 			intisa->num_opcodes, sizeof (xtensa_lookup_entry),
661 			xtensa_isa_name_compare);
662     }
663 
664   if (!result)
665     {
666       xtisa_errno = xtensa_isa_bad_opcode;
667       sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
668       return XTENSA_UNDEFINED;
669     }
670 
671   return result->u.opcode;
672 }
673 
674 
675 xtensa_opcode
xtensa_opcode_decode(xtensa_isa isa,xtensa_format fmt,int slot,const xtensa_insnbuf slotbuf)676 xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
677 		      const xtensa_insnbuf slotbuf)
678 {
679   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
680   int slot_id;
681   xtensa_opcode opc;
682 
683   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
684   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
685 
686   slot_id = intisa->formats[fmt].slot_id[slot];
687 
688   opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
689   if (opc != XTENSA_UNDEFINED)
690     return opc;
691 
692   xtisa_errno = xtensa_isa_bad_opcode;
693   strcpy (xtisa_error_msg, "cannot decode opcode");
694   return XTENSA_UNDEFINED;
695 }
696 
697 
698 int
xtensa_opcode_encode(xtensa_isa isa,xtensa_format fmt,int slot,xtensa_insnbuf slotbuf,xtensa_opcode opc)699 xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
700 		      xtensa_insnbuf slotbuf, xtensa_opcode opc)
701 {
702   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
703   int slot_id;
704   xtensa_opcode_encode_fn encode_fn;
705 
706   CHECK_FORMAT (intisa, fmt, -1);
707   CHECK_SLOT (intisa, fmt, slot, -1);
708   CHECK_OPCODE (intisa, opc, -1);
709 
710   slot_id = intisa->formats[fmt].slot_id[slot];
711   encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
712   if (!encode_fn)
713     {
714       xtisa_errno = xtensa_isa_wrong_slot;
715       sprintf (xtisa_error_msg,
716 	       "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
717 	       intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
718       return -1;
719     }
720   (*encode_fn) (slotbuf);
721   return 0;
722 }
723 
724 
725 const char *
xtensa_opcode_name(xtensa_isa isa,xtensa_opcode opc)726 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
727 {
728   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
729   CHECK_OPCODE (intisa, opc, NULL);
730   return intisa->opcodes[opc].name;
731 }
732 
733 
734 int
xtensa_opcode_is_branch(xtensa_isa isa,xtensa_opcode opc)735 xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
736 {
737   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
738   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
739   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
740     return 1;
741   return 0;
742 }
743 
744 
745 int
xtensa_opcode_is_jump(xtensa_isa isa,xtensa_opcode opc)746 xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
747 {
748   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
751     return 1;
752   return 0;
753 }
754 
755 
756 int
xtensa_opcode_is_loop(xtensa_isa isa,xtensa_opcode opc)757 xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
758 {
759   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
762     return 1;
763   return 0;
764 }
765 
766 
767 int
xtensa_opcode_is_call(xtensa_isa isa,xtensa_opcode opc)768 xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
769 {
770   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
771   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
772   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
773     return 1;
774   return 0;
775 }
776 
777 
778 int
xtensa_opcode_num_operands(xtensa_isa isa,xtensa_opcode opc)779 xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
780 {
781   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782   int iclass_id;
783 
784   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
785   iclass_id = intisa->opcodes[opc].iclass_id;
786   return intisa->iclasses[iclass_id].num_operands;
787 }
788 
789 
790 int
xtensa_opcode_num_stateOperands(xtensa_isa isa,xtensa_opcode opc)791 xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
792 {
793   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
794   int iclass_id;
795 
796   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
797   iclass_id = intisa->opcodes[opc].iclass_id;
798   return intisa->iclasses[iclass_id].num_stateOperands;
799 }
800 
801 
802 int
xtensa_opcode_num_interfaceOperands(xtensa_isa isa,xtensa_opcode opc)803 xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
804 {
805   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
806   int iclass_id;
807 
808   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
809   iclass_id = intisa->opcodes[opc].iclass_id;
810   return intisa->iclasses[iclass_id].num_interfaceOperands;
811 }
812 
813 
814 int
xtensa_opcode_num_funcUnit_uses(xtensa_isa isa,xtensa_opcode opc)815 xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
816 {
817   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
818   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
819   return intisa->opcodes[opc].num_funcUnit_uses;
820 }
821 
822 
823 xtensa_funcUnit_use *
xtensa_opcode_funcUnit_use(xtensa_isa isa,xtensa_opcode opc,int u)824 xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
825 {
826   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
827   CHECK_OPCODE (intisa, opc, NULL);
828   if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
829     {
830       xtisa_errno = xtensa_isa_bad_funcUnit;
831       sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
832 	       "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
833 	       intisa->opcodes[opc].num_funcUnit_uses);
834       return NULL;
835     }
836   return &intisa->opcodes[opc].funcUnit_uses[u];
837 }
838 
839 
840 
841 /* Operand information.  */
842 
843 
844 #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
845   do { \
846     if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
847       { \
848 	xtisa_errno = xtensa_isa_bad_operand; \
849 	sprintf (xtisa_error_msg, "invalid operand number (%d); " \
850 		 "opcode \"%s\" has %d operands", (OPND), \
851 		 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
852 	return (ERRVAL); \
853       } \
854   } while (0)
855 
856 
857 static xtensa_operand_internal *
get_operand(xtensa_isa_internal * intisa,xtensa_opcode opc,int opnd)858 get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
859 {
860   xtensa_iclass_internal *iclass;
861   int iclass_id, operand_id;
862 
863   CHECK_OPCODE (intisa, opc, NULL);
864   iclass_id = intisa->opcodes[opc].iclass_id;
865   iclass = &intisa->iclasses[iclass_id];
866   CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
867   operand_id = iclass->operands[opnd].u.operand_id;
868   return &intisa->operands[operand_id];
869 }
870 
871 
872 const char *
xtensa_operand_name(xtensa_isa isa,xtensa_opcode opc,int opnd)873 xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
874 {
875   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
876   xtensa_operand_internal *intop;
877 
878   intop = get_operand (intisa, opc, opnd);
879   if (!intop) return NULL;
880   return intop->name;
881 }
882 
883 
884 int
xtensa_operand_is_visible(xtensa_isa isa,xtensa_opcode opc,int opnd)885 xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
886 {
887   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
888   xtensa_iclass_internal *iclass;
889   int iclass_id, operand_id;
890   xtensa_operand_internal *intop;
891 
892   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
893   iclass_id = intisa->opcodes[opc].iclass_id;
894   iclass = &intisa->iclasses[iclass_id];
895   CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
896 
897   /* Special case for "sout" operands.  */
898   if (iclass->operands[opnd].inout == 's')
899     return 0;
900 
901   operand_id = iclass->operands[opnd].u.operand_id;
902   intop = &intisa->operands[operand_id];
903 
904   if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
905     return 1;
906   return 0;
907 }
908 
909 
910 char
xtensa_operand_inout(xtensa_isa isa,xtensa_opcode opc,int opnd)911 xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
912 {
913   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
914   xtensa_iclass_internal *iclass;
915   int iclass_id;
916   char inout;
917 
918   CHECK_OPCODE (intisa, opc, 0);
919   iclass_id = intisa->opcodes[opc].iclass_id;
920   iclass = &intisa->iclasses[iclass_id];
921   CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
922   inout = iclass->operands[opnd].inout;
923 
924   /* Special case for "sout" operands.  */
925   if (inout == 's')
926     return 'o';
927 
928   return inout;
929 }
930 
931 
932 int
xtensa_operand_get_field(xtensa_isa isa,xtensa_opcode opc,int opnd,xtensa_format fmt,int slot,const xtensa_insnbuf slotbuf,uint32 * valp)933 xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
934 			  xtensa_format fmt, int slot,
935 			  const xtensa_insnbuf slotbuf, uint32 *valp)
936 {
937   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
938   xtensa_operand_internal *intop;
939   int slot_id;
940   xtensa_get_field_fn get_fn;
941 
942   intop = get_operand (intisa, opc, opnd);
943   if (!intop) return -1;
944 
945   CHECK_FORMAT (intisa, fmt, -1);
946   CHECK_SLOT (intisa, fmt, slot, -1);
947 
948   slot_id = intisa->formats[fmt].slot_id[slot];
949   if (intop->field_id == XTENSA_UNDEFINED)
950     {
951       xtisa_errno = xtensa_isa_no_field;
952       strcpy (xtisa_error_msg, "implicit operand has no field");
953       return -1;
954     }
955   get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
956   if (!get_fn)
957     {
958       xtisa_errno = xtensa_isa_wrong_slot;
959       sprintf (xtisa_error_msg,
960 	       "operand \"%s\" does not exist in slot %d of format \"%s\"",
961 	       intop->name, slot, intisa->formats[fmt].name);
962       return -1;
963     }
964   *valp = (*get_fn) (slotbuf);
965   return 0;
966 }
967 
968 
969 int
xtensa_operand_set_field(xtensa_isa isa,xtensa_opcode opc,int opnd,xtensa_format fmt,int slot,xtensa_insnbuf slotbuf,uint32 val)970 xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
971 			  xtensa_format fmt, int slot,
972 			  xtensa_insnbuf slotbuf, uint32 val)
973 {
974   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
975   xtensa_operand_internal *intop;
976   int slot_id;
977   xtensa_set_field_fn set_fn;
978 
979   intop = get_operand (intisa, opc, opnd);
980   if (!intop) return -1;
981 
982   CHECK_FORMAT (intisa, fmt, -1);
983   CHECK_SLOT (intisa, fmt, slot, -1);
984 
985   slot_id = intisa->formats[fmt].slot_id[slot];
986   if (intop->field_id == XTENSA_UNDEFINED)
987     {
988       xtisa_errno = xtensa_isa_no_field;
989       strcpy (xtisa_error_msg, "implicit operand has no field");
990       return -1;
991     }
992   set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
993   if (!set_fn)
994     {
995       xtisa_errno = xtensa_isa_wrong_slot;
996       sprintf (xtisa_error_msg,
997 	       "operand \"%s\" does not exist in slot %d of format \"%s\"",
998 	       intop->name, slot, intisa->formats[fmt].name);
999       return -1;
1000     }
1001   (*set_fn) (slotbuf, val);
1002   return 0;
1003 }
1004 
1005 
1006 int
xtensa_operand_encode(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp)1007 xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1008 		       uint32 *valp)
1009 {
1010   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1011   xtensa_operand_internal *intop;
1012   uint32 test_val, orig_val;
1013 
1014   intop = get_operand (intisa, opc, opnd);
1015   if (!intop)
1016     return -1;
1017 
1018   if (!intop->encode)
1019     {
1020       /* This is a default operand for a field.  How can we tell if the
1021 	 value fits in the field?  Write the value into the field,
1022 	 read it back, and then make sure we get the same value.  */
1023       static xtensa_insnbuf tmpbuf = 0;
1024       int slot_id;
1025 
1026       if (!tmpbuf)
1027 	{
1028 	  tmpbuf = xtensa_insnbuf_alloc (isa);
1029 	  CHECK_ALLOC (tmpbuf, -1);
1030 	}
1031 
1032       /* A default operand is always associated with a field,
1033 	 but check just to be sure....  */
1034       if (intop->field_id == XTENSA_UNDEFINED)
1035 	{
1036 	  xtisa_errno = xtensa_isa_internal_error;
1037 	  strcpy (xtisa_error_msg, "operand has no field");
1038 	  return -1;
1039 	}
1040 
1041       /* Find some slot that includes the field.  */
1042       for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1043 	{
1044 	  xtensa_get_field_fn get_fn =
1045 	    intisa->slots[slot_id].get_field_fns[intop->field_id];
1046 	  xtensa_set_field_fn set_fn =
1047 	    intisa->slots[slot_id].set_field_fns[intop->field_id];
1048 
1049 	  if (get_fn && set_fn)
1050 	    {
1051 	      (*set_fn) (tmpbuf, *valp);
1052 	      return ((*get_fn) (tmpbuf) != *valp);
1053 	    }
1054 	}
1055 
1056       /* Couldn't find any slot containing the field....  */
1057       xtisa_errno = xtensa_isa_no_field;
1058       strcpy (xtisa_error_msg, "field does not exist in any slot");
1059       return -1;
1060     }
1061 
1062   /* Encode the value.  In some cases, the encoding function may detect
1063      errors, but most of the time the only way to determine if the value
1064      was successfully encoded is to decode it and check if it matches
1065      the original value.  */
1066   orig_val = *valp;
1067   if ((*intop->encode) (valp)
1068       || (test_val = *valp, (*intop->decode) (&test_val))
1069       || test_val != orig_val)
1070     {
1071       xtisa_errno = xtensa_isa_bad_value;
1072       sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1073       return -1;
1074     }
1075 
1076   return 0;
1077 }
1078 
1079 
1080 int
xtensa_operand_decode(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp)1081 xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1082 		       uint32 *valp)
1083 {
1084   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1085   xtensa_operand_internal *intop;
1086 
1087   intop = get_operand (intisa, opc, opnd);
1088   if (!intop) return -1;
1089 
1090   /* Use identity function for "default" operands.  */
1091   if (!intop->decode)
1092     return 0;
1093 
1094   if ((*intop->decode) (valp))
1095     {
1096       xtisa_errno = xtensa_isa_bad_value;
1097       sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
1098       return -1;
1099     }
1100   return 0;
1101 }
1102 
1103 
1104 int
xtensa_operand_is_register(xtensa_isa isa,xtensa_opcode opc,int opnd)1105 xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1106 {
1107   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1108   xtensa_operand_internal *intop;
1109 
1110   intop = get_operand (intisa, opc, opnd);
1111   if (!intop) return XTENSA_UNDEFINED;
1112 
1113   if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1114     return 1;
1115   return 0;
1116 }
1117 
1118 
1119 xtensa_regfile
xtensa_operand_regfile(xtensa_isa isa,xtensa_opcode opc,int opnd)1120 xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1121 {
1122   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1123   xtensa_operand_internal *intop;
1124 
1125   intop = get_operand (intisa, opc, opnd);
1126   if (!intop) return XTENSA_UNDEFINED;
1127 
1128   return intop->regfile;
1129 }
1130 
1131 
1132 int
xtensa_operand_num_regs(xtensa_isa isa,xtensa_opcode opc,int opnd)1133 xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1134 {
1135   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1136   xtensa_operand_internal *intop;
1137 
1138   intop = get_operand (intisa, opc, opnd);
1139   if (!intop) return XTENSA_UNDEFINED;
1140 
1141   return intop->num_regs;
1142 }
1143 
1144 
1145 int
xtensa_operand_is_known_reg(xtensa_isa isa,xtensa_opcode opc,int opnd)1146 xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
1147 {
1148   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1149   xtensa_operand_internal *intop;
1150 
1151   intop = get_operand (intisa, opc, opnd);
1152   if (!intop) return XTENSA_UNDEFINED;
1153 
1154   if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
1155     return 1;
1156   return 0;
1157 }
1158 
1159 
1160 int
xtensa_operand_is_PCrelative(xtensa_isa isa,xtensa_opcode opc,int opnd)1161 xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
1162 {
1163   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1164   xtensa_operand_internal *intop;
1165 
1166   intop = get_operand (intisa, opc, opnd);
1167   if (!intop) return XTENSA_UNDEFINED;
1168 
1169   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1170     return 1;
1171   return 0;
1172 }
1173 
1174 
1175 int
xtensa_operand_do_reloc(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp,uint32 pc)1176 xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1177 			 uint32 *valp, uint32 pc)
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 -1;
1184 
1185   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1186     return 0;
1187 
1188   if (!intop->do_reloc)
1189     {
1190       xtisa_errno = xtensa_isa_internal_error;
1191       strcpy (xtisa_error_msg, "operand missing do_reloc function");
1192       return -1;
1193     }
1194 
1195   if ((*intop->do_reloc) (valp, pc))
1196     {
1197       xtisa_errno = xtensa_isa_bad_value;
1198       sprintf (xtisa_error_msg,
1199 	       "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1200       return -1;
1201     }
1202 
1203   return 0;
1204 }
1205 
1206 
1207 int
xtensa_operand_undo_reloc(xtensa_isa isa,xtensa_opcode opc,int opnd,uint32 * valp,uint32 pc)1208 xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1209 			   uint32 *valp, uint32 pc)
1210 {
1211   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1212   xtensa_operand_internal *intop;
1213 
1214   intop = get_operand (intisa, opc, opnd);
1215   if (!intop) return -1;
1216 
1217   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1218     return 0;
1219 
1220   if (!intop->undo_reloc)
1221     {
1222       xtisa_errno = xtensa_isa_internal_error;
1223       strcpy (xtisa_error_msg, "operand missing undo_reloc function");
1224       return -1;
1225     }
1226 
1227   if ((*intop->undo_reloc) (valp, pc))
1228     {
1229       xtisa_errno = xtensa_isa_bad_value;
1230       sprintf (xtisa_error_msg,
1231 	       "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1232       return -1;
1233     }
1234 
1235   return 0;
1236 }
1237 
1238 
1239 
1240 /* State Operands.  */
1241 
1242 
1243 #define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
1244   do { \
1245     if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
1246       { \
1247 	xtisa_errno = xtensa_isa_bad_operand; \
1248 	sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
1249 		 "opcode \"%s\" has %d state operands", (STOP), \
1250 		 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
1251 	return (ERRVAL); \
1252       } \
1253   } while (0)
1254 
1255 
1256 xtensa_state
xtensa_stateOperand_state(xtensa_isa isa,xtensa_opcode opc,int stOp)1257 xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
1258 {
1259   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1260   xtensa_iclass_internal *iclass;
1261   int iclass_id;
1262 
1263   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1264   iclass_id = intisa->opcodes[opc].iclass_id;
1265   iclass = &intisa->iclasses[iclass_id];
1266   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
1267   return iclass->stateOperands[stOp].u.state;
1268 }
1269 
1270 
1271 char
xtensa_stateOperand_inout(xtensa_isa isa,xtensa_opcode opc,int stOp)1272 xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
1273 {
1274   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1275   xtensa_iclass_internal *iclass;
1276   int iclass_id;
1277 
1278   CHECK_OPCODE (intisa, opc, 0);
1279   iclass_id = intisa->opcodes[opc].iclass_id;
1280   iclass = &intisa->iclasses[iclass_id];
1281   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
1282   return iclass->stateOperands[stOp].inout;
1283 }
1284 
1285 
1286 
1287 /* Interface Operands.  */
1288 
1289 
1290 #define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
1291   do { \
1292     if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
1293       { \
1294 	xtisa_errno = xtensa_isa_bad_operand; \
1295 	sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
1296 		 "opcode \"%s\" has %d interface operands", (IFOP), \
1297 		 (INTISA)->opcodes[(OPC)].name, \
1298 		 (ICLASS)->num_interfaceOperands); \
1299 	return (ERRVAL); \
1300       } \
1301   } while (0)
1302 
1303 
1304 xtensa_interface
xtensa_interfaceOperand_interface(xtensa_isa isa,xtensa_opcode opc,int ifOp)1305 xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
1306 				   int ifOp)
1307 {
1308   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1309   xtensa_iclass_internal *iclass;
1310   int iclass_id;
1311 
1312   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1313   iclass_id = intisa->opcodes[opc].iclass_id;
1314   iclass = &intisa->iclasses[iclass_id];
1315   CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
1316   return iclass->interfaceOperands[ifOp];
1317 }
1318 
1319 
1320 
1321 /* Register Files.  */
1322 
1323 
1324 #define CHECK_REGFILE(INTISA,RF,ERRVAL) \
1325   do { \
1326     if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1327       { \
1328 	xtisa_errno = xtensa_isa_bad_regfile; \
1329 	strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1330 	return (ERRVAL); \
1331       } \
1332   } while (0)
1333 
1334 
1335 xtensa_regfile
xtensa_regfile_lookup(xtensa_isa isa,const char * name)1336 xtensa_regfile_lookup (xtensa_isa isa, const char *name)
1337 {
1338   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1339   int n;
1340 
1341   if (!name || !*name)
1342     {
1343       xtisa_errno = xtensa_isa_bad_regfile;
1344       strcpy (xtisa_error_msg, "invalid regfile name");
1345       return XTENSA_UNDEFINED;
1346     }
1347 
1348   /* The expected number of regfiles is small; use a linear search.  */
1349   for (n = 0; n < intisa->num_regfiles; n++)
1350     {
1351       if (!filename_cmp (intisa->regfiles[n].name, name))
1352 	return n;
1353     }
1354 
1355   xtisa_errno = xtensa_isa_bad_regfile;
1356   sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
1357   return XTENSA_UNDEFINED;
1358 }
1359 
1360 
1361 xtensa_regfile
xtensa_regfile_lookup_shortname(xtensa_isa isa,const char * shortname)1362 xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
1363 {
1364   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1365   int n;
1366 
1367   if (!shortname || !*shortname)
1368     {
1369       xtisa_errno = xtensa_isa_bad_regfile;
1370       strcpy (xtisa_error_msg, "invalid regfile shortname");
1371       return XTENSA_UNDEFINED;
1372     }
1373 
1374   /* The expected number of regfiles is small; use a linear search.  */
1375   for (n = 0; n < intisa->num_regfiles; n++)
1376     {
1377       /* Ignore regfile views since they always have the same shortnames
1378 	 as their parents.  */
1379       if (intisa->regfiles[n].parent != n)
1380 	continue;
1381       if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
1382 	return n;
1383     }
1384 
1385   xtisa_errno = xtensa_isa_bad_regfile;
1386   sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
1387 	   shortname);
1388   return XTENSA_UNDEFINED;
1389 }
1390 
1391 
1392 const char *
xtensa_regfile_name(xtensa_isa isa,xtensa_regfile rf)1393 xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
1394 {
1395   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1396   CHECK_REGFILE (intisa, rf, NULL);
1397   return intisa->regfiles[rf].name;
1398 }
1399 
1400 
1401 const char *
xtensa_regfile_shortname(xtensa_isa isa,xtensa_regfile rf)1402 xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
1403 {
1404   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1405   CHECK_REGFILE (intisa, rf, NULL);
1406   return intisa->regfiles[rf].shortname;
1407 }
1408 
1409 
1410 xtensa_regfile
xtensa_regfile_view_parent(xtensa_isa isa,xtensa_regfile rf)1411 xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
1412 {
1413   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1414   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1415   return intisa->regfiles[rf].parent;
1416 }
1417 
1418 
1419 int
xtensa_regfile_num_bits(xtensa_isa isa,xtensa_regfile rf)1420 xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
1421 {
1422   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1423   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1424   return intisa->regfiles[rf].num_bits;
1425 }
1426 
1427 
1428 int
xtensa_regfile_num_entries(xtensa_isa isa,xtensa_regfile rf)1429 xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
1430 {
1431   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1432   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1433   return intisa->regfiles[rf].num_entries;
1434 }
1435 
1436 
1437 
1438 /* Processor States.  */
1439 
1440 
1441 #define CHECK_STATE(INTISA,ST,ERRVAL) \
1442   do { \
1443     if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
1444       { \
1445 	xtisa_errno = xtensa_isa_bad_state; \
1446 	strcpy (xtisa_error_msg, "invalid state specifier"); \
1447 	return (ERRVAL); \
1448       } \
1449   } while (0)
1450 
1451 
1452 xtensa_state
xtensa_state_lookup(xtensa_isa isa,const char * name)1453 xtensa_state_lookup (xtensa_isa isa, const char *name)
1454 {
1455   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1456   xtensa_lookup_entry entry, *result = 0;
1457 
1458   if (!name || !*name)
1459     {
1460       xtisa_errno = xtensa_isa_bad_state;
1461       strcpy (xtisa_error_msg, "invalid state name");
1462       return XTENSA_UNDEFINED;
1463     }
1464 
1465   if (intisa->num_states != 0)
1466     {
1467       entry.key = name;
1468       result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
1469 			sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
1470     }
1471 
1472   if (!result)
1473     {
1474       xtisa_errno = xtensa_isa_bad_state;
1475       sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
1476       return XTENSA_UNDEFINED;
1477     }
1478 
1479   return result->u.state;
1480 }
1481 
1482 
1483 const char *
xtensa_state_name(xtensa_isa isa,xtensa_state st)1484 xtensa_state_name (xtensa_isa isa, xtensa_state st)
1485 {
1486   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1487   CHECK_STATE (intisa, st, NULL);
1488   return intisa->states[st].name;
1489 }
1490 
1491 
1492 int
xtensa_state_num_bits(xtensa_isa isa,xtensa_state st)1493 xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
1494 {
1495   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1496   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1497   return intisa->states[st].num_bits;
1498 }
1499 
1500 
1501 int
xtensa_state_is_exported(xtensa_isa isa,xtensa_state st)1502 xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
1503 {
1504   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1505   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1506   if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
1507     return 1;
1508   return 0;
1509 }
1510 
1511 
1512 int
xtensa_state_is_shared_or(xtensa_isa isa,xtensa_state st)1513 xtensa_state_is_shared_or (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_SHARED_OR) != 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