Back to index

cell-binutils  2.17cvs20070401
xtensa-isa.c
Go to the documentation of this file.
00001 /* Configurable Xtensa ISA support.
00002    Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
00003 
00004    This file is part of BFD, the Binary File Descriptor library.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00019 
00020 #include "bfd.h"
00021 #include "sysdep.h"
00022 #include "libbfd.h"
00023 #include "xtensa-isa.h"
00024 #include "xtensa-isa-internal.h"
00025 
00026 xtensa_isa_status xtisa_errno;
00027 char xtisa_error_msg[1024];
00028 
00029 
00030 xtensa_isa_status
00031 xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
00032 {
00033   return xtisa_errno;
00034 }
00035 
00036 
00037 char *
00038 xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
00039 {
00040   return xtisa_error_msg;
00041 }
00042 
00043 
00044 #define CHECK_ALLOC(MEM,ERRVAL) \
00045   do { \
00046     if ((MEM) == 0) \
00047       { \
00048        xtisa_errno = xtensa_isa_out_of_memory; \
00049        strcpy (xtisa_error_msg, "out of memory"); \
00050        return (ERRVAL); \
00051       } \
00052   } while (0)
00053 
00054 #define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
00055   do { \
00056     if ((MEM) == 0) \
00057       { \
00058        xtisa_errno = xtensa_isa_out_of_memory; \
00059        strcpy (xtisa_error_msg, "out of memory"); \
00060        if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
00061        if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
00062        return (ERRVAL); \
00063       } \
00064   } while (0)
00065 
00066 
00067 
00068 /* Instruction buffers.  */
00069 
00070 int
00071 xtensa_insnbuf_size (xtensa_isa isa)
00072 {
00073   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00074   return intisa->insnbuf_size;
00075 }
00076 
00077 
00078 xtensa_insnbuf
00079 xtensa_insnbuf_alloc (xtensa_isa isa)
00080 {
00081   xtensa_insnbuf result = (xtensa_insnbuf)
00082     malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
00083   CHECK_ALLOC (result, 0);
00084   return result;
00085 }
00086 
00087 
00088 void
00089 xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
00090                    xtensa_insnbuf buf)
00091 {
00092   free (buf);
00093 }
00094 
00095 
00096 /* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
00097    internal representation of a xtensa instruction word, return the index of
00098    its word and the bit index of its low order byte in the xtensa_insnbuf.  */
00099 
00100 static inline int
00101 byte_to_word_index (int byte_index)
00102 {
00103   return byte_index / sizeof (xtensa_insnbuf_word);
00104 }
00105 
00106 
00107 static inline int
00108 byte_to_bit_index (int byte_index)
00109 {
00110   return (byte_index & 0x3) * 8;
00111 }
00112 
00113 
00114 /* Copy an instruction in the 32-bit words pointed at by "insn" to
00115    characters pointed at by "cp".  This is more complicated than you
00116    might think because we want 16-bit instructions in bytes 2 & 3 for
00117    big-endian configurations.  This function allows us to specify
00118    which byte in "insn" to start with and which way to increment,
00119    allowing trivial implementation for both big- and little-endian
00120    configurations....and it seems to make pretty good code for
00121    both.  */
00122 
00123 int
00124 xtensa_insnbuf_to_chars (xtensa_isa isa,
00125                       const xtensa_insnbuf insn,
00126                       unsigned char *cp,
00127                       int num_chars)
00128 {
00129   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00130   int insn_size = xtensa_isa_maxlength (isa);
00131   int fence_post, start, increment, i, byte_count;
00132   xtensa_format fmt;
00133 
00134   if (num_chars == 0)
00135     num_chars = insn_size;
00136 
00137   if (intisa->is_big_endian)
00138     {
00139       start = insn_size - 1;
00140       increment = -1;
00141     }
00142   else
00143     {
00144       start = 0;
00145       increment = 1;
00146     }
00147 
00148   /* Find the instruction format.  Do nothing if the buffer does not contain
00149      a valid instruction since we need to know how many bytes to copy.  */
00150   fmt = xtensa_format_decode (isa, insn);
00151   if (fmt == XTENSA_UNDEFINED)
00152     return XTENSA_UNDEFINED;
00153 
00154   byte_count = xtensa_format_length (isa, fmt);
00155   if (byte_count == XTENSA_UNDEFINED)
00156     return XTENSA_UNDEFINED;
00157 
00158   if (byte_count > num_chars)
00159     {
00160       xtisa_errno = xtensa_isa_buffer_overflow;
00161       strcpy (xtisa_error_msg, "output buffer too small for instruction");
00162       return XTENSA_UNDEFINED;
00163     }
00164 
00165   fence_post = start + (byte_count * increment);
00166 
00167   for (i = start; i != fence_post; i += increment, ++cp)
00168     {
00169       int word_inx = byte_to_word_index (i);
00170       int bit_inx = byte_to_bit_index (i);
00171 
00172       *cp = (insn[word_inx] >> bit_inx) & 0xff;
00173     }
00174 
00175   return byte_count;
00176 }
00177 
00178 
00179 /* Inward conversion from byte stream to xtensa_insnbuf.  See
00180    xtensa_insnbuf_to_chars for a discussion of why this is complicated
00181    by endianness.  */
00182     
00183 void
00184 xtensa_insnbuf_from_chars (xtensa_isa isa,
00185                         xtensa_insnbuf insn,
00186                         const unsigned char *cp,
00187                         int num_chars)
00188 {
00189   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00190   int max_size, insn_size, fence_post, start, increment, i;
00191 
00192   max_size = xtensa_isa_maxlength (isa);
00193 
00194   /* Decode the instruction length so we know how many bytes to read.  */
00195   insn_size = (intisa->length_decode_fn) (cp);
00196   if (insn_size == XTENSA_UNDEFINED)
00197     {
00198       /* This should never happen when the byte stream contains a
00199         valid instruction.  Just read the maximum number of bytes....  */
00200       insn_size = max_size;
00201     }
00202 
00203   if (num_chars == 0 || num_chars > insn_size)
00204     num_chars = insn_size;
00205 
00206   if (intisa->is_big_endian)
00207     {
00208       start = max_size - 1;
00209       increment = -1;
00210     }
00211   else
00212     {
00213       start = 0;
00214       increment = 1;
00215     }
00216 
00217   fence_post = start + (num_chars * increment);
00218   memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
00219 
00220   for (i = start; i != fence_post; i += increment, ++cp)
00221     {
00222       int word_inx = byte_to_word_index (i);
00223       int bit_inx = byte_to_bit_index (i);
00224 
00225       insn[word_inx] |= (*cp & 0xff) << bit_inx;
00226     }
00227 }
00228 
00229 
00230 
00231 /* ISA information.  */
00232 
00233 extern xtensa_isa_internal xtensa_modules;
00234 
00235 xtensa_isa
00236 xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
00237 {
00238   xtensa_isa_internal *isa = &xtensa_modules;
00239   int n, is_user;
00240 
00241   /* Set up the opcode name lookup table.  */
00242   isa->opname_lookup_table =
00243     bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
00244   CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
00245   for (n = 0; n < isa->num_opcodes; n++)
00246     {
00247       isa->opname_lookup_table[n].key = isa->opcodes[n].name;
00248       isa->opname_lookup_table[n].u.opcode = n;
00249     }
00250   qsort (isa->opname_lookup_table, isa->num_opcodes,
00251         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
00252 
00253   /* Set up the state name lookup table.  */
00254   isa->state_lookup_table =
00255     bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
00256   CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
00257   for (n = 0; n < isa->num_states; n++)
00258     {
00259       isa->state_lookup_table[n].key = isa->states[n].name;
00260       isa->state_lookup_table[n].u.state = n;
00261     }
00262   qsort (isa->state_lookup_table, isa->num_states,
00263         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
00264 
00265   /* Set up the sysreg name lookup table.  */
00266   isa->sysreg_lookup_table =
00267     bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
00268   CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
00269   for (n = 0; n < isa->num_sysregs; n++)
00270     {
00271       isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
00272       isa->sysreg_lookup_table[n].u.sysreg = n;
00273     }
00274   qsort (isa->sysreg_lookup_table, isa->num_sysregs,
00275         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
00276 
00277   /* Set up the user & system sysreg number tables.  */
00278   for (is_user = 0; is_user < 2; is_user++)
00279     {
00280       isa->sysreg_table[is_user] =
00281        bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
00282                   * sizeof (xtensa_sysreg));
00283       CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
00284                          errno_p, error_msg_p);
00285 
00286       for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
00287        isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
00288     }
00289   for (n = 0; n < isa->num_sysregs; n++)
00290     {
00291       xtensa_sysreg_internal *sreg = &isa->sysregs[n];
00292       is_user = sreg->is_user;
00293 
00294       isa->sysreg_table[is_user][sreg->number] = n;
00295     }
00296 
00297   /* Set up the interface lookup table.  */
00298   isa->interface_lookup_table = 
00299     bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
00300   CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
00301                      error_msg_p);
00302   for (n = 0; n < isa->num_interfaces; n++)
00303     {
00304       isa->interface_lookup_table[n].key = isa->interfaces[n].name;
00305       isa->interface_lookup_table[n].u.intf = n;
00306     }
00307   qsort (isa->interface_lookup_table, isa->num_interfaces,
00308         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
00309 
00310   /* Set up the funcUnit lookup table.  */
00311   isa->funcUnit_lookup_table = 
00312     bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
00313   CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
00314                      error_msg_p);
00315   for (n = 0; n < isa->num_funcUnits; n++)
00316     {
00317       isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
00318       isa->funcUnit_lookup_table[n].u.fun = n;
00319     }
00320   qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
00321         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
00322 
00323   isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
00324                      sizeof (xtensa_insnbuf_word));
00325 
00326   return (xtensa_isa) isa;
00327 }
00328 
00329 
00330 void
00331 xtensa_isa_free (xtensa_isa isa)
00332 {
00333   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00334   int n;
00335 
00336   /* With this version of the code, the xtensa_isa structure is not
00337      dynamically allocated, so this function is not essential.  Free
00338      the memory allocated by xtensa_isa_init and restore the xtensa_isa
00339      structure to its initial state.  */
00340 
00341   if (intisa->opname_lookup_table)
00342     {
00343       free (intisa->opname_lookup_table);
00344       intisa->opname_lookup_table = 0;
00345     }
00346 
00347   if (intisa->state_lookup_table)
00348     {
00349       free (intisa->state_lookup_table);
00350       intisa->state_lookup_table = 0;
00351     }
00352 
00353   if (intisa->sysreg_lookup_table)
00354     {
00355       free (intisa->sysreg_lookup_table);
00356       intisa->sysreg_lookup_table = 0;
00357     }
00358   for (n = 0; n < 2; n++)
00359     {
00360       if (intisa->sysreg_table[n])
00361        {
00362          free (intisa->sysreg_table[n]);
00363          intisa->sysreg_table[n] = 0;
00364        }
00365     }
00366 
00367   if (intisa->interface_lookup_table)
00368     {
00369       free (intisa->interface_lookup_table);
00370       intisa->interface_lookup_table = 0;
00371     }
00372 
00373   if (intisa->funcUnit_lookup_table)
00374     {
00375       free (intisa->funcUnit_lookup_table);
00376       intisa->funcUnit_lookup_table = 0;
00377     }
00378 }
00379 
00380 
00381 int
00382 xtensa_isa_name_compare (const void *v1, const void *v2)
00383 {
00384   xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
00385   xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
00386 
00387   return strcasecmp (e1->key, e2->key);
00388 }
00389 
00390 
00391 int
00392 xtensa_isa_maxlength (xtensa_isa isa)
00393 {
00394   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00395   return intisa->insn_size;
00396 }
00397 
00398 
00399 int
00400 xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
00401 {
00402   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00403   return (intisa->length_decode_fn) (cp);
00404 }
00405 
00406 
00407 int
00408 xtensa_isa_num_pipe_stages (xtensa_isa isa) 
00409 {
00410   xtensa_opcode opcode;
00411   xtensa_funcUnit_use *use;
00412   int num_opcodes, num_uses;
00413   int i, stage, max_stage = XTENSA_UNDEFINED;
00414 
00415   num_opcodes = xtensa_isa_num_opcodes (isa);
00416   for (opcode = 0; opcode < num_opcodes; opcode++)
00417     {
00418       num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
00419       for (i = 0; i < num_uses; i++)
00420        {
00421          use = xtensa_opcode_funcUnit_use (isa, opcode, i);
00422          stage = use->stage;
00423          if (stage > max_stage)
00424            max_stage = stage;
00425        }
00426     }
00427 
00428   return max_stage + 1;
00429 }
00430 
00431 
00432 int
00433 xtensa_isa_num_formats (xtensa_isa isa)
00434 {
00435   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00436   return intisa->num_formats;
00437 }
00438 
00439 
00440 int
00441 xtensa_isa_num_opcodes (xtensa_isa isa)
00442 {
00443   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00444   return intisa->num_opcodes;
00445 }
00446 
00447 
00448 int
00449 xtensa_isa_num_regfiles (xtensa_isa isa)
00450 {
00451   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00452   return intisa->num_regfiles;
00453 }
00454 
00455 
00456 int
00457 xtensa_isa_num_states (xtensa_isa isa)
00458 {
00459   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00460   return intisa->num_states;
00461 }
00462 
00463 
00464 int
00465 xtensa_isa_num_sysregs (xtensa_isa isa)
00466 {
00467   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00468   return intisa->num_sysregs;
00469 }
00470 
00471 
00472 int
00473 xtensa_isa_num_interfaces (xtensa_isa isa)
00474 {
00475   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00476   return intisa->num_interfaces;
00477 }
00478 
00479 
00480 int
00481 xtensa_isa_num_funcUnits (xtensa_isa isa)
00482 {
00483   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00484   return intisa->num_funcUnits;
00485 }
00486 
00487 
00488 
00489 /* Instruction formats.  */
00490 
00491 
00492 #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
00493   do { \
00494     if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
00495       { \
00496        xtisa_errno = xtensa_isa_bad_format; \
00497        strcpy (xtisa_error_msg, "invalid format specifier"); \
00498        return (ERRVAL); \
00499       } \
00500   } while (0)
00501 
00502 
00503 #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
00504   do { \
00505     if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
00506       { \
00507        xtisa_errno = xtensa_isa_bad_slot; \
00508        strcpy (xtisa_error_msg, "invalid slot specifier"); \
00509        return (ERRVAL); \
00510       } \
00511   } while (0)
00512 
00513 
00514 const char *
00515 xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
00516 {
00517   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00518   CHECK_FORMAT (intisa, fmt, NULL);
00519   return intisa->formats[fmt].name;
00520 }
00521 
00522 
00523 xtensa_format
00524 xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
00525 {
00526   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00527   int fmt;
00528 
00529   if (!fmtname || !*fmtname)
00530     {
00531       xtisa_errno = xtensa_isa_bad_format;
00532       strcpy (xtisa_error_msg, "invalid format name");
00533       return XTENSA_UNDEFINED;
00534     }
00535 
00536   for (fmt = 0; fmt < intisa->num_formats; fmt++)
00537     {
00538       if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
00539        return fmt;
00540     }
00541   
00542   xtisa_errno = xtensa_isa_bad_format;
00543   sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
00544   return XTENSA_UNDEFINED;
00545 }
00546 
00547 
00548 xtensa_format
00549 xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
00550 {
00551   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00552   xtensa_format fmt;
00553 
00554   fmt = (intisa->format_decode_fn) (insn);
00555   if (fmt != XTENSA_UNDEFINED)
00556     return fmt;
00557 
00558   xtisa_errno = xtensa_isa_bad_format;
00559   strcpy (xtisa_error_msg, "cannot decode instruction format");
00560   return XTENSA_UNDEFINED;
00561 }
00562 
00563 
00564 int
00565 xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
00566 {
00567   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00568   CHECK_FORMAT (intisa, fmt, -1);
00569   (*intisa->formats[fmt].encode_fn) (insn);
00570   return 0;
00571 }
00572 
00573 
00574 int
00575 xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
00576 {
00577   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00578   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
00579   return intisa->formats[fmt].length;
00580 }
00581 
00582 
00583 int
00584 xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
00585 {
00586   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00587   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
00588   return intisa->formats[fmt].num_slots;
00589 }
00590 
00591 
00592 xtensa_opcode
00593 xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
00594 {
00595   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00596   int slot_id;
00597 
00598   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
00599   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
00600 
00601   slot_id = intisa->formats[fmt].slot_id[slot];
00602   return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
00603 }
00604 
00605 
00606 int
00607 xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
00608                      const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
00609 {
00610   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00611   int slot_id;
00612 
00613   CHECK_FORMAT (intisa, fmt, -1);
00614   CHECK_SLOT (intisa, fmt, slot, -1);
00615 
00616   slot_id = intisa->formats[fmt].slot_id[slot];
00617   (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
00618   return 0;
00619 }
00620 
00621 
00622 int
00623 xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
00624                      xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
00625 {
00626   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00627   int slot_id;
00628 
00629   CHECK_FORMAT (intisa, fmt, -1);
00630   CHECK_SLOT (intisa, fmt, slot, -1);
00631 
00632   slot_id = intisa->formats[fmt].slot_id[slot];
00633   (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
00634   return 0;
00635 }
00636 
00637 
00638 
00639 /* Opcode information.  */
00640 
00641 
00642 #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
00643   do { \
00644     if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
00645       { \
00646        xtisa_errno = xtensa_isa_bad_opcode; \
00647        strcpy (xtisa_error_msg, "invalid opcode specifier"); \
00648        return (ERRVAL); \
00649       } \
00650   } while (0)
00651 
00652 
00653 xtensa_opcode
00654 xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
00655 {
00656   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00657   xtensa_lookup_entry entry, *result = 0;
00658 
00659   if (!opname || !*opname)
00660     {
00661       xtisa_errno = xtensa_isa_bad_opcode;
00662       strcpy (xtisa_error_msg, "invalid opcode name");
00663       return XTENSA_UNDEFINED;
00664     }
00665 
00666   if (intisa->num_opcodes != 0)
00667     {
00668       entry.key = opname;
00669       result = bsearch (&entry, intisa->opname_lookup_table,
00670                      intisa->num_opcodes, sizeof (xtensa_lookup_entry),
00671                      xtensa_isa_name_compare);
00672     }
00673 
00674   if (!result)
00675     {
00676       xtisa_errno = xtensa_isa_bad_opcode;
00677       sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
00678       return XTENSA_UNDEFINED;
00679     }
00680 
00681   return result->u.opcode;
00682 }
00683 
00684 
00685 xtensa_opcode
00686 xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
00687                     const xtensa_insnbuf slotbuf)
00688 {
00689   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00690   int slot_id;
00691   xtensa_opcode opc;
00692 
00693   CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
00694   CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
00695 
00696   slot_id = intisa->formats[fmt].slot_id[slot];
00697 
00698   opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
00699   if (opc != XTENSA_UNDEFINED)
00700     return opc;
00701 
00702   xtisa_errno = xtensa_isa_bad_opcode;
00703   strcpy (xtisa_error_msg, "cannot decode opcode");
00704   return XTENSA_UNDEFINED;
00705 }
00706 
00707 
00708 int
00709 xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
00710                     xtensa_insnbuf slotbuf, xtensa_opcode opc)
00711 {
00712   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00713   int slot_id;
00714   xtensa_opcode_encode_fn encode_fn;
00715 
00716   CHECK_FORMAT (intisa, fmt, -1);
00717   CHECK_SLOT (intisa, fmt, slot, -1);
00718   CHECK_OPCODE (intisa, opc, -1);
00719 
00720   slot_id = intisa->formats[fmt].slot_id[slot];
00721   encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
00722   if (!encode_fn)
00723     {
00724       xtisa_errno = xtensa_isa_wrong_slot;
00725       sprintf (xtisa_error_msg,
00726               "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
00727               intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
00728       return -1;
00729     }
00730   (*encode_fn) (slotbuf);
00731   return 0;
00732 }
00733 
00734 
00735 const char *
00736 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
00737 {
00738   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00739   CHECK_OPCODE (intisa, opc, NULL);
00740   return intisa->opcodes[opc].name;
00741 }
00742 
00743 
00744 int
00745 xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
00746 {
00747   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00748   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00749   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
00750     return 1;
00751   return 0;
00752 }
00753 
00754 
00755 int
00756 xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
00757 {
00758   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00759   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00760   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
00761     return 1;
00762   return 0;
00763 }
00764 
00765 
00766 int
00767 xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
00768 {
00769   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00770   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00771   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
00772     return 1;
00773   return 0;
00774 }
00775 
00776 
00777 int
00778 xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
00779 {
00780   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00781   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00782   if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
00783     return 1;
00784   return 0;
00785 }
00786 
00787 
00788 int
00789 xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
00790 {
00791   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00792   int iclass_id;
00793 
00794   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00795   iclass_id = intisa->opcodes[opc].iclass_id;
00796   return intisa->iclasses[iclass_id].num_operands;
00797 }
00798 
00799 
00800 int
00801 xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
00802 {
00803   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00804   int iclass_id;
00805 
00806   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00807   iclass_id = intisa->opcodes[opc].iclass_id;
00808   return intisa->iclasses[iclass_id].num_stateOperands;
00809 }
00810 
00811 
00812 int
00813 xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
00814 {
00815   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00816   int iclass_id;
00817 
00818   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00819   iclass_id = intisa->opcodes[opc].iclass_id;
00820   return intisa->iclasses[iclass_id].num_interfaceOperands;
00821 }
00822 
00823 
00824 int
00825 xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
00826 {
00827   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00828   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00829   return intisa->opcodes[opc].num_funcUnit_uses;
00830 }
00831 
00832 
00833 xtensa_funcUnit_use *
00834 xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
00835 {
00836   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00837   CHECK_OPCODE (intisa, opc, NULL);
00838   if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
00839     {
00840       xtisa_errno = xtensa_isa_bad_funcUnit;
00841       sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
00842               "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
00843               intisa->opcodes[opc].num_funcUnit_uses);
00844       return NULL;
00845     }
00846   return &intisa->opcodes[opc].funcUnit_uses[u];
00847 }
00848 
00849 
00850 
00851 /* Operand information.  */
00852 
00853 
00854 #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
00855   do { \
00856     if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
00857       { \
00858        xtisa_errno = xtensa_isa_bad_operand; \
00859        sprintf (xtisa_error_msg, "invalid operand number (%d); " \
00860                "opcode \"%s\" has %d operands", (OPND), \
00861                (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
00862        return (ERRVAL); \
00863       } \
00864   } while (0)
00865 
00866 
00867 static xtensa_operand_internal *
00868 get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
00869 {
00870   xtensa_iclass_internal *iclass;
00871   int iclass_id, operand_id;
00872 
00873   CHECK_OPCODE (intisa, opc, NULL);
00874   iclass_id = intisa->opcodes[opc].iclass_id;
00875   iclass = &intisa->iclasses[iclass_id];
00876   CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
00877   operand_id = iclass->operands[opnd].u.operand_id;
00878   return &intisa->operands[operand_id];
00879 }
00880 
00881 
00882 const char *
00883 xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
00884 {
00885   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00886   xtensa_operand_internal *intop;
00887 
00888   intop = get_operand (intisa, opc, opnd);
00889   if (!intop) return NULL;
00890   return intop->name;
00891 }
00892 
00893 
00894 int
00895 xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
00896 {
00897   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00898   xtensa_iclass_internal *iclass;
00899   int iclass_id, operand_id;
00900   xtensa_operand_internal *intop;
00901 
00902   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
00903   iclass_id = intisa->opcodes[opc].iclass_id;
00904   iclass = &intisa->iclasses[iclass_id];
00905   CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
00906 
00907   /* Special case for "sout" operands.  */
00908   if (iclass->operands[opnd].inout == 's')
00909     return 0;
00910 
00911   operand_id = iclass->operands[opnd].u.operand_id;
00912   intop = &intisa->operands[operand_id];
00913 
00914   if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
00915     return 1;
00916   return 0;
00917 }
00918 
00919 
00920 char
00921 xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
00922 {
00923   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00924   xtensa_iclass_internal *iclass;
00925   int iclass_id;
00926   char inout;
00927 
00928   CHECK_OPCODE (intisa, opc, 0);
00929   iclass_id = intisa->opcodes[opc].iclass_id;
00930   iclass = &intisa->iclasses[iclass_id];
00931   CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
00932   inout = iclass->operands[opnd].inout;
00933 
00934   /* Special case for "sout" operands.  */
00935   if (inout == 's')
00936     return 'o';
00937 
00938   return inout;
00939 }
00940 
00941 
00942 int
00943 xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
00944                        xtensa_format fmt, int slot,
00945                        const xtensa_insnbuf slotbuf, uint32 *valp)
00946 {
00947   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00948   xtensa_operand_internal *intop;
00949   int slot_id;
00950   xtensa_get_field_fn get_fn;
00951 
00952   intop = get_operand (intisa, opc, opnd);
00953   if (!intop) return -1;
00954 
00955   CHECK_FORMAT (intisa, fmt, -1);
00956   CHECK_SLOT (intisa, fmt, slot, -1);
00957 
00958   slot_id = intisa->formats[fmt].slot_id[slot];
00959   if (intop->field_id == XTENSA_UNDEFINED)
00960     {
00961       xtisa_errno = xtensa_isa_no_field;
00962       strcpy (xtisa_error_msg, "implicit operand has no field");
00963       return -1;
00964     }
00965   get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
00966   if (!get_fn)
00967     {
00968       xtisa_errno = xtensa_isa_wrong_slot;
00969       sprintf (xtisa_error_msg,
00970               "operand \"%s\" does not exist in slot %d of format \"%s\"",
00971               intop->name, slot, intisa->formats[fmt].name);
00972       return -1;
00973     }
00974   *valp = (*get_fn) (slotbuf);
00975   return 0;
00976 }
00977 
00978 
00979 int
00980 xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
00981                        xtensa_format fmt, int slot,
00982                        xtensa_insnbuf slotbuf, uint32 val)
00983 {
00984   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
00985   xtensa_operand_internal *intop;
00986   int slot_id;
00987   xtensa_set_field_fn set_fn;
00988 
00989   intop = get_operand (intisa, opc, opnd);
00990   if (!intop) return -1;
00991 
00992   CHECK_FORMAT (intisa, fmt, -1);
00993   CHECK_SLOT (intisa, fmt, slot, -1);
00994 
00995   slot_id = intisa->formats[fmt].slot_id[slot];
00996   if (intop->field_id == XTENSA_UNDEFINED)
00997     {
00998       xtisa_errno = xtensa_isa_no_field;
00999       strcpy (xtisa_error_msg, "implicit operand has no field");
01000       return -1;
01001     }
01002   set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
01003   if (!set_fn)
01004     {
01005       xtisa_errno = xtensa_isa_wrong_slot;
01006       sprintf (xtisa_error_msg,
01007               "operand \"%s\" does not exist in slot %d of format \"%s\"",
01008               intop->name, slot, intisa->formats[fmt].name);
01009       return -1;
01010     }
01011   (*set_fn) (slotbuf, val);
01012   return 0;
01013 }
01014 
01015 
01016 int
01017 xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
01018                      uint32 *valp)
01019 {
01020   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01021   xtensa_operand_internal *intop;
01022   uint32 test_val, orig_val;
01023 
01024   intop = get_operand (intisa, opc, opnd);
01025   if (!intop) return -1;
01026 
01027   if (!intop->encode)
01028     {
01029       /* This is a default operand for a field.  How can we tell if the
01030         value fits in the field?  Write the value into the field,
01031         read it back, and then make sure we get the same value.  */
01032 
01033       xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01034       static xtensa_insnbuf tmpbuf = 0;
01035       int slot_id;
01036 
01037       if (!tmpbuf)
01038        {
01039          tmpbuf = xtensa_insnbuf_alloc (isa);
01040          CHECK_ALLOC (tmpbuf, -1);
01041        }
01042 
01043       /* A default operand is always associated with a field,
01044         but check just to be sure....  */
01045       if (intop->field_id == XTENSA_UNDEFINED)
01046        {
01047          xtisa_errno = xtensa_isa_internal_error;
01048          strcpy (xtisa_error_msg, "operand has no field");
01049          return -1;
01050        }
01051 
01052       /* Find some slot that includes the field.  */
01053       for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
01054        {
01055          xtensa_get_field_fn get_fn =
01056            intisa->slots[slot_id].get_field_fns[intop->field_id];
01057          xtensa_set_field_fn set_fn =
01058            intisa->slots[slot_id].set_field_fns[intop->field_id];
01059 
01060          if (get_fn && set_fn)
01061            {
01062              (*set_fn) (tmpbuf, *valp);
01063              return ((*get_fn) (tmpbuf) != *valp);
01064            }
01065        }
01066 
01067       /* Couldn't find any slot containing the field....  */
01068       xtisa_errno = xtensa_isa_no_field;
01069       strcpy (xtisa_error_msg, "field does not exist in any slot");
01070       return -1;
01071     }
01072 
01073   /* Encode the value.  In some cases, the encoding function may detect
01074      errors, but most of the time the only way to determine if the value
01075      was successfully encoded is to decode it and check if it matches
01076      the original value.  */
01077   orig_val = *valp;
01078   if ((*intop->encode) (valp) ||
01079       (test_val = *valp, (*intop->decode) (&test_val)) ||
01080       test_val != orig_val)
01081     {
01082       xtisa_errno = xtensa_isa_bad_value;
01083       sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
01084       return -1;
01085     }
01086 
01087   return 0;
01088 }
01089 
01090 
01091 int
01092 xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
01093                      uint32 *valp)
01094 {
01095   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01096   xtensa_operand_internal *intop;
01097 
01098   intop = get_operand (intisa, opc, opnd);
01099   if (!intop) return -1;
01100 
01101   /* Use identity function for "default" operands.  */
01102   if (!intop->decode)
01103     return 0;
01104 
01105   if ((*intop->decode) (valp))
01106     {
01107       xtisa_errno = xtensa_isa_bad_value;
01108       sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
01109       return -1;
01110     }
01111   return 0;
01112 }
01113 
01114 
01115 int
01116 xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
01117 {
01118   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01119   xtensa_operand_internal *intop;
01120 
01121   intop = get_operand (intisa, opc, opnd);
01122   if (!intop) return XTENSA_UNDEFINED;
01123 
01124   if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
01125     return 1;
01126   return 0;
01127 }
01128 
01129 
01130 xtensa_regfile
01131 xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
01132 {
01133   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01134   xtensa_operand_internal *intop;
01135 
01136   intop = get_operand (intisa, opc, opnd);
01137   if (!intop) return XTENSA_UNDEFINED;
01138 
01139   return intop->regfile;
01140 }
01141 
01142 
01143 int
01144 xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
01145 {
01146   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01147   xtensa_operand_internal *intop;
01148 
01149   intop = get_operand (intisa, opc, opnd);
01150   if (!intop) return XTENSA_UNDEFINED;
01151 
01152   return intop->num_regs;
01153 }
01154 
01155 
01156 int
01157 xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
01158 {
01159   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01160   xtensa_operand_internal *intop;
01161 
01162   intop = get_operand (intisa, opc, opnd);
01163   if (!intop) return XTENSA_UNDEFINED;
01164 
01165   if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
01166     return 1;
01167   return 0;
01168 }
01169 
01170 
01171 int
01172 xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
01173 {
01174   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01175   xtensa_operand_internal *intop;
01176 
01177   intop = get_operand (intisa, opc, opnd);
01178   if (!intop) return XTENSA_UNDEFINED;
01179 
01180   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
01181     return 1;
01182   return 0;
01183 }
01184 
01185 
01186 int
01187 xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
01188                       uint32 *valp, uint32 pc)
01189 {
01190   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01191   xtensa_operand_internal *intop;
01192 
01193   intop = get_operand (intisa, opc, opnd);
01194   if (!intop) return -1;
01195 
01196   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
01197     return 0;
01198 
01199   if (!intop->do_reloc)
01200     {
01201       xtisa_errno = xtensa_isa_internal_error;
01202       strcpy (xtisa_error_msg, "operand missing do_reloc function");
01203       return -1;
01204     }
01205 
01206   if ((*intop->do_reloc) (valp, pc))
01207     {
01208       xtisa_errno = xtensa_isa_bad_value;
01209       sprintf (xtisa_error_msg,
01210               "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
01211       return -1;
01212     }
01213 
01214   return 0;
01215 }
01216 
01217 
01218 int
01219 xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
01220                         uint32 *valp, uint32 pc)
01221 {
01222   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01223   xtensa_operand_internal *intop;
01224 
01225   intop = get_operand (intisa, opc, opnd);
01226   if (!intop) return -1;
01227 
01228   if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
01229     return 0;
01230 
01231   if (!intop->undo_reloc)
01232     {
01233       xtisa_errno = xtensa_isa_internal_error;
01234       strcpy (xtisa_error_msg, "operand missing undo_reloc function");
01235       return -1;
01236     }
01237 
01238   if ((*intop->undo_reloc) (valp, pc))
01239     {
01240       xtisa_errno = xtensa_isa_bad_value;
01241       sprintf (xtisa_error_msg,
01242               "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
01243       return -1;
01244     }
01245 
01246   return 0;
01247 }
01248 
01249 
01250 
01251 /* State Operands.  */
01252 
01253 
01254 #define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
01255   do { \
01256     if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
01257       { \
01258        xtisa_errno = xtensa_isa_bad_operand; \
01259        sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
01260                "opcode \"%s\" has %d state operands", (STOP), \
01261                (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
01262        return (ERRVAL); \
01263       } \
01264   } while (0)
01265 
01266 
01267 xtensa_state
01268 xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
01269 {
01270   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01271   xtensa_iclass_internal *iclass;
01272   int iclass_id;
01273 
01274   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
01275   iclass_id = intisa->opcodes[opc].iclass_id;
01276   iclass = &intisa->iclasses[iclass_id];
01277   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
01278   return iclass->stateOperands[stOp].u.state;
01279 }
01280 
01281 
01282 char
01283 xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
01284 {
01285   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01286   xtensa_iclass_internal *iclass;
01287   int iclass_id;
01288 
01289   CHECK_OPCODE (intisa, opc, 0);
01290   iclass_id = intisa->opcodes[opc].iclass_id;
01291   iclass = &intisa->iclasses[iclass_id];
01292   CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
01293   return iclass->stateOperands[stOp].inout;
01294 }
01295 
01296 
01297 
01298 /* Interface Operands.  */
01299 
01300 
01301 #define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
01302   do { \
01303     if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
01304       { \
01305        xtisa_errno = xtensa_isa_bad_operand; \
01306        sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
01307                "opcode \"%s\" has %d interface operands", (IFOP), \
01308                (INTISA)->opcodes[(OPC)].name, \
01309                (ICLASS)->num_interfaceOperands); \
01310        return (ERRVAL); \
01311       } \
01312   } while (0)
01313 
01314 
01315 xtensa_interface
01316 xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
01317                                int ifOp)
01318 {
01319   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01320   xtensa_iclass_internal *iclass;
01321   int iclass_id;
01322 
01323   CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
01324   iclass_id = intisa->opcodes[opc].iclass_id;
01325   iclass = &intisa->iclasses[iclass_id];
01326   CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
01327   return iclass->interfaceOperands[ifOp];
01328 }
01329 
01330 
01331 
01332 /* Register Files.  */
01333 
01334 
01335 #define CHECK_REGFILE(INTISA,RF,ERRVAL) \
01336   do { \
01337     if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
01338       { \
01339        xtisa_errno = xtensa_isa_bad_regfile; \
01340        strcpy (xtisa_error_msg, "invalid regfile specifier"); \
01341        return (ERRVAL); \
01342       } \
01343   } while (0)
01344 
01345 
01346 xtensa_regfile
01347 xtensa_regfile_lookup (xtensa_isa isa, const char *name)
01348 {
01349   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01350   int n;
01351 
01352   if (!name || !*name)
01353     {
01354       xtisa_errno = xtensa_isa_bad_regfile;
01355       strcpy (xtisa_error_msg, "invalid regfile name");
01356       return XTENSA_UNDEFINED;
01357     }
01358 
01359   /* The expected number of regfiles is small; use a linear search.  */
01360   for (n = 0; n < intisa->num_regfiles; n++)
01361     {
01362       if (!strcmp (intisa->regfiles[n].name, name))
01363        return n;
01364     }
01365 
01366   xtisa_errno = xtensa_isa_bad_regfile;
01367   sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
01368   return XTENSA_UNDEFINED;
01369 }
01370 
01371 
01372 xtensa_regfile
01373 xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
01374 {
01375   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01376   int n;
01377 
01378   if (!shortname || !*shortname)
01379     {
01380       xtisa_errno = xtensa_isa_bad_regfile;
01381       strcpy (xtisa_error_msg, "invalid regfile shortname");
01382       return XTENSA_UNDEFINED;
01383     }
01384 
01385   /* The expected number of regfiles is small; use a linear search.  */
01386   for (n = 0; n < intisa->num_regfiles; n++)
01387     {
01388       /* Ignore regfile views since they always have the same shortnames
01389         as their parents.  */
01390       if (intisa->regfiles[n].parent != n)
01391        continue;
01392       if (!strcmp (intisa->regfiles[n].shortname, shortname))
01393        return n;
01394     }
01395 
01396   xtisa_errno = xtensa_isa_bad_regfile;
01397   sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
01398           shortname);
01399   return XTENSA_UNDEFINED;
01400 }
01401 
01402 
01403 const char *
01404 xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
01405 {
01406   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01407   CHECK_REGFILE (intisa, rf, NULL);
01408   return intisa->regfiles[rf].name;
01409 }
01410 
01411 
01412 const char *
01413 xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
01414 {
01415   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01416   CHECK_REGFILE (intisa, rf, NULL);
01417   return intisa->regfiles[rf].shortname;
01418 }
01419 
01420 
01421 xtensa_regfile
01422 xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
01423 {
01424   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01425   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
01426   return intisa->regfiles[rf].parent;
01427 }
01428 
01429 
01430 int
01431 xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
01432 {
01433   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01434   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
01435   return intisa->regfiles[rf].num_bits;
01436 }
01437 
01438 
01439 int
01440 xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
01441 {
01442   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01443   CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
01444   return intisa->regfiles[rf].num_entries;
01445 }
01446 
01447 
01448 
01449 /* Processor States.  */
01450 
01451 
01452 #define CHECK_STATE(INTISA,ST,ERRVAL) \
01453   do { \
01454     if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
01455       { \
01456        xtisa_errno = xtensa_isa_bad_state; \
01457        strcpy (xtisa_error_msg, "invalid state specifier"); \
01458        return (ERRVAL); \
01459       } \
01460   } while (0)
01461 
01462 
01463 xtensa_state
01464 xtensa_state_lookup (xtensa_isa isa, const char *name)
01465 {
01466   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01467   xtensa_lookup_entry entry, *result = 0;
01468 
01469   if (!name || !*name)
01470     {
01471       xtisa_errno = xtensa_isa_bad_state;
01472       strcpy (xtisa_error_msg, "invalid state name");
01473       return XTENSA_UNDEFINED;
01474     }
01475 
01476   if (intisa->num_states != 0)
01477     {
01478       entry.key = name;
01479       result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
01480                      sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
01481     }
01482 
01483   if (!result)
01484     {
01485       xtisa_errno = xtensa_isa_bad_state;
01486       sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
01487       return XTENSA_UNDEFINED;
01488     }
01489 
01490   return result->u.state;
01491 }
01492 
01493 
01494 const char *
01495 xtensa_state_name (xtensa_isa isa, xtensa_state st)
01496 {
01497   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01498   CHECK_STATE (intisa, st, NULL);
01499   return intisa->states[st].name;
01500 }
01501 
01502 
01503 int
01504 xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
01505 {
01506   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01507   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
01508   return intisa->states[st].num_bits;
01509 }
01510 
01511 
01512 int
01513 xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
01514 {
01515   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01516   CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
01517   if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
01518     return 1;
01519   return 0;
01520 }
01521 
01522 
01523 
01524 /* Sysregs.  */
01525 
01526 
01527 #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
01528   do { \
01529     if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
01530       { \
01531        xtisa_errno = xtensa_isa_bad_sysreg; \
01532        strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
01533        return (ERRVAL); \
01534       } \
01535   } while (0)
01536 
01537 
01538 xtensa_sysreg
01539 xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
01540 {
01541   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01542 
01543   if (is_user != 0)
01544     is_user = 1;
01545 
01546   if (num < 0 || num > intisa->max_sysreg_num[is_user]
01547       || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
01548     {
01549       xtisa_errno = xtensa_isa_bad_sysreg;
01550       strcpy (xtisa_error_msg, "sysreg not recognized");
01551       return XTENSA_UNDEFINED;
01552     }
01553 
01554   return intisa->sysreg_table[is_user][num];
01555 }
01556 
01557 
01558 xtensa_sysreg
01559 xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
01560 {
01561   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01562   xtensa_lookup_entry entry, *result = 0;
01563 
01564   if (!name || !*name)
01565     {
01566       xtisa_errno = xtensa_isa_bad_sysreg;
01567       strcpy (xtisa_error_msg, "invalid sysreg name");
01568       return XTENSA_UNDEFINED;
01569     }
01570 
01571   if (intisa->num_sysregs != 0)
01572     {
01573       entry.key = name;
01574       result = bsearch (&entry, intisa->sysreg_lookup_table,
01575                      intisa->num_sysregs, sizeof (xtensa_lookup_entry),
01576                      xtensa_isa_name_compare);
01577     }
01578 
01579   if (!result)
01580     {
01581       xtisa_errno = xtensa_isa_bad_sysreg;
01582       sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
01583       return XTENSA_UNDEFINED;
01584     }
01585 
01586   return result->u.sysreg;
01587 }
01588 
01589 
01590 const char *
01591 xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
01592 {
01593   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01594   CHECK_SYSREG (intisa, sysreg, NULL);
01595   return intisa->sysregs[sysreg].name;
01596 }
01597 
01598 
01599 int
01600 xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
01601 {
01602   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01603   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
01604   return intisa->sysregs[sysreg].number;
01605 }
01606 
01607 
01608 int
01609 xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
01610 {
01611   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01612   CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
01613   if (intisa->sysregs[sysreg].is_user)
01614     return 1;
01615   return 0;
01616 }
01617 
01618 
01619 
01620 /* Interfaces.  */
01621 
01622 
01623 #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
01624   do { \
01625     if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
01626       { \
01627        xtisa_errno = xtensa_isa_bad_interface; \
01628        strcpy (xtisa_error_msg, "invalid interface specifier"); \
01629        return (ERRVAL); \
01630       } \
01631   } while (0)
01632 
01633 
01634 xtensa_interface
01635 xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
01636 {
01637   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01638   xtensa_lookup_entry entry, *result = 0;
01639 
01640   if (!ifname || !*ifname)
01641     {
01642       xtisa_errno = xtensa_isa_bad_interface;
01643       strcpy (xtisa_error_msg, "invalid interface name");
01644       return XTENSA_UNDEFINED;
01645     }
01646 
01647   if (intisa->num_interfaces != 0)
01648     {
01649       entry.key = ifname;
01650       result = bsearch (&entry, intisa->interface_lookup_table,
01651                      intisa->num_interfaces, sizeof (xtensa_lookup_entry),
01652                      xtensa_isa_name_compare);
01653     }
01654 
01655   if (!result)
01656     {
01657       xtisa_errno = xtensa_isa_bad_interface;
01658       sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
01659       return XTENSA_UNDEFINED;
01660     }
01661 
01662   return result->u.intf;
01663 }
01664 
01665 
01666 const char *
01667 xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
01668 {
01669   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01670   CHECK_INTERFACE (intisa, intf, NULL);
01671   return intisa->interfaces[intf].name;
01672 }
01673 
01674 
01675 int
01676 xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
01677 {
01678   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01679   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
01680   return intisa->interfaces[intf].num_bits;
01681 }
01682 
01683 
01684 char
01685 xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
01686 {
01687   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01688   CHECK_INTERFACE (intisa, intf, 0);
01689   return intisa->interfaces[intf].inout;
01690 }
01691 
01692 
01693 int
01694 xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
01695 {
01696   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01697   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
01698   if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
01699     return 1;
01700   return 0;
01701 }
01702 
01703 
01704 int
01705 xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
01706 {
01707   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01708   CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
01709   return intisa->interfaces[intf].class_id;
01710 }
01711 
01712 
01713 
01714 /* Functional Units.  */
01715 
01716 
01717 #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
01718   do { \
01719     if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
01720       { \
01721        xtisa_errno = xtensa_isa_bad_funcUnit; \
01722        strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
01723        return (ERRVAL); \
01724       } \
01725   } while (0)
01726 
01727 
01728 xtensa_funcUnit
01729 xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
01730 {
01731   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01732   xtensa_lookup_entry entry, *result = 0;
01733 
01734   if (!fname || !*fname)
01735     {
01736       xtisa_errno = xtensa_isa_bad_funcUnit;
01737       strcpy (xtisa_error_msg, "invalid functional unit name");
01738       return XTENSA_UNDEFINED;
01739     }
01740 
01741   if (intisa->num_funcUnits != 0)
01742     {
01743       entry.key = fname;
01744       result = bsearch (&entry, intisa->funcUnit_lookup_table,
01745                      intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
01746                      xtensa_isa_name_compare);
01747     }
01748 
01749   if (!result)
01750     {
01751       xtisa_errno = xtensa_isa_bad_funcUnit;
01752       sprintf (xtisa_error_msg,
01753               "functional unit \"%s\" not recognized", fname);
01754       return XTENSA_UNDEFINED;
01755     }
01756 
01757   return result->u.fun;
01758 }
01759 
01760 
01761 const char *
01762 xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
01763 {
01764   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01765   CHECK_FUNCUNIT (intisa, fun, NULL);
01766   return intisa->funcUnits[fun].name;
01767 }
01768 
01769 
01770 int
01771 xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
01772 {
01773   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
01774   CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
01775   return intisa->funcUnits[fun].num_copies;
01776 }
01777