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