1/* TI C6X disassembler. 2 Copyright (C) 2010-2017 Free Software Foundation, Inc. 3 Contributed by Joseph Myers <joseph@codesourcery.com> 4 Bernd Schmidt <bernds@codesourcery.com> 5 6 This file is part of libopcodes. 7 8 This library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 It is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23#include "sysdep.h" 24#include "dis-asm.h" 25#include "opcode/tic6x.h" 26#include "libiberty.h" 27 28/* Define the instruction format table. */ 29const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max] = 30 { 31#define FMT(name, num_bits, cst_bits, mask, fields) \ 32 { num_bits, cst_bits, mask, fields }, 33#include "opcode/tic6x-insn-formats.h" 34#undef FMT 35 }; 36 37/* Define the control register table. */ 38const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max] = 39 { 40#define CTRL(name, isa, rw, crlo, crhi_mask) \ 41 { \ 42 STRINGX(name), \ 43 CONCAT2(TIC6X_INSN_,isa), \ 44 CONCAT2(tic6x_rw_,rw), \ 45 crlo, \ 46 crhi_mask \ 47 }, 48#include "opcode/tic6x-control-registers.h" 49#undef CTRL 50 }; 51 52/* Define the opcode table. */ 53const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max] = 54 { 55#define INSNU(name, func_unit, format, type, isa, flags, fixed, ops, var) \ 56 { \ 57 STRINGX(name), \ 58 CONCAT2(tic6x_func_unit_,func_unit), \ 59 CONCAT3(tic6x_insn_format,_,format), \ 60 CONCAT2(tic6x_pipeline_,type), \ 61 CONCAT2(TIC6X_INSN_,isa), \ 62 flags, \ 63 fixed, \ 64 ops, \ 65 var \ 66 }, 67#define INSNUE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \ 68 { \ 69 STRINGX(name), \ 70 CONCAT2(tic6x_func_unit_,func_unit), \ 71 CONCAT3(tic6x_insn_format,_,format), \ 72 CONCAT2(tic6x_pipeline_,type), \ 73 CONCAT2(TIC6X_INSN_,isa), \ 74 flags, \ 75 fixed, \ 76 ops, \ 77 var \ 78 }, 79#define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \ 80 { \ 81 STRINGX(name), \ 82 CONCAT2(tic6x_func_unit_,func_unit), \ 83 CONCAT4(tic6x_insn_format_,func_unit,_,format), \ 84 CONCAT2(tic6x_pipeline_,type), \ 85 CONCAT2(TIC6X_INSN_,isa), \ 86 flags, \ 87 fixed, \ 88 ops, \ 89 var \ 90 }, 91#define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \ 92 { \ 93 STRINGX(name), \ 94 CONCAT2(tic6x_func_unit_,func_unit), \ 95 CONCAT4(tic6x_insn_format_,func_unit,_,format), \ 96 CONCAT2(tic6x_pipeline_,type), \ 97 CONCAT2(TIC6X_INSN_,isa), \ 98 flags, \ 99 fixed, \ 100 ops, \ 101 var \ 102 }, 103#include "opcode/tic6x-opcode-table.h" 104#undef INSN 105#undef INSNE 106#undef INSNU 107#undef INSNUE 108 }; 109 110/* If instruction format FMT has a field FIELD, return a pointer to 111 the description of that field; otherwise return NULL. */ 112 113const tic6x_insn_field * 114tic6x_field_from_fmt (const tic6x_insn_format *fmt, tic6x_insn_field_id field) 115{ 116 unsigned int f; 117 118 for (f = 0; f < fmt->num_fields; f++) 119 if (fmt->fields[f].field_id == field) 120 return &fmt->fields[f]; 121 122 return NULL; 123} 124 125/* Extract the field width. */ 126 127static unsigned int 128tic6x_field_width (const tic6x_insn_field *field) 129{ 130 unsigned int i; 131 unsigned int width = 0; 132 133 if (!field->num_bitfields) 134 return field->bitfields[0].width; 135 136 for (i = 0 ; i < field->num_bitfields ; i++) 137 width += field->bitfields[i].width; 138 139 return width; 140} 141 142/* Extract the bits corresponding to FIELD from OPCODE. */ 143 144static unsigned int 145tic6x_field_bits (unsigned int opcode, const tic6x_insn_field *field) 146{ 147 unsigned int i; 148 unsigned int val = 0; 149 150 if (!field->num_bitfields) 151 return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1); 152 153 for (i = 0 ; i < field->num_bitfields ; i++) 154 val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1)) 155 << field->bitfields[i].pos; 156 157 return val; 158} 159 160/* Extract a 32-bit value read from the instruction stream. */ 161 162static unsigned int 163tic6x_extract_32 (unsigned char *p, struct disassemble_info *info) 164{ 165 if (info->endian == BFD_ENDIAN_LITTLE) 166 return (p[0]) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 167 else 168 return (p[3]) | (p[2] << 8) | (p[1] << 16) | (p[0] << 24); 169} 170 171/* Extract a 16-bit value read from the instruction stream. */ 172 173static unsigned int 174tic6x_extract_16 (unsigned char *p, tic6x_fetch_packet_header *header, 175 struct disassemble_info *info) 176{ 177 unsigned int op16; 178 179 if (info->endian == BFD_ENDIAN_LITTLE) 180 op16 = (p[0]) | (p[1] << 8); 181 else 182 op16 = (p[1]) | (p[0] << 8); 183 op16 |= (header->sat << TIC6X_COMPACT_SAT_POS); 184 op16 |= (header->br << TIC6X_COMPACT_BR_POS); 185 op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS); 186 return op16; 187} 188 189/* FP points to a fetch packet. Return whether it is header-based; if 190 it is, fill in HEADER. */ 191 192static bfd_boolean 193tic6x_check_fetch_packet_header (unsigned char *fp, 194 tic6x_fetch_packet_header *header, 195 struct disassemble_info *info) 196{ 197 int i; 198 199 header->header = tic6x_extract_32 (fp + 28, info); 200 201 if ((header->header & 0xf0000000) != 0xe0000000) 202 { 203 header->prot = 0; 204 header->rs = 0; 205 header->dsz = 0; 206 header->br = 0; 207 header->sat = 0; 208 for (i = 0; i < 7; i++) 209 header->word_compact[i] = FALSE; 210 for (i = 0; i < 14; i++) 211 header->p_bits[i] = FALSE; 212 return FALSE; 213 } 214 215 for (i = 0; i < 7; i++) 216 header->word_compact[i] 217 = (header->header & (1u << (21 + i))) ? TRUE : FALSE; 218 219 header->prot = (header->header & (1u << 20)) ? TRUE : FALSE; 220 header->rs = (header->header & (1u << 19)) ? TRUE : FALSE; 221 header->dsz = (header->header >> 16) & 0x7; 222 header->br = (header->header & (1u << 15)) ? TRUE : FALSE; 223 header->sat = (header->header & (1u << 14)) ? TRUE : FALSE; 224 225 for (i = 0; i < 14; i++) 226 header->p_bits[i] 227 = (header->header & (1u << i)) ? TRUE : FALSE; 228 229 return TRUE; 230} 231 232/* Disassemble the instruction at ADDR and print it using 233 INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes 234 consumed. */ 235 236int 237print_insn_tic6x (bfd_vma addr, struct disassemble_info *info) 238{ 239 int status; 240 bfd_vma fp_addr; 241 bfd_vma fp_offset; 242 unsigned char fp[32]; 243 unsigned int opcode; 244 tic6x_opcode_id opcode_id; 245 bfd_boolean fetch_packet_header_based; 246 tic6x_fetch_packet_header header; 247 unsigned int num_bits; 248 bfd_boolean bad_offset = FALSE; 249 250 fp_offset = addr & 0x1f; 251 fp_addr = addr - fp_offset; 252 /* Read in a block of instructions. Since there might be a 253 symbol in the middle of this block, disable stop_vma. */ 254 info->stop_vma = 0; 255 status = info->read_memory_func (fp_addr, fp, 32, info); 256 if (status) 257 { 258 info->memory_error_func (status, addr, info); 259 return -1; 260 } 261 262 fetch_packet_header_based 263 = tic6x_check_fetch_packet_header (fp, &header, info); 264 if (fetch_packet_header_based) 265 { 266 if (fp_offset & 0x1) 267 bad_offset = TRUE; 268 if ((fp_offset & 0x3) && (fp_offset >= 28 269 || !header.word_compact[fp_offset >> 2])) 270 bad_offset = TRUE; 271 if (fp_offset == 28) 272 { 273 info->bytes_per_chunk = 4; 274 info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>", 275 header.header); 276 return 4; 277 } 278 num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32); 279 } 280 else 281 { 282 num_bits = 32; 283 if (fp_offset & 0x3) 284 bad_offset = TRUE; 285 } 286 287 if (bad_offset) 288 { 289 info->bytes_per_chunk = 1; 290 info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]); 291 return 1; 292 } 293 294 if (num_bits == 16) 295 { 296 /* The least-significant part of a 32-bit word comes logically 297 before the most-significant part. For big-endian, follow the 298 TI assembler in showing instructions in logical order by 299 pretending that the two halves of the word are in opposite 300 locations to where they actually are. */ 301 if (info->endian == BFD_ENDIAN_LITTLE) 302 opcode = tic6x_extract_16 (fp + fp_offset, &header, info); 303 else 304 opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info); 305 } 306 else 307 opcode = tic6x_extract_32 (fp + fp_offset, info); 308 309 for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++) 310 { 311 const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id]; 312 const tic6x_insn_format *const fmt 313 = &tic6x_insn_format_table[opc->format]; 314 const tic6x_insn_field *creg_field; 315 bfd_boolean p_bit; 316 const char *parallel; 317 const char *cond = ""; 318 const char *func_unit; 319 char func_unit_buf[7]; 320 unsigned int func_unit_side = 0; 321 unsigned int func_unit_data_side = 0; 322 unsigned int func_unit_cross = 0; 323 unsigned int t_val = 0; 324 /* The maximum length of the text of a non-PC-relative operand 325 is 24 bytes (SPMASK masking all eight functional units, with 326 separating commas and trailing NUL). */ 327 char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } }; 328 bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 }; 329 bfd_boolean operands_text[TIC6X_MAX_OPERANDS] = { FALSE }; 330 bfd_boolean operands_pcrel[TIC6X_MAX_OPERANDS] = { FALSE }; 331 unsigned int fix; 332 unsigned int num_operands; 333 unsigned int op_num; 334 bfd_boolean fixed_ok; 335 bfd_boolean operands_ok; 336 bfd_boolean have_t = FALSE; 337 338 if (opc->flags & TIC6X_FLAG_MACRO) 339 continue; 340 if (fmt->num_bits != num_bits) 341 continue; 342 if ((opcode & fmt->mask) != fmt->cst_bits) 343 continue; 344 345 /* If the format has a creg field, it is only a candidate for a 346 match if the creg and z fields have values indicating a valid 347 condition; reserved values indicate either an instruction 348 format without a creg field, or an invalid instruction. */ 349 creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg); 350 if (creg_field) 351 { 352 const tic6x_insn_field *z_field; 353 unsigned int creg_value, z_value; 354 static const char *const conds[8][2] = 355 { 356 { "", NULL }, 357 { "[b0] ", "[!b0] " }, 358 { "[b1] ", "[!b1] " }, 359 { "[b2] ", "[!b2] " }, 360 { "[a1] ", "[!a1] " }, 361 { "[a2] ", "[!a2] " }, 362 { "[a0] ", "[!a0] " }, 363 { NULL, NULL } 364 }; 365 366 /* A creg field is not meaningful without a z field, so if 367 the z field is not present this is an error in the format 368 table. */ 369 z_field = tic6x_field_from_fmt (fmt, tic6x_field_z); 370 if (!z_field) 371 { 372 printf ("*** opcode %x: missing z field", opcode); 373 abort (); 374 } 375 376 creg_value = tic6x_field_bits (opcode, creg_field); 377 z_value = tic6x_field_bits (opcode, z_field); 378 cond = conds[creg_value][z_value]; 379 if (cond == NULL) 380 continue; 381 } 382 383 if (opc->flags & TIC6X_FLAG_INSN16_SPRED) 384 { 385 const tic6x_insn_field *cc_field; 386 unsigned int s_value = 0; 387 unsigned int z_value = 0; 388 bfd_boolean cond_known = FALSE; 389 static const char *const conds[2][2] = 390 { 391 { "[a0] ", "[!a0] " }, 392 { "[b0] ", "[!b0] " } 393 }; 394 395 cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc); 396 397 if (cc_field) 398 { 399 unsigned int cc_value; 400 401 cc_value = tic6x_field_bits (opcode, cc_field); 402 s_value = (cc_value & 0x2) >> 1; 403 z_value = (cc_value & 0x1); 404 cond_known = TRUE; 405 } 406 else 407 { 408 const tic6x_insn_field *z_field; 409 const tic6x_insn_field *s_field; 410 411 s_field = tic6x_field_from_fmt (fmt, tic6x_field_s); 412 413 if (!s_field) 414 { 415 printf ("opcode %x: missing compact insn predicate register field (s field)\n", 416 opcode); 417 abort (); 418 } 419 s_value = tic6x_field_bits (opcode, s_field); 420 z_field = tic6x_field_from_fmt (fmt, tic6x_field_z); 421 if (!z_field) 422 { 423 printf ("opcode %x: missing compact insn predicate z_value (z field)\n", opcode); 424 abort (); 425 } 426 427 z_value = tic6x_field_bits (opcode, z_field); 428 cond_known = TRUE; 429 } 430 431 if (!cond_known) 432 { 433 printf ("opcode %x: unspecified ompact insn predicate\n", opcode); 434 abort (); 435 } 436 cond = conds[s_value][z_value]; 437 } 438 439 /* All fixed fields must have matching values; all fields with 440 restricted ranges must have values within those ranges. */ 441 fixed_ok = TRUE; 442 for (fix = 0; fix < opc->num_fixed_fields; fix++) 443 { 444 unsigned int field_bits; 445 const tic6x_insn_field *const field 446 = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id); 447 448 if (!field) 449 { 450 printf ("opcode %x: missing field #%d for FIX #%d\n", 451 opcode, opc->fixed_fields[fix].field_id, fix); 452 abort (); 453 } 454 455 field_bits = tic6x_field_bits (opcode, field); 456 if (field_bits < opc->fixed_fields[fix].min_val 457 || field_bits > opc->fixed_fields[fix].max_val) 458 { 459 fixed_ok = FALSE; 460 break; 461 } 462 } 463 if (!fixed_ok) 464 continue; 465 466 /* The instruction matches. */ 467 468 /* The p-bit indicates whether this instruction is in parallel 469 with the *next* instruction, whereas the parallel bars 470 indicate the instruction is in parallel with the *previous* 471 instruction. Thus, we must find the p-bit for the previous 472 instruction. */ 473 if (num_bits == 16 && (fp_offset & 0x2) == 2) 474 { 475 /* This is the logically second (most significant; second in 476 fp_offset terms because fp_offset relates to logical not 477 physical addresses) instruction of a compact pair; find 478 the p-bit for the first (least significant). */ 479 p_bit = header.p_bits[(fp_offset >> 2) << 1]; 480 } 481 else if (fp_offset >= 4) 482 { 483 /* Find the last instruction of the previous word in this 484 fetch packet. For compact instructions, this is the most 485 significant 16 bits. */ 486 if (fetch_packet_header_based 487 && header.word_compact[(fp_offset >> 2) - 1]) 488 p_bit = header.p_bits[(fp_offset >> 1) - 1]; 489 else 490 { 491 unsigned int prev_opcode 492 = tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info); 493 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE; 494 } 495 } 496 else 497 { 498 /* Find the last instruction of the previous fetch 499 packet. */ 500 unsigned char fp_prev[32]; 501 502 status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info); 503 if (status) 504 /* No previous instruction to be parallel with. */ 505 p_bit = FALSE; 506 else 507 { 508 bfd_boolean prev_header_based; 509 tic6x_fetch_packet_header prev_header; 510 511 prev_header_based 512 = tic6x_check_fetch_packet_header (fp_prev, &prev_header, info); 513 if (prev_header_based && prev_header.word_compact[6]) 514 p_bit = prev_header.p_bits[13]; 515 else 516 { 517 unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28, 518 info); 519 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE; 520 } 521 } 522 } 523 parallel = p_bit ? "|| " : ""; 524 525 if (opc->func_unit == tic6x_func_unit_nfu) 526 func_unit = ""; 527 else 528 { 529 unsigned int fld_num; 530 char func_unit_char; 531 const char *data_str; 532 bfd_boolean have_areg = FALSE; 533 bfd_boolean have_cross = FALSE; 534 535 func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0; 536 func_unit_cross = 0; 537 func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0; 538 539 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++) 540 { 541 const tic6x_coding_field *const enc = &opc->variable_fields[fld_num]; 542 const tic6x_insn_field *field; 543 unsigned int fld_val; 544 545 field = tic6x_field_from_fmt (fmt, enc->field_id); 546 547 if (!field) 548 { 549 printf ("opcode %x: could not retrieve field (field_id:%d)\n", 550 opcode, fld_num); 551 abort (); 552 } 553 554 fld_val = tic6x_field_bits (opcode, field); 555 556 switch (enc->coding_method) 557 { 558 case tic6x_coding_fu: 559 /* The side must be specified exactly once. */ 560 if (func_unit_side) 561 { 562 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n", 563 opcode, fld_num); 564 abort (); 565 } 566 func_unit_side = (fld_val ? 2 : 1); 567 break; 568 569 case tic6x_coding_data_fu: 570 /* The data side must be specified exactly once. */ 571 if (func_unit_data_side) 572 { 573 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n", 574 opcode, fld_num); 575 abort (); 576 } 577 func_unit_data_side = (fld_val ? 2 : 1); 578 break; 579 580 case tic6x_coding_xpath: 581 /* Cross path use must be specified exactly 582 once. */ 583 if (have_cross) 584 { 585 printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n", 586 opcode, fld_num); 587 abort (); 588 } 589 have_cross = TRUE; 590 func_unit_cross = fld_val; 591 break; 592 593 case tic6x_coding_rside: 594 /* If the format has a t field, use it for src/dst register side. */ 595 have_t = TRUE; 596 t_val = fld_val; 597 func_unit_data_side = (t_val ? 2 : 1); 598 break; 599 600 case tic6x_coding_areg: 601 have_areg = TRUE; 602 break; 603 604 default: 605 /* Don't relate to functional units. */ 606 break; 607 } 608 } 609 610 /* The side of the functional unit used must now have been 611 determined either from the flags or from an instruction 612 field. */ 613 if (func_unit_side != 1 && func_unit_side != 2) 614 { 615 printf ("opcode %x: func_unit_side is not encoded!\n", opcode); 616 abort (); 617 } 618 619 /* Cross paths are not applicable when sides are specified 620 for both address and data paths. */ 621 if (func_unit_data_side && have_cross) 622 { 623 printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n", 624 opcode); 625 abort (); 626 } 627 628 /* Separate address and data paths are only applicable for 629 the D unit. */ 630 if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d) 631 { 632 printf ("opcode %x: separate address and data paths only applicable for D unit!\n", 633 opcode); 634 abort (); 635 } 636 637 /* If an address register is being used but in ADDA rather 638 than a load or store, it uses a cross path for side-A 639 instructions, and the cross path use is not specified by 640 an instruction field. */ 641 if (have_areg && !func_unit_data_side) 642 { 643 if (have_cross) 644 { 645 printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode); 646 abort (); 647 } 648 func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE); 649 } 650 651 switch (opc->func_unit) 652 { 653 case tic6x_func_unit_d: 654 func_unit_char = 'D'; 655 break; 656 657 case tic6x_func_unit_l: 658 func_unit_char = 'L'; 659 break; 660 661 case tic6x_func_unit_m: 662 func_unit_char = 'M'; 663 break; 664 665 case tic6x_func_unit_s: 666 func_unit_char = 'S'; 667 break; 668 669 default: 670 printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit); 671 abort (); 672 } 673 674 switch (func_unit_data_side) 675 { 676 case 0: 677 data_str = ""; 678 break; 679 680 case 1: 681 data_str = "T1"; 682 break; 683 684 case 2: 685 data_str = "T2"; 686 break; 687 688 default: 689 printf ("opcode %x: illegal data func_unit specifier %d\n", 690 opcode, func_unit_data_side); 691 abort (); 692 } 693 694 if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1) 695 func_unit_cross = 1; 696 697 snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char, 698 func_unit_side, (func_unit_cross ? "X" : ""), data_str); 699 func_unit = func_unit_buf; 700 } 701 702 /* For each operand there must be one or more fields set based 703 on that operand, that can together be used to derive the 704 operand value. */ 705 operands_ok = TRUE; 706 num_operands = opc->num_operands; 707 for (op_num = 0; op_num < num_operands; op_num++) 708 { 709 unsigned int fld_num; 710 unsigned int mem_base_reg = 0; 711 bfd_boolean mem_base_reg_known = FALSE; 712 bfd_boolean mem_base_reg_known_long = FALSE; 713 unsigned int mem_offset = 0; 714 bfd_boolean mem_offset_known = FALSE; 715 bfd_boolean mem_offset_known_long = FALSE; 716 unsigned int mem_mode = 0; 717 bfd_boolean mem_mode_known = FALSE; 718 unsigned int mem_scaled = 0; 719 bfd_boolean mem_scaled_known = FALSE; 720 unsigned int crlo = 0; 721 bfd_boolean crlo_known = FALSE; 722 unsigned int crhi = 0; 723 bfd_boolean crhi_known = FALSE; 724 bfd_boolean spmask_skip_operand = FALSE; 725 unsigned int fcyc_bits = 0; 726 bfd_boolean prev_sploop_found = FALSE; 727 728 switch (opc->operand_info[op_num].form) 729 { 730 case tic6x_operand_b15reg: 731 /* Fully determined by the functional unit. */ 732 operands_text[op_num] = TRUE; 733 snprintf (operands[op_num], 24, "b15"); 734 continue; 735 736 case tic6x_operand_zreg: 737 /* Fully determined by the functional unit. */ 738 operands_text[op_num] = TRUE; 739 snprintf (operands[op_num], 24, "%c0", 740 (func_unit_side == 2 ? 'b' : 'a')); 741 continue; 742 743 case tic6x_operand_retreg: 744 /* Fully determined by the functional unit. */ 745 operands_text[op_num] = TRUE; 746 snprintf (operands[op_num], 24, "%c3", 747 (func_unit_side == 2 ? 'b' : 'a')); 748 continue; 749 750 case tic6x_operand_irp: 751 operands_text[op_num] = TRUE; 752 snprintf (operands[op_num], 24, "irp"); 753 continue; 754 755 case tic6x_operand_nrp: 756 operands_text[op_num] = TRUE; 757 snprintf (operands[op_num], 24, "nrp"); 758 continue; 759 760 case tic6x_operand_ilc: 761 operands_text[op_num] = TRUE; 762 snprintf (operands[op_num], 24, "ilc"); 763 continue; 764 765 case tic6x_operand_hw_const_minus_1: 766 operands_text[op_num] = TRUE; 767 snprintf (operands[op_num], 24, "-1"); 768 continue; 769 770 case tic6x_operand_hw_const_0: 771 operands_text[op_num] = TRUE; 772 snprintf (operands[op_num], 24, "0"); 773 continue; 774 775 case tic6x_operand_hw_const_1: 776 operands_text[op_num] = TRUE; 777 snprintf (operands[op_num], 24, "1"); 778 continue; 779 780 case tic6x_operand_hw_const_5: 781 operands_text[op_num] = TRUE; 782 snprintf (operands[op_num], 24, "5"); 783 continue; 784 785 case tic6x_operand_hw_const_16: 786 operands_text[op_num] = TRUE; 787 snprintf (operands[op_num], 24, "16"); 788 continue; 789 790 case tic6x_operand_hw_const_24: 791 operands_text[op_num] = TRUE; 792 snprintf (operands[op_num], 24, "24"); 793 continue; 794 795 case tic6x_operand_hw_const_31: 796 operands_text[op_num] = TRUE; 797 snprintf (operands[op_num], 24, "31"); 798 continue; 799 800 default: 801 break; 802 } 803 804 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++) 805 { 806 const tic6x_coding_field *const enc 807 = &opc->variable_fields[fld_num]; 808 const tic6x_insn_field *field; 809 unsigned int fld_val; 810 unsigned int reg_base = 0; 811 signed int signed_fld_val; 812 char reg_side = '?'; 813 814 if (enc->operand_num != op_num) 815 continue; 816 field = tic6x_field_from_fmt (fmt, enc->field_id); 817 if (!field) 818 { 819 printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id); 820 abort (); 821 } 822 fld_val = tic6x_field_bits (opcode, field); 823 switch (enc->coding_method) 824 { 825 case tic6x_coding_cst_s3i: 826 (fld_val == 0x00) && (fld_val = 0x10); 827 (fld_val == 0x07) && (fld_val = 0x08); 828 /* Fall through. */ 829 case tic6x_coding_ucst: 830 case tic6x_coding_ulcst_dpr_byte: 831 case tic6x_coding_ulcst_dpr_half: 832 case tic6x_coding_ulcst_dpr_word: 833 case tic6x_coding_lcst_low16: 834 switch (opc->operand_info[op_num].form) 835 { 836 case tic6x_operand_asm_const: 837 case tic6x_operand_link_const: 838 operands_text[op_num] = TRUE; 839 snprintf (operands[op_num], 24, "%u", fld_val); 840 break; 841 842 case tic6x_operand_mem_long: 843 mem_offset = fld_val; 844 mem_offset_known_long = TRUE; 845 break; 846 847 default: 848 printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num); 849 abort (); 850 } 851 break; 852 853 case tic6x_coding_lcst_high16: 854 operands_text[op_num] = TRUE; 855 snprintf (operands[op_num], 24, "%u", fld_val << 16); 856 break; 857 858 case tic6x_coding_scst_l3i: 859 operands_text[op_num] = TRUE; 860 if (fld_val == 0) 861 { 862 signed_fld_val = 8; 863 } 864 else 865 { 866 signed_fld_val = (signed int) fld_val; 867 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1)); 868 signed_fld_val -= (1 << (tic6x_field_width (field) - 1)); 869 } 870 snprintf (operands[op_num], 24, "%d", signed_fld_val); 871 break; 872 873 case tic6x_coding_scst: 874 operands_text[op_num] = TRUE; 875 signed_fld_val = (signed int) fld_val; 876 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1)); 877 signed_fld_val -= (1 << (tic6x_field_width (field) - 1)); 878 snprintf (operands[op_num], 24, "%d", signed_fld_val); 879 break; 880 881 case tic6x_coding_ucst_minus_one: 882 operands_text[op_num] = TRUE; 883 snprintf (operands[op_num], 24, "%u", fld_val + 1); 884 break; 885 886 case tic6x_coding_pcrel: 887 case tic6x_coding_pcrel_half: 888 signed_fld_val = (signed int) fld_val; 889 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1)); 890 signed_fld_val -= (1 << (tic6x_field_width (field) - 1)); 891 if (fetch_packet_header_based 892 && enc->coding_method == tic6x_coding_pcrel_half) 893 signed_fld_val *= 2; 894 else 895 signed_fld_val *= 4; 896 operands_pcrel[op_num] = TRUE; 897 operands_addresses[op_num] = fp_addr + signed_fld_val; 898 break; 899 900 case tic6x_coding_regpair_msb: 901 if (opc->operand_info[op_num].form != tic6x_operand_regpair) 902 abort (); 903 operands_text[op_num] = TRUE; 904 snprintf (operands[op_num], 24, "%c%u:%c%u", 905 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1), 906 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1); 907 break; 908 909 case tic6x_coding_pcrel_half_unsigned: 910 operands_pcrel[op_num] = TRUE; 911 operands_addresses[op_num] = fp_addr + 2 * fld_val; 912 break; 913 914 case tic6x_coding_reg_shift: 915 fld_val <<= 1; 916 /* Fall through. */ 917 case tic6x_coding_reg: 918 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS)) 919 { 920 reg_base = 16; 921 } 922 switch (opc->operand_info[op_num].form) 923 { 924 case tic6x_operand_treg: 925 if (!have_t) 926 { 927 printf ("opcode %x: operand treg but missing t field\n", opcode); 928 abort (); 929 } 930 operands_text[op_num] = TRUE; 931 reg_side = t_val ? 'b' : 'a'; 932 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val); 933 break; 934 935 case tic6x_operand_reg: 936 operands_text[op_num] = TRUE; 937 reg_side = (func_unit_side == 2) ? 'b' : 'a'; 938 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val); 939 break; 940 941 case tic6x_operand_reg_nors: 942 operands_text[op_num] = TRUE; 943 reg_side = (func_unit_side == 2) ? 'b' : 'a'; 944 snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val); 945 break; 946 947 case tic6x_operand_reg_bside: 948 operands_text[op_num] = TRUE; 949 snprintf (operands[op_num], 24, "b%u", reg_base + fld_val); 950 break; 951 952 case tic6x_operand_reg_bside_nors: 953 operands_text[op_num] = TRUE; 954 snprintf (operands[op_num], 24, "b%u", fld_val); 955 break; 956 957 case tic6x_operand_xreg: 958 operands_text[op_num] = TRUE; 959 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a'; 960 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val); 961 break; 962 963 case tic6x_operand_dreg: 964 operands_text[op_num] = TRUE; 965 reg_side = (func_unit_data_side == 2) ? 'b' : 'a'; 966 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val); 967 break; 968 969 case tic6x_operand_regpair: 970 operands_text[op_num] = TRUE; 971 if (fld_val & 1) 972 operands_ok = FALSE; 973 reg_side = (func_unit_side == 2) ? 'b' : 'a'; 974 snprintf (operands[op_num], 24, "%c%u:%c%u", 975 reg_side, reg_base + fld_val + 1, 976 reg_side, reg_base + fld_val); 977 break; 978 979 case tic6x_operand_xregpair: 980 operands_text[op_num] = TRUE; 981 if (fld_val & 1) 982 operands_ok = FALSE; 983 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a'; 984 snprintf (operands[op_num], 24, "%c%u:%c%u", 985 reg_side, reg_base + fld_val + 1, 986 reg_side, reg_base + fld_val); 987 break; 988 989 case tic6x_operand_tregpair: 990 if (!have_t) 991 { 992 printf ("opcode %x: operand tregpair but missing t field\n", opcode); 993 abort (); 994 } 995 operands_text[op_num] = TRUE; 996 if (fld_val & 1) 997 operands_ok = FALSE; 998 reg_side = t_val ? 'b' : 'a'; 999 snprintf (operands[op_num], 24, "%c%u:%c%u", 1000 reg_side, reg_base + fld_val + 1, 1001 reg_side, reg_base + fld_val); 1002 break; 1003 1004 case tic6x_operand_dregpair: 1005 operands_text[op_num] = TRUE; 1006 if (fld_val & 1) 1007 operands_ok = FALSE; 1008 reg_side = (func_unit_data_side) == 2 ? 'b' : 'a'; 1009 snprintf (operands[op_num], 24, "%c%u:%c%u", 1010 reg_side, reg_base + fld_val + 1, 1011 reg_side, reg_base + fld_val); 1012 break; 1013 1014 case tic6x_operand_mem_deref: 1015 operands_text[op_num] = TRUE; 1016 reg_side = func_unit_side == 2 ? 'b' : 'a'; 1017 snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val); 1018 break; 1019 1020 case tic6x_operand_mem_short: 1021 case tic6x_operand_mem_ndw: 1022 mem_base_reg = fld_val; 1023 mem_base_reg_known = TRUE; 1024 break; 1025 1026 default: 1027 printf ("opcode %x: unexpected operand form %d for operand #%d", 1028 opcode, opc->operand_info[op_num].form, op_num); 1029 abort (); 1030 } 1031 break; 1032 1033 case tic6x_coding_reg_ptr: 1034 switch (opc->operand_info[op_num].form) 1035 { 1036 case tic6x_operand_mem_short: 1037 case tic6x_operand_mem_ndw: 1038 if (fld_val > 0x3u) 1039 { 1040 printf("opcode %x: illegal field value for ptr register of operand #%d (%d)", 1041 opcode, op_num, fld_val); 1042 abort (); 1043 } 1044 mem_base_reg = 0x4 | fld_val; 1045 mem_base_reg_known = TRUE; 1046 break; 1047 1048 default: 1049 printf ("opcode %x: unexpected operand form %d for operand #%d", 1050 opcode, opc->operand_info[op_num].form, op_num); 1051 abort (); 1052 } 1053 break; 1054 1055 case tic6x_coding_areg: 1056 switch (opc->operand_info[op_num].form) 1057 { 1058 case tic6x_operand_areg: 1059 operands_text[op_num] = TRUE; 1060 snprintf (operands[op_num], 24, "b%u", 1061 fld_val ? 15u : 14u); 1062 break; 1063 1064 case tic6x_operand_mem_long: 1065 mem_base_reg = fld_val ? 15u : 14u; 1066 mem_base_reg_known_long = TRUE; 1067 break; 1068 1069 default: 1070 printf ("opcode %x: bad operand form\n", opcode); 1071 abort (); 1072 } 1073 break; 1074 1075 case tic6x_coding_mem_offset_minus_one_noscale: 1076 case tic6x_coding_mem_offset_minus_one: 1077 fld_val += 1; 1078 /* Fall through. */ 1079 case tic6x_coding_mem_offset_noscale: 1080 case tic6x_coding_mem_offset: 1081 mem_offset = fld_val; 1082 mem_offset_known = TRUE; 1083 if (num_bits == 16) 1084 { 1085 mem_mode_known = TRUE; 1086 mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags); 1087 mem_scaled_known = TRUE; 1088 mem_scaled = TRUE; 1089 if (opc->flags & TIC6X_FLAG_INSN16_B15PTR) 1090 { 1091 mem_base_reg_known = TRUE; 1092 mem_base_reg = 15; 1093 } 1094 if ( enc->coding_method == tic6x_coding_mem_offset_noscale 1095 || enc->coding_method == tic6x_coding_mem_offset_noscale ) 1096 mem_scaled = FALSE; 1097 } 1098 break; 1099 1100 case tic6x_coding_mem_mode: 1101 mem_mode = fld_val; 1102 mem_mode_known = TRUE; 1103 break; 1104 1105 case tic6x_coding_scaled: 1106 mem_scaled = fld_val; 1107 mem_scaled_known = TRUE; 1108 break; 1109 1110 case tic6x_coding_crlo: 1111 crlo = fld_val; 1112 crlo_known = TRUE; 1113 break; 1114 1115 case tic6x_coding_crhi: 1116 crhi = fld_val; 1117 crhi_known = TRUE; 1118 break; 1119 1120 case tic6x_coding_fstg: 1121 case tic6x_coding_fcyc: 1122 if (!prev_sploop_found) 1123 { 1124 bfd_vma search_fp_addr = fp_addr; 1125 bfd_vma search_fp_offset = fp_offset; 1126 bfd_boolean search_fp_header_based 1127 = fetch_packet_header_based; 1128 tic6x_fetch_packet_header search_fp_header = header; 1129 unsigned char search_fp[32]; 1130 unsigned int search_num_bits; 1131 unsigned int search_opcode; 1132 unsigned int sploop_ii = 0; 1133 int i; 1134 1135 memcpy (search_fp, fp, 32); 1136 1137 /* To interpret these bits in an SPKERNEL 1138 instruction, we must find the previous 1139 SPLOOP-family instruction. It may come up to 1140 48 execute packets earlier. */ 1141 for (i = 0; i < 48 * 8; i++) 1142 { 1143 /* Find the previous instruction. */ 1144 if (search_fp_offset & 2) 1145 search_fp_offset -= 2; 1146 else if (search_fp_offset >= 4) 1147 { 1148 if (search_fp_header_based 1149 && (search_fp_header.word_compact 1150 [(search_fp_offset >> 2) - 1])) 1151 search_fp_offset -= 2; 1152 else 1153 search_fp_offset -= 4; 1154 } 1155 else 1156 { 1157 search_fp_addr -= 32; 1158 status = info->read_memory_func (search_fp_addr, 1159 search_fp, 1160 32, info); 1161 if (status) 1162 /* No previous SPLOOP instruction. */ 1163 break; 1164 search_fp_header_based 1165 = (tic6x_check_fetch_packet_header 1166 (search_fp, &search_fp_header, info)); 1167 if (search_fp_header_based) 1168 search_fp_offset 1169 = search_fp_header.word_compact[6] ? 26 : 24; 1170 else 1171 search_fp_offset = 28; 1172 } 1173 1174 /* Extract the previous instruction. */ 1175 if (search_fp_header_based) 1176 search_num_bits 1177 = (search_fp_header.word_compact[search_fp_offset 1178 >> 2] 1179 ? 16 1180 : 32); 1181 else 1182 search_num_bits = 32; 1183 if (search_num_bits == 16) 1184 { 1185 if (info->endian == BFD_ENDIAN_LITTLE) 1186 search_opcode 1187 = (tic6x_extract_16 1188 (search_fp + search_fp_offset, &header, info)); 1189 else 1190 search_opcode 1191 = (tic6x_extract_16 1192 (search_fp + (search_fp_offset ^ 2), &header, 1193 info)); 1194 } 1195 else 1196 search_opcode 1197 = tic6x_extract_32 (search_fp + search_fp_offset, 1198 info); 1199 1200 /* Check whether it is an SPLOOP-family 1201 instruction. */ 1202 if (search_num_bits == 32 1203 && ((search_opcode & 0x003ffffe) == 0x00038000 1204 || (search_opcode & 0x003ffffe) == 0x0003a000 1205 || ((search_opcode & 0x003ffffe) 1206 == 0x0003e000))) 1207 { 1208 prev_sploop_found = TRUE; 1209 sploop_ii = ((search_opcode >> 23) & 0x1f) + 1; 1210 } 1211 else if (search_num_bits == 16 1212 && (search_opcode & 0x3c7e) == 0x0c66) 1213 { 1214 prev_sploop_found = TRUE; 1215 sploop_ii 1216 = (((search_opcode >> 7) & 0x7) 1217 | ((search_opcode >> 11) & 0x8)) + 1; 1218 } 1219 if (prev_sploop_found) 1220 { 1221 if (sploop_ii <= 0) 1222 { 1223 printf ("opcode %x: sloop index not found (%d)\n", opcode, sploop_ii); 1224 abort (); 1225 } 1226 else if (sploop_ii <= 1) 1227 fcyc_bits = 0; 1228 else if (sploop_ii <= 2) 1229 fcyc_bits = 1; 1230 else if (sploop_ii <= 4) 1231 fcyc_bits = 2; 1232 else if (sploop_ii <= 8) 1233 fcyc_bits = 3; 1234 else if (sploop_ii <= 14) 1235 fcyc_bits = 4; 1236 else 1237 prev_sploop_found = FALSE; 1238 } 1239 if (prev_sploop_found) 1240 break; 1241 } 1242 } 1243 if (!prev_sploop_found) 1244 { 1245 operands_ok = FALSE; 1246 operands_text[op_num] = TRUE; 1247 break; 1248 } 1249 if (fcyc_bits > tic6x_field_width(field)) 1250 { 1251 printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits); 1252 abort (); 1253 } 1254 if (enc->coding_method == tic6x_coding_fstg) 1255 { 1256 int i, t; 1257 for (t = 0, i = fcyc_bits; i < 6; i++) 1258 t = (t << 1) | ((fld_val >> i) & 1); 1259 operands_text[op_num] = TRUE; 1260 snprintf (operands[op_num], 24, "%u", t); 1261 } 1262 else 1263 { 1264 operands_text[op_num] = TRUE; 1265 snprintf (operands[op_num], 24, "%u", 1266 fld_val & ((1 << fcyc_bits) - 1)); 1267 } 1268 break; 1269 1270 case tic6x_coding_spmask: 1271 if (fld_val == 0) 1272 spmask_skip_operand = TRUE; 1273 else 1274 { 1275 char *p; 1276 unsigned int i; 1277 1278 operands_text[op_num] = TRUE; 1279 p = operands[op_num]; 1280 for (i = 0; i < 8; i++) 1281 if (fld_val & (1 << i)) 1282 { 1283 *p++ = "LSDM"[i/2]; 1284 *p++ = '1' + (i & 1); 1285 *p++ = ','; 1286 } 1287 p[-1] = 0; 1288 } 1289 break; 1290 1291 case tic6x_coding_fu: 1292 case tic6x_coding_data_fu: 1293 case tic6x_coding_xpath: 1294 case tic6x_coding_rside: 1295 /* Don't relate to operands, so operand number is 1296 meaningless. */ 1297 break; 1298 1299 default: 1300 printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method); 1301 abort (); 1302 } 1303 1304 if (mem_base_reg_known_long && mem_offset_known_long) 1305 { 1306 if (operands_text[op_num] || operands_pcrel[op_num]) 1307 { 1308 printf ("opcode %x: long access but operands already known ?\n", opcode); 1309 abort (); 1310 } 1311 operands_text[op_num] = TRUE; 1312 snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg, 1313 mem_offset * opc->operand_info[op_num].size); 1314 } 1315 1316 if (mem_base_reg_known && mem_offset_known && mem_mode_known 1317 && (mem_scaled_known 1318 || (opc->operand_info[op_num].form 1319 != tic6x_operand_mem_ndw))) 1320 { 1321 char side; 1322 char base[4]; 1323 bfd_boolean offset_is_reg; 1324 bfd_boolean offset_scaled; 1325 char offset[4]; 1326 char offsetp[6]; 1327 1328 if (operands_text[op_num] || operands_pcrel[op_num]) 1329 { 1330 printf ("opcode %x: mem access operands already known ?\n", opcode); 1331 abort (); 1332 } 1333 1334 side = func_unit_side == 2 ? 'b' : 'a'; 1335 snprintf (base, 4, "%c%u", side, mem_base_reg); 1336 1337 offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE); 1338 if (offset_is_reg) 1339 { 1340 1341 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS)) 1342 { 1343 reg_base = 16; 1344 } 1345 snprintf (offset, 4, "%c%u", side, reg_base + mem_offset); 1346 if (opc->operand_info[op_num].form 1347 == tic6x_operand_mem_ndw) 1348 offset_scaled = mem_scaled ? TRUE : FALSE; 1349 else 1350 offset_scaled = TRUE; 1351 } 1352 else 1353 { 1354 if (opc->operand_info[op_num].form 1355 == tic6x_operand_mem_ndw) 1356 { 1357 offset_scaled = mem_scaled ? TRUE : FALSE; 1358 snprintf (offset, 4, "%u", mem_offset); 1359 } 1360 else 1361 { 1362 offset_scaled = FALSE; 1363 snprintf (offset, 4, "%u", 1364 (mem_offset 1365 * opc->operand_info[op_num].size)); 1366 } 1367 } 1368 1369 if (offset_scaled) 1370 snprintf (offsetp, 6, "[%s]", offset); 1371 else 1372 snprintf (offsetp, 6, "(%s)", offset); 1373 1374 operands_text[op_num] = TRUE; 1375 switch (mem_mode & ~4u) 1376 { 1377 case 0: 1378 snprintf (operands[op_num], 24, "*-%s%s", base, offsetp); 1379 break; 1380 1381 case 1: 1382 snprintf (operands[op_num], 24, "*+%s%s", base, offsetp); 1383 break; 1384 1385 case 2: 1386 case 3: 1387 operands_ok = FALSE; 1388 break; 1389 1390 case 8: 1391 snprintf (operands[op_num], 24, "*--%s%s", base, 1392 offsetp); 1393 break; 1394 1395 case 9: 1396 snprintf (operands[op_num], 24, "*++%s%s", base, 1397 offsetp); 1398 break; 1399 1400 case 10: 1401 snprintf (operands[op_num], 24, "*%s--%s", base, 1402 offsetp); 1403 break; 1404 1405 case 11: 1406 snprintf (operands[op_num], 24, "*%s++%s", base, 1407 offsetp); 1408 break; 1409 1410 default: 1411 printf ("*** unknown mem_mode : %d \n", mem_mode); 1412 abort (); 1413 } 1414 } 1415 1416 if (crlo_known && crhi_known) 1417 { 1418 tic6x_rw rw; 1419 tic6x_ctrl_id crid; 1420 1421 if (operands_text[op_num] || operands_pcrel[op_num]) 1422 { 1423 printf ("*** abort crlo crli\n"); 1424 abort (); 1425 } 1426 1427 rw = opc->operand_info[op_num].rw; 1428 if (rw != tic6x_rw_read 1429 && rw != tic6x_rw_write) 1430 { 1431 printf ("*** abort rw : %d\n", rw); 1432 abort (); 1433 } 1434 1435 for (crid = 0; crid < tic6x_ctrl_max; crid++) 1436 { 1437 if (crlo == tic6x_ctrl_table[crid].crlo 1438 && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0 1439 && (rw == tic6x_rw_read 1440 ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read 1441 || (tic6x_ctrl_table[crid].rw 1442 == tic6x_rw_read_write)) 1443 : (tic6x_ctrl_table[crid].rw == tic6x_rw_write 1444 || (tic6x_ctrl_table[crid].rw 1445 == tic6x_rw_read_write)))) 1446 break; 1447 } 1448 if (crid == tic6x_ctrl_max) 1449 { 1450 operands_text[op_num] = TRUE; 1451 operands_ok = FALSE; 1452 } 1453 else 1454 { 1455 operands_text[op_num] = TRUE; 1456 snprintf (operands[op_num], 24, "%s", 1457 tic6x_ctrl_table[crid].name); 1458 } 1459 } 1460 1461 if (operands_text[op_num] || operands_pcrel[op_num] 1462 || spmask_skip_operand) 1463 break; 1464 } 1465 /* end for fld_num */ 1466 1467 if (spmask_skip_operand) 1468 { 1469 /* SPMASK operands are only valid as the single operand 1470 in the opcode table. */ 1471 if (num_operands != 1) 1472 { 1473 printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands); 1474 abort (); 1475 } 1476 num_operands = 0; 1477 break; 1478 } 1479 1480 /* The operand must by now have been decoded. */ 1481 if (!operands_text[op_num] && !operands_pcrel[op_num]) 1482 { 1483 printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num); 1484 abort (); 1485 } 1486 } 1487 /* end for op_num */ 1488 1489 if (!operands_ok) 1490 continue; 1491 1492 info->bytes_per_chunk = num_bits / 8; 1493 info->fprintf_func (info->stream, "%s", parallel); 1494 info->fprintf_func (info->stream, "%s%s%s", cond, opc->name, 1495 func_unit); 1496 for (op_num = 0; op_num < num_operands; op_num++) 1497 { 1498 info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ',')); 1499 if (operands_pcrel[op_num]) 1500 info->print_address_func (operands_addresses[op_num], info); 1501 else 1502 info->fprintf_func (info->stream, "%s", operands[op_num]); 1503 } 1504 if (fetch_packet_header_based && header.prot) 1505 info->fprintf_func (info->stream, " || nop 5"); 1506 1507 return num_bits / 8; 1508 } 1509 1510 info->bytes_per_chunk = num_bits / 8; 1511 info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>", 1512 (int) num_bits / 4, opcode); 1513 return num_bits / 8; 1514} 1515