1/* Print instructions for the Texas TMS320C[34]X, for GDB and GNU Binutils. 2 3 Copyright 2002, 2003, 2005, 2007 Free Software Foundation, Inc. 4 5 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) 6 7 This file is part of the GNU opcodes library. 8 9 This library is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3, or (at your option) 12 any later version. 13 14 It is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22 MA 02110-1301, USA. */ 23 24#include <math.h> 25#include "libiberty.h" 26#include "dis-asm.h" 27#include "opcode/tic4x.h" 28 29#define TIC4X_DEBUG 0 30 31#define TIC4X_HASH_SIZE 11 /* 11 (bits) and above should give unique entries. */ 32#define TIC4X_SPESOP_SIZE 8 /* Max 8. ops for special instructions. */ 33 34typedef enum 35{ 36 IMMED_SINT, 37 IMMED_SUINT, 38 IMMED_SFLOAT, 39 IMMED_INT, 40 IMMED_UINT, 41 IMMED_FLOAT 42} 43immed_t; 44 45typedef enum 46{ 47 INDIRECT_SHORT, 48 INDIRECT_LONG, 49 INDIRECT_TIC4X 50} 51indirect_t; 52 53static int tic4x_version = 0; 54static int tic4x_dp = 0; 55 56static int 57tic4x_pc_offset (unsigned int op) 58{ 59 /* Determine the PC offset for a C[34]x instruction. 60 This could be simplified using some boolean algebra 61 but at the expense of readability. */ 62 switch (op >> 24) 63 { 64 case 0x60: /* br */ 65 case 0x62: /* call (C4x) */ 66 case 0x64: /* rptb (C4x) */ 67 return 1; 68 case 0x61: /* brd */ 69 case 0x63: /* laj */ 70 case 0x65: /* rptbd (C4x) */ 71 return 3; 72 case 0x66: /* swi */ 73 case 0x67: 74 return 0; 75 default: 76 break; 77 } 78 79 switch ((op & 0xffe00000) >> 20) 80 { 81 case 0x6a0: /* bB */ 82 case 0x720: /* callB */ 83 case 0x740: /* trapB */ 84 return 1; 85 86 case 0x6a2: /* bBd */ 87 case 0x6a6: /* bBat */ 88 case 0x6aa: /* bBaf */ 89 case 0x722: /* lajB */ 90 case 0x748: /* latB */ 91 case 0x798: /* rptbd */ 92 return 3; 93 94 default: 95 break; 96 } 97 98 switch ((op & 0xfe200000) >> 20) 99 { 100 case 0x6e0: /* dbB */ 101 return 1; 102 103 case 0x6e2: /* dbBd */ 104 return 3; 105 106 default: 107 break; 108 } 109 110 return 0; 111} 112 113static int 114tic4x_print_char (struct disassemble_info * info, char ch) 115{ 116 if (info != NULL) 117 (*info->fprintf_func) (info->stream, "%c", ch); 118 return 1; 119} 120 121static int 122tic4x_print_str (struct disassemble_info *info, char *str) 123{ 124 if (info != NULL) 125 (*info->fprintf_func) (info->stream, "%s", str); 126 return 1; 127} 128 129static int 130tic4x_print_register (struct disassemble_info *info, unsigned long regno) 131{ 132 static tic4x_register_t ** registertable = NULL; 133 unsigned int i; 134 135 if (registertable == NULL) 136 { 137 registertable = xmalloc (sizeof (tic4x_register_t *) * REG_TABLE_SIZE); 138 for (i = 0; i < tic3x_num_registers; i++) 139 registertable[tic3x_registers[i].regno] = (tic4x_register_t *) (tic3x_registers + i); 140 if (IS_CPU_TIC4X (tic4x_version)) 141 { 142 /* Add C4x additional registers, overwriting 143 any C3x registers if necessary. */ 144 for (i = 0; i < tic4x_num_registers; i++) 145 registertable[tic4x_registers[i].regno] = 146 (tic4x_register_t *)(tic4x_registers + i); 147 } 148 } 149 if ((int) regno > (IS_CPU_TIC4X (tic4x_version) ? TIC4X_REG_MAX : TIC3X_REG_MAX)) 150 return 0; 151 if (info != NULL) 152 (*info->fprintf_func) (info->stream, "%s", registertable[regno]->name); 153 return 1; 154} 155 156static int 157tic4x_print_addr (struct disassemble_info *info, unsigned long addr) 158{ 159 if (info != NULL) 160 (*info->print_address_func)(addr, info); 161 return 1; 162} 163 164static int 165tic4x_print_relative (struct disassemble_info *info, 166 unsigned long pc, 167 long offset, 168 unsigned long opcode) 169{ 170 return tic4x_print_addr (info, pc + offset + tic4x_pc_offset (opcode)); 171} 172 173static int 174tic4x_print_direct (struct disassemble_info *info, unsigned long arg) 175{ 176 if (info != NULL) 177 { 178 (*info->fprintf_func) (info->stream, "@"); 179 tic4x_print_addr (info, arg + (tic4x_dp << 16)); 180 } 181 return 1; 182} 183#if 0 184/* FIXME: make the floating point stuff not rely on host 185 floating point arithmetic. */ 186 187static void 188tic4x_print_ftoa (unsigned int val, FILE *stream, fprintf_ftype pfunc) 189{ 190 int e; 191 int s; 192 int f; 193 double num = 0.0; 194 195 e = EXTRS (val, 31, 24); /* Exponent. */ 196 if (e != -128) 197 { 198 s = EXTRU (val, 23, 23); /* Sign bit. */ 199 f = EXTRU (val, 22, 0); /* Mantissa. */ 200 if (s) 201 f += -2 * (1 << 23); 202 else 203 f += (1 << 23); 204 num = f / (double)(1 << 23); 205 num = ldexp (num, e); 206 } 207 (*pfunc)(stream, "%.9g", num); 208} 209#endif 210 211static int 212tic4x_print_immed (struct disassemble_info *info, 213 immed_t type, 214 unsigned long arg) 215{ 216 int s; 217 int f; 218 int e; 219 double num = 0.0; 220 221 if (info == NULL) 222 return 1; 223 switch (type) 224 { 225 case IMMED_SINT: 226 case IMMED_INT: 227 (*info->fprintf_func) (info->stream, "%ld", (long) arg); 228 break; 229 230 case IMMED_SUINT: 231 case IMMED_UINT: 232 (*info->fprintf_func) (info->stream, "%lu", arg); 233 break; 234 235 case IMMED_SFLOAT: 236 e = EXTRS (arg, 15, 12); 237 if (e != -8) 238 { 239 s = EXTRU (arg, 11, 11); 240 f = EXTRU (arg, 10, 0); 241 if (s) 242 f += -2 * (1 << 11); 243 else 244 f += (1 << 11); 245 num = f / (double)(1 << 11); 246 num = ldexp (num, e); 247 } 248 (*info->fprintf_func) (info->stream, "%f", num); 249 break; 250 case IMMED_FLOAT: 251 e = EXTRS (arg, 31, 24); 252 if (e != -128) 253 { 254 s = EXTRU (arg, 23, 23); 255 f = EXTRU (arg, 22, 0); 256 if (s) 257 f += -2 * (1 << 23); 258 else 259 f += (1 << 23); 260 num = f / (double)(1 << 23); 261 num = ldexp (num, e); 262 } 263 (*info->fprintf_func) (info->stream, "%f", num); 264 break; 265 } 266 return 1; 267} 268 269static int 270tic4x_print_cond (struct disassemble_info *info, unsigned int cond) 271{ 272 static tic4x_cond_t **condtable = NULL; 273 unsigned int i; 274 275 if (condtable == NULL) 276 { 277 condtable = xmalloc (sizeof (tic4x_cond_t *) * 32); 278 for (i = 0; i < tic4x_num_conds; i++) 279 condtable[tic4x_conds[i].cond] = (tic4x_cond_t *)(tic4x_conds + i); 280 } 281 if (cond > 31 || condtable[cond] == NULL) 282 return 0; 283 if (info != NULL) 284 (*info->fprintf_func) (info->stream, "%s", condtable[cond]->name); 285 return 1; 286} 287 288static int 289tic4x_print_indirect (struct disassemble_info *info, 290 indirect_t type, 291 unsigned long arg) 292{ 293 unsigned int aregno; 294 unsigned int modn; 295 unsigned int disp; 296 char *a; 297 298 aregno = 0; 299 modn = 0; 300 disp = 1; 301 switch(type) 302 { 303 case INDIRECT_TIC4X: /* *+ARn(disp) */ 304 disp = EXTRU (arg, 7, 3); 305 aregno = EXTRU (arg, 2, 0) + REG_AR0; 306 modn = 0; 307 break; 308 case INDIRECT_SHORT: 309 disp = 1; 310 aregno = EXTRU (arg, 2, 0) + REG_AR0; 311 modn = EXTRU (arg, 7, 3); 312 break; 313 case INDIRECT_LONG: 314 disp = EXTRU (arg, 7, 0); 315 aregno = EXTRU (arg, 10, 8) + REG_AR0; 316 modn = EXTRU (arg, 15, 11); 317 if (modn > 7 && disp != 0) 318 return 0; 319 break; 320 default: 321 (*info->fprintf_func)(info->stream, "# internal error: Unknown indirect type %d", type); 322 return 0; 323 } 324 if (modn > TIC3X_MODN_MAX) 325 return 0; 326 a = tic4x_indirects[modn].name; 327 while (*a) 328 { 329 switch (*a) 330 { 331 case 'a': 332 tic4x_print_register (info, aregno); 333 break; 334 case 'd': 335 tic4x_print_immed (info, IMMED_UINT, disp); 336 break; 337 case 'y': 338 tic4x_print_str (info, "ir0"); 339 break; 340 case 'z': 341 tic4x_print_str (info, "ir1"); 342 break; 343 default: 344 tic4x_print_char (info, *a); 345 break; 346 } 347 a++; 348 } 349 return 1; 350} 351 352static int 353tic4x_print_op (struct disassemble_info *info, 354 unsigned long instruction, 355 tic4x_inst_t *p, 356 unsigned long pc) 357{ 358 int val; 359 char *s; 360 char *parallel = NULL; 361 362 /* Print instruction name. */ 363 s = p->name; 364 while (*s && parallel == NULL) 365 { 366 switch (*s) 367 { 368 case 'B': 369 if (! tic4x_print_cond (info, EXTRU (instruction, 20, 16))) 370 return 0; 371 break; 372 case 'C': 373 if (! tic4x_print_cond (info, EXTRU (instruction, 27, 23))) 374 return 0; 375 break; 376 case '_': 377 parallel = s + 1; /* Skip past `_' in name. */ 378 break; 379 default: 380 tic4x_print_char (info, *s); 381 break; 382 } 383 s++; 384 } 385 386 /* Print arguments. */ 387 s = p->args; 388 if (*s) 389 tic4x_print_char (info, ' '); 390 391 while (*s) 392 { 393 switch (*s) 394 { 395 case '*': /* Indirect 0--15. */ 396 if (! tic4x_print_indirect (info, INDIRECT_LONG, 397 EXTRU (instruction, 15, 0))) 398 return 0; 399 break; 400 401 case '#': /* Only used for ldp, ldpk. */ 402 tic4x_print_immed (info, IMMED_UINT, EXTRU (instruction, 15, 0)); 403 break; 404 405 case '@': /* Direct 0--15. */ 406 tic4x_print_direct (info, EXTRU (instruction, 15, 0)); 407 break; 408 409 case 'A': /* Address register 24--22. */ 410 if (! tic4x_print_register (info, EXTRU (instruction, 24, 22) + 411 REG_AR0)) 412 return 0; 413 break; 414 415 case 'B': /* 24-bit unsigned int immediate br(d)/call/rptb 416 address 0--23. */ 417 if (IS_CPU_TIC4X (tic4x_version)) 418 tic4x_print_relative (info, pc, EXTRS (instruction, 23, 0), 419 p->opcode); 420 else 421 tic4x_print_addr (info, EXTRU (instruction, 23, 0)); 422 break; 423 424 case 'C': /* Indirect (short C4x) 0--7. */ 425 if (! IS_CPU_TIC4X (tic4x_version)) 426 return 0; 427 if (! tic4x_print_indirect (info, INDIRECT_TIC4X, 428 EXTRU (instruction, 7, 0))) 429 return 0; 430 break; 431 432 case 'D': 433 /* Cockup if get here... */ 434 break; 435 436 case 'E': /* Register 0--7. */ 437 case 'e': 438 if (! tic4x_print_register (info, EXTRU (instruction, 7, 0))) 439 return 0; 440 break; 441 442 case 'F': /* 16-bit float immediate 0--15. */ 443 tic4x_print_immed (info, IMMED_SFLOAT, 444 EXTRU (instruction, 15, 0)); 445 break; 446 447 case 'i': /* Extended indirect 0--7. */ 448 if (EXTRU (instruction, 7, 5) == 7) 449 { 450 if (!tic4x_print_register (info, EXTRU (instruction, 4, 0))) 451 return 0; 452 break; 453 } 454 /* Fallthrough */ 455 456 case 'I': /* Indirect (short) 0--7. */ 457 if (! tic4x_print_indirect (info, INDIRECT_SHORT, 458 EXTRU (instruction, 7, 0))) 459 return 0; 460 break; 461 462 case 'j': /* Extended indirect 8--15 */ 463 if (EXTRU (instruction, 15, 13) == 7) 464 { 465 if (! tic4x_print_register (info, EXTRU (instruction, 12, 8))) 466 return 0; 467 break; 468 } 469 470 case 'J': /* Indirect (short) 8--15. */ 471 if (! tic4x_print_indirect (info, INDIRECT_SHORT, 472 EXTRU (instruction, 15, 8))) 473 return 0; 474 break; 475 476 case 'G': /* Register 8--15. */ 477 case 'g': 478 if (! tic4x_print_register (info, EXTRU (instruction, 15, 8))) 479 return 0; 480 break; 481 482 case 'H': /* Register 16--18. */ 483 if (! tic4x_print_register (info, EXTRU (instruction, 18, 16))) 484 return 0; 485 break; 486 487 case 'K': /* Register 19--21. */ 488 if (! tic4x_print_register (info, EXTRU (instruction, 21, 19))) 489 return 0; 490 break; 491 492 case 'L': /* Register 22--24. */ 493 if (! tic4x_print_register (info, EXTRU (instruction, 24, 22))) 494 return 0; 495 break; 496 497 case 'M': /* Register 22--22. */ 498 tic4x_print_register (info, EXTRU (instruction, 22, 22) + REG_R2); 499 break; 500 501 case 'N': /* Register 23--23. */ 502 tic4x_print_register (info, EXTRU (instruction, 23, 23) + REG_R0); 503 break; 504 505 case 'O': /* Indirect (short C4x) 8--15. */ 506 if (! IS_CPU_TIC4X (tic4x_version)) 507 return 0; 508 if (! tic4x_print_indirect (info, INDIRECT_TIC4X, 509 EXTRU (instruction, 15, 8))) 510 return 0; 511 break; 512 513 case 'P': /* Displacement 0--15 (used by Bcond and BcondD). */ 514 tic4x_print_relative (info, pc, EXTRS (instruction, 15, 0), 515 p->opcode); 516 break; 517 518 case 'Q': /* Register 0--15. */ 519 case 'q': 520 if (! tic4x_print_register (info, EXTRU (instruction, 15, 0))) 521 return 0; 522 break; 523 524 case 'R': /* Register 16--20. */ 525 case 'r': 526 if (! tic4x_print_register (info, EXTRU (instruction, 20, 16))) 527 return 0; 528 break; 529 530 case 'S': /* 16-bit signed immediate 0--15. */ 531 tic4x_print_immed (info, IMMED_SINT, 532 EXTRS (instruction, 15, 0)); 533 break; 534 535 case 'T': /* 5-bit signed immediate 16--20 (C4x stik). */ 536 if (! IS_CPU_TIC4X (tic4x_version)) 537 return 0; 538 if (! tic4x_print_immed (info, IMMED_SUINT, 539 EXTRU (instruction, 20, 16))) 540 return 0; 541 break; 542 543 case 'U': /* 16-bit unsigned int immediate 0--15. */ 544 tic4x_print_immed (info, IMMED_SUINT, EXTRU (instruction, 15, 0)); 545 break; 546 547 case 'V': /* 5/9-bit unsigned vector 0--4/8. */ 548 tic4x_print_immed (info, IMMED_SUINT, 549 IS_CPU_TIC4X (tic4x_version) ? 550 EXTRU (instruction, 8, 0) : 551 EXTRU (instruction, 4, 0) & ~0x20); 552 break; 553 554 case 'W': /* 8-bit signed immediate 0--7. */ 555 if (! IS_CPU_TIC4X (tic4x_version)) 556 return 0; 557 tic4x_print_immed (info, IMMED_SINT, EXTRS (instruction, 7, 0)); 558 break; 559 560 case 'X': /* Expansion register 4--0. */ 561 val = EXTRU (instruction, 4, 0) + REG_IVTP; 562 if (val < REG_IVTP || val > REG_TVTP) 563 return 0; 564 if (! tic4x_print_register (info, val)) 565 return 0; 566 break; 567 568 case 'Y': /* Address register 16--20. */ 569 val = EXTRU (instruction, 20, 16); 570 if (val < REG_AR0 || val > REG_SP) 571 return 0; 572 if (! tic4x_print_register (info, val)) 573 return 0; 574 break; 575 576 case 'Z': /* Expansion register 16--20. */ 577 val = EXTRU (instruction, 20, 16) + REG_IVTP; 578 if (val < REG_IVTP || val > REG_TVTP) 579 return 0; 580 if (! tic4x_print_register (info, val)) 581 return 0; 582 break; 583 584 case '|': /* Parallel instruction. */ 585 tic4x_print_str (info, " || "); 586 tic4x_print_str (info, parallel); 587 tic4x_print_char (info, ' '); 588 break; 589 590 case ';': 591 tic4x_print_char (info, ','); 592 break; 593 594 default: 595 tic4x_print_char (info, *s); 596 break; 597 } 598 s++; 599 } 600 return 1; 601} 602 603static void 604tic4x_hash_opcode_special (tic4x_inst_t **optable_special, 605 const tic4x_inst_t *inst) 606{ 607 int i; 608 609 for (i = 0;i < TIC4X_SPESOP_SIZE; i++) 610 if (optable_special[i] != NULL 611 && optable_special[i]->opcode == inst->opcode) 612 { 613 /* Collision (we have it already) - overwrite. */ 614 optable_special[i] = (tic4x_inst_t *) inst; 615 return; 616 } 617 618 for (i = 0; i < TIC4X_SPESOP_SIZE; i++) 619 if (optable_special[i] == NULL) 620 { 621 /* Add the new opcode. */ 622 optable_special[i] = (tic4x_inst_t *) inst; 623 return; 624 } 625 626 /* This should never occur. This happens if the number of special 627 instructions exceeds TIC4X_SPESOP_SIZE. Please increase the variable 628 of this variable */ 629#if TIC4X_DEBUG 630 printf ("optable_special[] is full, please increase TIC4X_SPESOP_SIZE!\n"); 631#endif 632} 633 634static void 635tic4x_hash_opcode (tic4x_inst_t **optable, 636 tic4x_inst_t **optable_special, 637 const tic4x_inst_t *inst, 638 const unsigned long tic4x_oplevel) 639{ 640 int j; 641 int opcode = inst->opcode >> (32 - TIC4X_HASH_SIZE); 642 int opmask = inst->opmask >> (32 - TIC4X_HASH_SIZE); 643 644 /* Use a TIC4X_HASH_SIZE bit index as a hash index. We should 645 have unique entries so there's no point having a linked list 646 for each entry? */ 647 for (j = opcode; j < opmask; j++) 648 if ((j & opmask) == opcode 649 && inst->oplevel & tic4x_oplevel) 650 { 651#if TIC4X_DEBUG 652 /* We should only have collisions for synonyms like 653 ldp for ldi. */ 654 if (optable[j] != NULL) 655 printf ("Collision at index %d, %s and %s\n", 656 j, optable[j]->name, inst->name); 657#endif 658 /* Catch those ops that collide with others already inside the 659 hash, and have a opmask greater than the one we use in the 660 hash. Store them in a special-list, that will handle full 661 32-bit INSN, not only the first 11-bit (or so). */ 662 if (optable[j] != NULL 663 && inst->opmask & ~(opmask << (32 - TIC4X_HASH_SIZE))) 664 { 665 /* Add the instruction already on the list. */ 666 tic4x_hash_opcode_special (optable_special, optable[j]); 667 668 /* Add the new instruction. */ 669 tic4x_hash_opcode_special (optable_special, inst); 670 } 671 672 optable[j] = (tic4x_inst_t *) inst; 673 } 674} 675 676/* Disassemble the instruction in 'instruction'. 677 'pc' should be the address of this instruction, it will 678 be used to print the target address if this is a relative jump or call 679 the disassembled instruction is written to 'info'. 680 The function returns the length of this instruction in words. */ 681 682static int 683tic4x_disassemble (unsigned long pc, 684 unsigned long instruction, 685 struct disassemble_info *info) 686{ 687 static tic4x_inst_t **optable = NULL; 688 static tic4x_inst_t **optable_special = NULL; 689 tic4x_inst_t *p; 690 int i; 691 unsigned long tic4x_oplevel; 692 693 tic4x_version = info->mach; 694 695 tic4x_oplevel = (IS_CPU_TIC4X (tic4x_version)) ? OP_C4X : 0; 696 tic4x_oplevel |= OP_C3X | OP_LPWR | OP_IDLE2 | OP_ENH; 697 698 if (optable == NULL) 699 { 700 optable = xcalloc (sizeof (tic4x_inst_t *), (1 << TIC4X_HASH_SIZE)); 701 702 optable_special = xcalloc (sizeof (tic4x_inst_t *), TIC4X_SPESOP_SIZE); 703 704 /* Install opcodes in reverse order so that preferred 705 forms overwrite synonyms. */ 706 for (i = tic4x_num_insts - 1; i >= 0; i--) 707 tic4x_hash_opcode (optable, optable_special, &tic4x_insts[i], 708 tic4x_oplevel); 709 710 /* We now need to remove the insn that are special from the 711 "normal" optable, to make the disasm search this extra list 712 for them. */ 713 for (i = 0; i < TIC4X_SPESOP_SIZE; i++) 714 if (optable_special[i] != NULL) 715 optable[optable_special[i]->opcode >> (32 - TIC4X_HASH_SIZE)] = NULL; 716 } 717 718 /* See if we can pick up any loading of the DP register... */ 719 if ((instruction >> 16) == 0x5070 || (instruction >> 16) == 0x1f70) 720 tic4x_dp = EXTRU (instruction, 15, 0); 721 722 p = optable[instruction >> (32 - TIC4X_HASH_SIZE)]; 723 if (p != NULL) 724 { 725 if (((instruction & p->opmask) == p->opcode) 726 && tic4x_print_op (NULL, instruction, p, pc)) 727 tic4x_print_op (info, instruction, p, pc); 728 else 729 (*info->fprintf_func) (info->stream, "%08lx", instruction); 730 } 731 else 732 { 733 for (i = 0; i<TIC4X_SPESOP_SIZE; i++) 734 if (optable_special[i] != NULL 735 && optable_special[i]->opcode == instruction) 736 { 737 (*info->fprintf_func)(info->stream, "%s", optable_special[i]->name); 738 break; 739 } 740 if (i == TIC4X_SPESOP_SIZE) 741 (*info->fprintf_func) (info->stream, "%08lx", instruction); 742 } 743 744 /* Return size of insn in words. */ 745 return 1; 746} 747 748/* The entry point from objdump and gdb. */ 749int 750print_insn_tic4x (bfd_vma memaddr, struct disassemble_info *info) 751{ 752 int status; 753 unsigned long pc; 754 unsigned long op; 755 bfd_byte buffer[4]; 756 757 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 758 if (status != 0) 759 { 760 (*info->memory_error_func) (status, memaddr, info); 761 return -1; 762 } 763 764 pc = memaddr; 765 op = bfd_getl32 (buffer); 766 info->bytes_per_line = 4; 767 info->bytes_per_chunk = 4; 768 info->octets_per_byte = 4; 769 info->display_endian = BFD_ENDIAN_LITTLE; 770 return tic4x_disassemble (pc, op, info) * 4; 771} 772