1/* kvx-dis.c -- Kalray MPPA generic disassembler. 2 Copyright (C) 2009-2024 Free Software Foundation, Inc. 3 Contributed by Kalray SA. 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; see the file COPYING3. If not, 19 see <http://www.gnu.org/licenses/>. */ 20 21#define STATIC_TABLE 22#define DEFINE_TABLE 23 24#include "sysdep.h" 25#include "disassemble.h" 26#include "libiberty.h" 27#include "opintl.h" 28#include <assert.h> 29#include "elf-bfd.h" 30#include "kvx-dis.h" 31 32#include "elf/kvx.h" 33#include "opcode/kvx.h" 34 35/* Steering values for the kvx VLIW architecture. */ 36 37typedef enum 38{ 39 Steering_BCU, 40 Steering_LSU, 41 Steering_MAU, 42 Steering_ALU, 43 Steering__ 44} enum_Steering; 45typedef uint8_t Steering; 46 47/* BundleIssue enumeration. */ 48 49typedef enum 50{ 51 BundleIssue_BCU, 52 BundleIssue_TCA, 53 BundleIssue_ALU0, 54 BundleIssue_ALU1, 55 BundleIssue_MAU, 56 BundleIssue_LSU, 57 BundleIssue__, 58} enum_BundleIssue; 59typedef uint8_t BundleIssue; 60 61/* An IMMX syllable is associated with the BundleIssue Extension_BundleIssue[extension]. */ 62static const BundleIssue Extension_BundleIssue[] = { 63 BundleIssue_ALU0, 64 BundleIssue_ALU1, 65 BundleIssue_MAU, 66 BundleIssue_LSU 67}; 68 69static inline int 70kvx_steering (uint32_t x) 71{ 72 return (((x) & 0x60000000) >> 29); 73} 74 75static inline int 76kvx_extension (uint32_t x) 77{ 78 return (((x) & 0x18000000) >> 27); 79} 80 81static inline int 82kvx_has_parallel_bit (uint32_t x) 83{ 84 return (((x) & 0x80000000) == 0x80000000); 85} 86 87static inline int 88kvx_is_tca_opcode (uint32_t x) 89{ 90 unsigned major = ((x) >> 24) & 0x1F; 91 return (major > 1) && (major < 8); 92} 93 94static inline int 95kvx_is_nop_opcode (uint32_t x) 96{ 97 return ((x) << 1) == 0xFFFFFFFE; 98} 99 100/* A raw instruction. */ 101 102struct insn_s 103{ 104 uint32_t syllables[KVXMAXSYLLABLES]; 105 int len; 106}; 107typedef struct insn_s insn_t; 108 109 110static uint32_t bundle_words[KVXMAXBUNDLEWORDS]; 111 112static insn_t bundle_insn[KVXMAXBUNDLEISSUE]; 113 114/* A re-interpreted instruction. */ 115 116struct instr_s 117{ 118 int valid; 119 int opcode; 120 int immx[2]; 121 int immx_valid[2]; 122 int immx_count; 123 int nb_syllables; 124}; 125 126/* Option for "pretty printing", ie, not the usual little endian objdump output. */ 127static int opt_pretty = 0; 128/* Option for not emiting a new line between all bundles. */ 129static int opt_compact_assembly = 0; 130 131void 132parse_kvx_dis_option (const char *option) 133{ 134 /* Try to match options that are simple flags. */ 135 if (startswith (option, "pretty")) 136 { 137 opt_pretty = 1; 138 return; 139 } 140 141 if (startswith (option, "compact-assembly")) 142 { 143 opt_compact_assembly = 1; 144 return; 145 } 146 147 if (startswith (option, "no-compact-assembly")) 148 { 149 opt_compact_assembly = 0; 150 return; 151 } 152 153 /* Invalid option. */ 154 opcodes_error_handler (_("unrecognised disassembler option: %s"), option); 155} 156 157static void 158parse_kvx_dis_options (const char *options) 159{ 160 const char *option_end; 161 162 if (options == NULL) 163 return; 164 165 while (*options != '\0') 166 { 167 /* Skip empty options. */ 168 if (*options == ',') 169 { 170 options++; 171 continue; 172 } 173 174 /* We know that *options is neither NUL or a comma. */ 175 option_end = options + 1; 176 while (*option_end != ',' && *option_end != '\0') 177 option_end++; 178 179 parse_kvx_dis_option (options); 180 181 /* Go on to the next one. If option_end points to a comma, it 182 will be skipped above. */ 183 options = option_end; 184 } 185} 186 187struct kvx_dis_env 188{ 189 int kvx_arch_size; 190 struct kvxopc *opc_table; 191 struct kvx_Register *kvx_registers; 192 const char ***kvx_modifiers; 193 int *kvx_dec_registers; 194 int *kvx_regfiles; 195 unsigned int kvx_max_dec_registers; 196 int initialized_p; 197}; 198 199static struct kvx_dis_env env = { 200 .kvx_arch_size = 0, 201 .opc_table = NULL, 202 .kvx_registers = NULL, 203 .kvx_modifiers = NULL, 204 .kvx_dec_registers = NULL, 205 .kvx_regfiles = NULL, 206 .initialized_p = 0, 207 .kvx_max_dec_registers = 0 208}; 209 210static void 211kvx_dis_init (struct disassemble_info *info) 212{ 213 env.kvx_arch_size = 32; 214 switch (info->mach) 215 { 216 case bfd_mach_kv3_1_64: 217 env.kvx_arch_size = 64; 218 /* fallthrough */ 219 case bfd_mach_kv3_1_usr: 220 case bfd_mach_kv3_1: 221 default: 222 env.opc_table = kvx_kv3_v1_optab; 223 env.kvx_regfiles = kvx_kv3_v1_regfiles; 224 env.kvx_registers = kvx_kv3_v1_registers; 225 env.kvx_modifiers = kvx_kv3_v1_modifiers; 226 env.kvx_dec_registers = kvx_kv3_v1_dec_registers; 227 break; 228 case bfd_mach_kv3_2_64: 229 env.kvx_arch_size = 64; 230 /* fallthrough */ 231 case bfd_mach_kv3_2_usr: 232 case bfd_mach_kv3_2: 233 env.opc_table = kvx_kv3_v2_optab; 234 env.kvx_regfiles = kvx_kv3_v2_regfiles; 235 env.kvx_registers = kvx_kv3_v2_registers; 236 env.kvx_modifiers = kvx_kv3_v2_modifiers; 237 env.kvx_dec_registers = kvx_kv3_v2_dec_registers; 238 break; 239 case bfd_mach_kv4_1_64: 240 env.kvx_arch_size = 64; 241 /* fallthrough */ 242 case bfd_mach_kv4_1_usr: 243 case bfd_mach_kv4_1: 244 env.opc_table = kvx_kv4_v1_optab; 245 env.kvx_regfiles = kvx_kv4_v1_regfiles; 246 env.kvx_registers = kvx_kv4_v1_registers; 247 env.kvx_modifiers = kvx_kv4_v1_modifiers; 248 env.kvx_dec_registers = kvx_kv4_v1_dec_registers; 249 break; 250 } 251 252 env.kvx_max_dec_registers = env.kvx_regfiles[KVX_REGFILE_DEC_REGISTERS]; 253 254 if (info->disassembler_options) 255 parse_kvx_dis_options (info->disassembler_options); 256 257 env.initialized_p = 1; 258} 259 260static bool 261kvx_reassemble_bundle (int wordcount, int *_insncount) 262{ 263 264 /* Debugging flag. */ 265 int debug = 0; 266 267 /* Available resources. */ 268 int bcu_taken = 0; 269 int tca_taken = 0; 270 int alu0_taken = 0; 271 int alu1_taken = 0; 272 int mau_taken = 0; 273 int lsu_taken = 0; 274 275 if (debug) 276 fprintf (stderr, "kvx_reassemble_bundle: wordcount = %d\n", wordcount); 277 278 if (wordcount > KVXMAXBUNDLEWORDS) 279 { 280 if (debug) 281 fprintf (stderr, "bundle exceeds maximum size\n"); 282 return false; 283 } 284 285 struct instr_s instr[KVXMAXBUNDLEISSUE]; 286 memset (instr, 0, sizeof (instr)); 287 assert (KVXMAXBUNDLEISSUE >= BundleIssue__); 288 289 int i; 290 unsigned int j; 291 292 for (i = 0; i < wordcount; i++) 293 { 294 uint32_t syllable = bundle_words[i]; 295 switch (kvx_steering (syllable)) 296 { 297 case Steering_BCU: 298 /* BCU or TCA instruction. */ 299 if (i == 0) 300 { 301 if (kvx_is_tca_opcode (syllable)) 302 { 303 if (tca_taken) 304 { 305 if (debug) 306 fprintf (stderr, "Too many TCA instructions"); 307 return false; 308 } 309 if (debug) 310 fprintf (stderr, 311 "Syllable 0: Set valid on TCA for instr %d with 0x%x\n", 312 BundleIssue_TCA, syllable); 313 instr[BundleIssue_TCA].valid = 1; 314 instr[BundleIssue_TCA].opcode = syllable; 315 instr[BundleIssue_TCA].nb_syllables = 1; 316 tca_taken = 1; 317 } 318 else 319 { 320 if (debug) 321 fprintf (stderr, 322 "Syllable 0: Set valid on BCU for instr %d with 0x%x\n", 323 BundleIssue_BCU, syllable); 324 325 instr[BundleIssue_BCU].valid = 1; 326 instr[BundleIssue_BCU].opcode = syllable; 327 instr[BundleIssue_BCU].nb_syllables = 1; 328 bcu_taken = 1; 329 } 330 } 331 else 332 { 333 if (i == 1 && bcu_taken && kvx_is_tca_opcode (syllable)) 334 { 335 if (tca_taken) 336 { 337 if (debug) 338 fprintf (stderr, "Too many TCA instructions"); 339 return false; 340 } 341 if (debug) 342 fprintf (stderr, 343 "Syllable 0: Set valid on TCA for instr %d with 0x%x\n", 344 BundleIssue_TCA, syllable); 345 instr[BundleIssue_TCA].valid = 1; 346 instr[BundleIssue_TCA].opcode = syllable; 347 instr[BundleIssue_TCA].nb_syllables = 1; 348 tca_taken = 1; 349 } 350 else 351 { 352 /* Not first syllable in bundle, IMMX. */ 353 struct instr_s *instr_p = 354 &(instr[Extension_BundleIssue[kvx_extension (syllable)]]); 355 int immx_count = instr_p->immx_count; 356 if (immx_count > 1) 357 { 358 if (debug) 359 fprintf (stderr, "Too many IMMX syllables"); 360 return false; 361 } 362 instr_p->immx[immx_count] = syllable; 363 instr_p->immx_valid[immx_count] = 1; 364 instr_p->nb_syllables++; 365 if (debug) 366 fprintf (stderr, 367 "Set IMMX[%d] on instr %d for extension %d @ %d\n", 368 immx_count, 369 Extension_BundleIssue[kvx_extension (syllable)], 370 kvx_extension (syllable), i); 371 instr_p->immx_count = immx_count + 1; 372 } 373 } 374 break; 375 376 case Steering_ALU: 377 if (alu0_taken == 0) 378 { 379 if (debug) 380 fprintf (stderr, "Set valid on ALU0 for instr %d with 0x%x\n", 381 BundleIssue_ALU0, syllable); 382 instr[BundleIssue_ALU0].valid = 1; 383 instr[BundleIssue_ALU0].opcode = syllable; 384 instr[BundleIssue_ALU0].nb_syllables = 1; 385 alu0_taken = 1; 386 } 387 else if (alu1_taken == 0) 388 { 389 if (debug) 390 fprintf (stderr, "Set valid on ALU1 for instr %d with 0x%x\n", 391 BundleIssue_ALU1, syllable); 392 instr[BundleIssue_ALU1].valid = 1; 393 instr[BundleIssue_ALU1].opcode = syllable; 394 instr[BundleIssue_ALU1].nb_syllables = 1; 395 alu1_taken = 1; 396 } 397 else if (mau_taken == 0) 398 { 399 if (debug) 400 fprintf (stderr, 401 "Set valid on MAU (ALU) for instr %d with 0x%x\n", 402 BundleIssue_MAU, syllable); 403 instr[BundleIssue_MAU].valid = 1; 404 instr[BundleIssue_MAU].opcode = syllable; 405 instr[BundleIssue_MAU].nb_syllables = 1; 406 mau_taken = 1; 407 } 408 else if (lsu_taken == 0) 409 { 410 if (debug) 411 fprintf (stderr, 412 "Set valid on LSU (ALU) for instr %d with 0x%x\n", 413 BundleIssue_LSU, syllable); 414 instr[BundleIssue_LSU].valid = 1; 415 instr[BundleIssue_LSU].opcode = syllable; 416 instr[BundleIssue_LSU].nb_syllables = 1; 417 lsu_taken = 1; 418 } 419 else if (kvx_is_nop_opcode (syllable)) 420 { 421 if (debug) 422 fprintf (stderr, "Ignoring NOP (ALU) syllable\n"); 423 } 424 else 425 { 426 if (debug) 427 fprintf (stderr, "Too many ALU instructions"); 428 return false; 429 } 430 break; 431 432 case Steering_MAU: 433 if (mau_taken == 1) 434 { 435 if (debug) 436 fprintf (stderr, "Too many MAU instructions"); 437 return false; 438 } 439 else 440 { 441 if (debug) 442 fprintf (stderr, "Set valid on MAU for instr %d with 0x%x\n", 443 BundleIssue_MAU, syllable); 444 instr[BundleIssue_MAU].valid = 1; 445 instr[BundleIssue_MAU].opcode = syllable; 446 instr[BundleIssue_MAU].nb_syllables = 1; 447 mau_taken = 1; 448 } 449 break; 450 451 case Steering_LSU: 452 if (lsu_taken == 1) 453 { 454 if (debug) 455 fprintf (stderr, "Too many LSU instructions"); 456 return false; 457 } 458 else 459 { 460 if (debug) 461 fprintf (stderr, "Set valid on LSU for instr %d with 0x%x\n", 462 BundleIssue_LSU, syllable); 463 instr[BundleIssue_LSU].valid = 1; 464 instr[BundleIssue_LSU].opcode = syllable; 465 instr[BundleIssue_LSU].nb_syllables = 1; 466 lsu_taken = 1; 467 } 468 } 469 if (debug) 470 fprintf (stderr, "Continue %d < %d?\n", i, wordcount); 471 } 472 473 /* Fill bundle_insn and count read syllables. */ 474 int instr_idx = 0; 475 for (i = 0; i < KVXMAXBUNDLEISSUE; i++) 476 { 477 if (instr[i].valid == 1) 478 { 479 int syllable_idx = 0; 480 481 /* First copy opcode. */ 482 bundle_insn[instr_idx].syllables[syllable_idx++] = instr[i].opcode; 483 bundle_insn[instr_idx].len = 1; 484 485 for (j = 0; j < 2; j++) 486 { 487 if (instr[i].immx_valid[j]) 488 { 489 if (debug) 490 fprintf (stderr, "Instr %d valid immx[%d] is valid\n", i, 491 j); 492 bundle_insn[instr_idx].syllables[syllable_idx++] = 493 instr[i].immx[j]; 494 bundle_insn[instr_idx].len++; 495 } 496 } 497 498 if (debug) 499 fprintf (stderr, 500 "Instr %d valid, copying in bundle_insn (%d syllables <-> %d)\n", 501 i, bundle_insn[instr_idx].len, instr[i].nb_syllables); 502 instr_idx++; 503 } 504 } 505 506 if (debug) 507 fprintf (stderr, "End => %d instructions\n", instr_idx); 508 509 *_insncount = instr_idx; 510 return true; 511} 512 513struct decoded_insn 514{ 515 /* The entry in the opc_table. */ 516 struct kvxopc *opc; 517 /* The number of operands. */ 518 int nb_ops; 519 /* The content of an operands. */ 520 struct 521 { 522 enum 523 { 524 CAT_REGISTER, 525 CAT_MODIFIER, 526 CAT_IMMEDIATE, 527 } type; 528 /* The value of the operands. */ 529 uint64_t val; 530 /* If it is an immediate, its sign. */ 531 int sign; 532 /* If it is an immediate, is it pc relative. */ 533 int pcrel; 534 /* The width of the operand. */ 535 int width; 536 /* If it is a modifier, the modifier category. 537 An index in the modifier table. */ 538 int mod_idx; 539 } operands[KVXMAXOPERANDS]; 540}; 541 542static int 543decode_insn (bfd_vma memaddr, insn_t * insn, struct decoded_insn *res) 544{ 545 546 int found = 0; 547 int idx = 0; 548 for (struct kvxopc * op = env.opc_table; 549 op->as_op && (((char) op->as_op[0]) != 0); op++) 550 { 551 /* Find the format of this insn. */ 552 int opcode_match = 1; 553 554 if (op->wordcount != insn->len) 555 continue; 556 557 for (int i = 0; i < op->wordcount; i++) 558 if ((op->codewords[i].mask & insn->syllables[i]) != 559 op->codewords[i].opcode) 560 opcode_match = 0; 561 562 int encoding_space_flags = env.kvx_arch_size == 32 563 ? kvxOPCODE_FLAG_MODE32 : kvxOPCODE_FLAG_MODE64; 564 565 for (int i = 0; i < op->wordcount; i++) 566 if (!(op->codewords[i].flags & encoding_space_flags)) 567 opcode_match = 0; 568 569 if (opcode_match) 570 { 571 res->opc = op; 572 573 for (int i = 0; op->format[i]; i++) 574 { 575 struct kvx_bitfield *bf = op->format[i]->bfield; 576 int bf_nb = op->format[i]->bitfields; 577 int width = op->format[i]->width; 578 int type = op->format[i]->type; 579 const char *type_name = op->format[i]->tname; 580 int flags = op->format[i]->flags; 581 int shift = op->format[i]->shift; 582 int bias = op->format[i]->bias; 583 uint64_t value = 0; 584 585 for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++) 586 { 587 int insn_idx = (int) bf[bf_idx].to_offset / 32; 588 int to_offset = bf[bf_idx].to_offset % 32; 589 uint64_t encoded_value = 590 insn->syllables[insn_idx] >> to_offset; 591 encoded_value &= (1LL << bf[bf_idx].size) - 1; 592 value |= encoded_value << bf[bf_idx].from_offset; 593 } 594 if (flags & kvxSIGNED) 595 { 596 uint64_t signbit = 1LL << (width - 1); 597 value = (value ^ signbit) - signbit; 598 } 599 value = (value << shift) + bias; 600 601#define KVX_PRINT_REG(regfile,value) \ 602 if(env.kvx_regfiles[regfile]+value < env.kvx_max_dec_registers) { \ 603 res->operands[idx].val = env.kvx_dec_registers[env.kvx_regfiles[regfile]+value]; \ 604 res->operands[idx].type = CAT_REGISTER; \ 605 idx++; \ 606 } else { \ 607 res->operands[idx].val = ~0; \ 608 res->operands[idx].type = CAT_REGISTER; \ 609 idx++; \ 610 } 611 612 if (env.opc_table == kvx_kv3_v1_optab) 613 { 614 switch (type) 615 { 616 case RegClass_kv3_v1_singleReg: 617 KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) 618 break; 619 case RegClass_kv3_v1_pairedReg: 620 KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) 621 break; 622 case RegClass_kv3_v1_quadReg: 623 KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) 624 break; 625 case RegClass_kv3_v1_systemReg: 626 case RegClass_kv3_v1_aloneReg: 627 case RegClass_kv3_v1_onlyraReg: 628 case RegClass_kv3_v1_onlygetReg: 629 case RegClass_kv3_v1_onlysetReg: 630 case RegClass_kv3_v1_onlyfxReg: 631 KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) 632 break; 633 case RegClass_kv3_v1_coproReg0M4: 634 case RegClass_kv3_v1_coproReg1M4: 635 case RegClass_kv3_v1_coproReg2M4: 636 case RegClass_kv3_v1_coproReg3M4: 637 KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) 638 break; 639 case RegClass_kv3_v1_blockRegE: 640 case RegClass_kv3_v1_blockRegO: 641 case RegClass_kv3_v1_blockReg0M4: 642 case RegClass_kv3_v1_blockReg1M4: 643 case RegClass_kv3_v1_blockReg2M4: 644 case RegClass_kv3_v1_blockReg3M4: 645 KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) 646 break; 647 case RegClass_kv3_v1_vectorReg: 648 case RegClass_kv3_v1_vectorRegE: 649 case RegClass_kv3_v1_vectorRegO: 650 KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) 651 break; 652 case RegClass_kv3_v1_tileReg: 653 KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) 654 break; 655 case RegClass_kv3_v1_matrixReg: 656 KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) 657 break; 658 case Immediate_kv3_v1_sysnumber: 659 case Immediate_kv3_v1_signed10: 660 case Immediate_kv3_v1_signed16: 661 case Immediate_kv3_v1_signed27: 662 case Immediate_kv3_v1_wrapped32: 663 case Immediate_kv3_v1_signed37: 664 case Immediate_kv3_v1_signed43: 665 case Immediate_kv3_v1_signed54: 666 case Immediate_kv3_v1_wrapped64: 667 case Immediate_kv3_v1_unsigned6: 668 res->operands[idx].val = value; 669 res->operands[idx].sign = flags & kvxSIGNED; 670 res->operands[idx].width = width; 671 res->operands[idx].type = CAT_IMMEDIATE; 672 res->operands[idx].pcrel = 0; 673 idx++; 674 break; 675 case Immediate_kv3_v1_pcrel17: 676 case Immediate_kv3_v1_pcrel27: 677 res->operands[idx].val = value + memaddr; 678 res->operands[idx].sign = flags & kvxSIGNED; 679 res->operands[idx].width = width; 680 res->operands[idx].type = CAT_IMMEDIATE; 681 res->operands[idx].pcrel = 1; 682 idx++; 683 break; 684 case Modifier_kv3_v1_column: 685 case Modifier_kv3_v1_comparison: 686 case Modifier_kv3_v1_doscale: 687 case Modifier_kv3_v1_exunum: 688 case Modifier_kv3_v1_floatcomp: 689 case Modifier_kv3_v1_qindex: 690 case Modifier_kv3_v1_rectify: 691 case Modifier_kv3_v1_rounding: 692 case Modifier_kv3_v1_roundint: 693 case Modifier_kv3_v1_saturate: 694 case Modifier_kv3_v1_scalarcond: 695 case Modifier_kv3_v1_silent: 696 case Modifier_kv3_v1_simplecond: 697 case Modifier_kv3_v1_speculate: 698 case Modifier_kv3_v1_splat32: 699 case Modifier_kv3_v1_variant: 700 { 701 int sz = 0; 702 int mod_idx = type - Modifier_kv3_v1_column; 703 for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz); 704 const char *mod = value < (unsigned) sz 705 ? env.kvx_modifiers[mod_idx][value] : NULL; 706 if (!mod) goto retry; 707 res->operands[idx].val = value; 708 res->operands[idx].type = CAT_MODIFIER; 709 res->operands[idx].mod_idx = mod_idx; 710 idx++; 711 } 712 break; 713 default: 714 fprintf (stderr, "error: unexpected operand type (%s)\n", 715 type_name); 716 exit (-1); 717 }; 718 } 719 else if (env.opc_table == kvx_kv3_v2_optab) 720 { 721 switch (type) 722 { 723 case RegClass_kv3_v2_singleReg: 724 KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) 725 break; 726 case RegClass_kv3_v2_pairedReg: 727 KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) 728 break; 729 case RegClass_kv3_v2_quadReg: 730 KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) 731 break; 732 case RegClass_kv3_v2_systemReg: 733 case RegClass_kv3_v2_aloneReg: 734 case RegClass_kv3_v2_onlyraReg: 735 case RegClass_kv3_v2_onlygetReg: 736 case RegClass_kv3_v2_onlysetReg: 737 case RegClass_kv3_v2_onlyfxReg: 738 KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) 739 break; 740 case RegClass_kv3_v2_coproReg: 741 case RegClass_kv3_v2_coproReg0M4: 742 case RegClass_kv3_v2_coproReg1M4: 743 case RegClass_kv3_v2_coproReg2M4: 744 case RegClass_kv3_v2_coproReg3M4: 745 KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) 746 break; 747 case RegClass_kv3_v2_blockReg: 748 case RegClass_kv3_v2_blockRegE: 749 case RegClass_kv3_v2_blockRegO: 750 KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) 751 break; 752 case RegClass_kv3_v2_vectorReg: 753 KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) 754 break; 755 case RegClass_kv3_v2_tileReg: 756 KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) 757 break; 758 case RegClass_kv3_v2_matrixReg: 759 KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) 760 break; 761 case RegClass_kv3_v2_buffer2Reg: 762 KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value) 763 break; 764 case RegClass_kv3_v2_buffer4Reg: 765 KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value) 766 break; 767 case RegClass_kv3_v2_buffer8Reg: 768 KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value) 769 break; 770 case RegClass_kv3_v2_buffer16Reg: 771 KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value) 772 break; 773 case RegClass_kv3_v2_buffer32Reg: 774 KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value) 775 break; 776 case RegClass_kv3_v2_buffer64Reg: 777 KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value) 778 break; 779 case Immediate_kv3_v2_brknumber: 780 case Immediate_kv3_v2_sysnumber: 781 case Immediate_kv3_v2_signed10: 782 case Immediate_kv3_v2_signed16: 783 case Immediate_kv3_v2_signed27: 784 case Immediate_kv3_v2_wrapped32: 785 case Immediate_kv3_v2_signed37: 786 case Immediate_kv3_v2_signed43: 787 case Immediate_kv3_v2_signed54: 788 case Immediate_kv3_v2_wrapped64: 789 case Immediate_kv3_v2_unsigned6: 790 res->operands[idx].val = value; 791 res->operands[idx].sign = flags & kvxSIGNED; 792 res->operands[idx].width = width; 793 res->operands[idx].type = CAT_IMMEDIATE; 794 res->operands[idx].pcrel = 0; 795 idx++; 796 break; 797 case Immediate_kv3_v2_pcrel27: 798 case Immediate_kv3_v2_pcrel17: 799 res->operands[idx].val = value + memaddr; 800 res->operands[idx].sign = flags & kvxSIGNED; 801 res->operands[idx].width = width; 802 res->operands[idx].type = CAT_IMMEDIATE; 803 res->operands[idx].pcrel = 1; 804 idx++; 805 break; 806 case Modifier_kv3_v2_accesses: 807 case Modifier_kv3_v2_boolcas: 808 case Modifier_kv3_v2_cachelev: 809 case Modifier_kv3_v2_channel: 810 case Modifier_kv3_v2_coherency: 811 case Modifier_kv3_v2_comparison: 812 case Modifier_kv3_v2_conjugate: 813 case Modifier_kv3_v2_doscale: 814 case Modifier_kv3_v2_exunum: 815 case Modifier_kv3_v2_floatcomp: 816 case Modifier_kv3_v2_hindex: 817 case Modifier_kv3_v2_lsomask: 818 case Modifier_kv3_v2_lsumask: 819 case Modifier_kv3_v2_lsupack: 820 case Modifier_kv3_v2_qindex: 821 case Modifier_kv3_v2_rounding: 822 case Modifier_kv3_v2_scalarcond: 823 case Modifier_kv3_v2_shuffleV: 824 case Modifier_kv3_v2_shuffleX: 825 case Modifier_kv3_v2_silent: 826 case Modifier_kv3_v2_simplecond: 827 case Modifier_kv3_v2_speculate: 828 case Modifier_kv3_v2_splat32: 829 case Modifier_kv3_v2_transpose: 830 case Modifier_kv3_v2_variant: 831 { 832 int sz = 0; 833 int mod_idx = type - Modifier_kv3_v2_accesses; 834 for (sz = 0; env.kvx_modifiers[mod_idx][sz]; 835 ++sz); 836 const char *mod = value < (unsigned) sz 837 ? env.kvx_modifiers[mod_idx][value] : NULL; 838 if (!mod) goto retry; 839 res->operands[idx].val = value; 840 res->operands[idx].type = CAT_MODIFIER; 841 res->operands[idx].mod_idx = mod_idx; 842 idx++; 843 }; 844 break; 845 default: 846 fprintf (stderr, 847 "error: unexpected operand type (%s)\n", 848 type_name); 849 exit (-1); 850 }; 851 } 852 else if (env.opc_table == kvx_kv4_v1_optab) 853 { 854 switch (type) 855 { 856 857 case RegClass_kv4_v1_singleReg: 858 KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) 859 break; 860 case RegClass_kv4_v1_pairedReg: 861 KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) 862 break; 863 case RegClass_kv4_v1_quadReg: 864 KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) 865 break; 866 case RegClass_kv4_v1_systemReg: 867 case RegClass_kv4_v1_aloneReg: 868 case RegClass_kv4_v1_onlyraReg: 869 case RegClass_kv4_v1_onlygetReg: 870 case RegClass_kv4_v1_onlysetReg: 871 case RegClass_kv4_v1_onlyfxReg: 872 KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) 873 break; 874 case RegClass_kv4_v1_coproReg: 875 case RegClass_kv4_v1_coproReg0M4: 876 case RegClass_kv4_v1_coproReg1M4: 877 case RegClass_kv4_v1_coproReg2M4: 878 case RegClass_kv4_v1_coproReg3M4: 879 KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) 880 break; 881 case RegClass_kv4_v1_blockReg: 882 case RegClass_kv4_v1_blockRegE: 883 case RegClass_kv4_v1_blockRegO: 884 KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) 885 break; 886 case RegClass_kv4_v1_vectorReg: 887 KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) 888 break; 889 case RegClass_kv4_v1_tileReg: 890 KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) 891 break; 892 case RegClass_kv4_v1_matrixReg: 893 KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) 894 break; 895 case RegClass_kv4_v1_buffer2Reg: 896 KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value) 897 break; 898 case RegClass_kv4_v1_buffer4Reg: 899 KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value) 900 break; 901 case RegClass_kv4_v1_buffer8Reg: 902 KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value) 903 break; 904 case RegClass_kv4_v1_buffer16Reg: 905 KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value) 906 break; 907 case RegClass_kv4_v1_buffer32Reg: 908 KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value) 909 break; 910 case RegClass_kv4_v1_buffer64Reg: 911 KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value) 912 break; 913 case Immediate_kv4_v1_brknumber: 914 case Immediate_kv4_v1_sysnumber: 915 case Immediate_kv4_v1_signed10: 916 case Immediate_kv4_v1_signed16: 917 case Immediate_kv4_v1_signed27: 918 case Immediate_kv4_v1_wrapped32: 919 case Immediate_kv4_v1_signed37: 920 case Immediate_kv4_v1_signed43: 921 case Immediate_kv4_v1_signed54: 922 case Immediate_kv4_v1_wrapped64: 923 case Immediate_kv4_v1_unsigned6: 924 res->operands[idx].val = value; 925 res->operands[idx].sign = flags & kvxSIGNED; 926 res->operands[idx].width = width; 927 res->operands[idx].type = CAT_IMMEDIATE; 928 res->operands[idx].pcrel = 0; 929 idx++; 930 break; 931 case Immediate_kv4_v1_pcrel27: 932 case Immediate_kv4_v1_pcrel17: 933 res->operands[idx].val = value + memaddr; 934 res->operands[idx].sign = flags & kvxSIGNED; 935 res->operands[idx].width = width; 936 res->operands[idx].type = CAT_IMMEDIATE; 937 res->operands[idx].pcrel = 1; 938 idx++; 939 break; 940 case Modifier_kv4_v1_accesses: 941 case Modifier_kv4_v1_boolcas: 942 case Modifier_kv4_v1_cachelev: 943 case Modifier_kv4_v1_channel: 944 case Modifier_kv4_v1_coherency: 945 case Modifier_kv4_v1_comparison: 946 case Modifier_kv4_v1_conjugate: 947 case Modifier_kv4_v1_doscale: 948 case Modifier_kv4_v1_exunum: 949 case Modifier_kv4_v1_floatcomp: 950 case Modifier_kv4_v1_hindex: 951 case Modifier_kv4_v1_lsomask: 952 case Modifier_kv4_v1_lsumask: 953 case Modifier_kv4_v1_lsupack: 954 case Modifier_kv4_v1_qindex: 955 case Modifier_kv4_v1_rounding: 956 case Modifier_kv4_v1_scalarcond: 957 case Modifier_kv4_v1_shuffleV: 958 case Modifier_kv4_v1_shuffleX: 959 case Modifier_kv4_v1_silent: 960 case Modifier_kv4_v1_simplecond: 961 case Modifier_kv4_v1_speculate: 962 case Modifier_kv4_v1_splat32: 963 case Modifier_kv4_v1_transpose: 964 case Modifier_kv4_v1_variant: 965 { 966 int sz = 0; 967 int mod_idx = type - Modifier_kv4_v1_accesses; 968 for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz); 969 const char *mod = value < (unsigned) sz 970 ? env.kvx_modifiers[mod_idx][value] : NULL; 971 if (!mod) goto retry; 972 res->operands[idx].val = value; 973 res->operands[idx].type = CAT_MODIFIER; 974 res->operands[idx].mod_idx = mod_idx; 975 idx++; 976 } 977 break; 978 default: 979 fprintf (stderr, "error: unexpected operand type (%s)\n", 980 type_name); 981 exit (-1); 982 }; 983 } 984 985#undef KVX_PRINT_REG 986 } 987 988 found = 1; 989 break; 990 retry:; 991 idx = 0; 992 continue; 993 } 994 } 995 res->nb_ops = idx; 996 return found; 997} 998 999int 1000print_insn_kvx (bfd_vma memaddr, struct disassemble_info *info) 1001{ 1002 static int insnindex = 0; 1003 static int insncount = 0; 1004 insn_t *insn; 1005 int readsofar = 0; 1006 int found = 0; 1007 int invalid_bundle = 0; 1008 1009 if (!env.initialized_p) 1010 kvx_dis_init (info); 1011 1012 /* Clear instruction information field. */ 1013 info->insn_info_valid = 0; 1014 info->branch_delay_insns = 0; 1015 info->data_size = 0; 1016 info->insn_type = dis_noninsn; 1017 info->target = 0; 1018 info->target2 = 0; 1019 1020 /* Set line length. */ 1021 info->bytes_per_line = 16; 1022 1023 1024 /* If this is the beginning of the bundle, read BUNDLESIZE words and apply 1025 decentrifugate function. */ 1026 if (insnindex == 0) 1027 { 1028 int wordcount; 1029 for (wordcount = 0; wordcount < KVXMAXBUNDLEWORDS; wordcount++) 1030 { 1031 int status; 1032 status = 1033 (*info->read_memory_func) (memaddr + 4 * wordcount, 1034 (bfd_byte *) (bundle_words + 1035 wordcount), 4, info); 1036 if (status != 0) 1037 { 1038 (*info->memory_error_func) (status, memaddr + 4 * wordcount, 1039 info); 1040 return -1; 1041 } 1042 if (!kvx_has_parallel_bit (bundle_words[wordcount])) 1043 break; 1044 } 1045 wordcount++; 1046 invalid_bundle = !kvx_reassemble_bundle (wordcount, &insncount); 1047 } 1048 1049 assert (insnindex < KVXMAXBUNDLEISSUE); 1050 insn = &(bundle_insn[insnindex]); 1051 readsofar = insn->len * 4; 1052 insnindex++; 1053 1054 if (opt_pretty) 1055 { 1056 (*info->fprintf_func) (info->stream, "[ "); 1057 for (int i = 0; i < insn->len; i++) 1058 (*info->fprintf_func) (info->stream, "%08x ", insn->syllables[i]); 1059 (*info->fprintf_func) (info->stream, "] "); 1060 } 1061 1062 /* Check for extension to right iff this is not the end of bundle. */ 1063 1064 struct decoded_insn dec; 1065 memset (&dec, 0, sizeof dec); 1066 if (!invalid_bundle && (found = decode_insn (memaddr, insn, &dec))) 1067 { 1068 int ch; 1069 (*info->fprintf_func) (info->stream, "%s", dec.opc->as_op); 1070 const char *fmtp = dec.opc->fmtstring; 1071 for (int i = 0; i < dec.nb_ops; ++i) 1072 { 1073 /* Print characters in the format string up to the following % or nul. */ 1074 while ((ch = *fmtp) && ch != '%') 1075 { 1076 (*info->fprintf_func) (info->stream, "%c", ch); 1077 fmtp++; 1078 } 1079 1080 /* Skip past %s. */ 1081 if (ch == '%') 1082 { 1083 ch = *fmtp++; 1084 fmtp++; 1085 } 1086 1087 switch (dec.operands[i].type) 1088 { 1089 case CAT_REGISTER: 1090 (*info->fprintf_func) (info->stream, "%s", 1091 env.kvx_registers[dec.operands[i].val].name); 1092 break; 1093 case CAT_MODIFIER: 1094 { 1095 const char *mod = env.kvx_modifiers[dec.operands[i].mod_idx][dec.operands[i].val]; 1096 (*info->fprintf_func) (info->stream, "%s", !mod || !strcmp (mod, ".") ? "" : mod); 1097 } 1098 break; 1099 case CAT_IMMEDIATE: 1100 { 1101 if (dec.operands[i].pcrel) 1102 { 1103 /* Fill in instruction information. */ 1104 info->insn_info_valid = 1; 1105 info->insn_type = 1106 dec.operands[i].width == 1107 17 ? dis_condbranch : dis_branch; 1108 info->target = dec.operands[i].val; 1109 1110 info->print_address_func (dec.operands[i].val, info); 1111 } 1112 else if (dec.operands[i].sign) 1113 { 1114 if (dec.operands[i].width <= 32) 1115 { 1116 (*info->fprintf_func) (info->stream, "%" PRId32 " (0x%" PRIx32 ")", 1117 (int32_t) dec.operands[i].val, 1118 (int32_t) dec.operands[i].val); 1119 } 1120 else 1121 { 1122 (*info->fprintf_func) (info->stream, "%" PRId64 " (0x%" PRIx64 ")", 1123 dec.operands[i].val, 1124 dec.operands[i].val); 1125 } 1126 } 1127 else 1128 { 1129 if (dec.operands[i].width <= 32) 1130 { 1131 (*info->fprintf_func) (info->stream, "%" PRIu32 " (0x%" PRIx32 ")", 1132 (uint32_t) dec.operands[i]. 1133 val, 1134 (uint32_t) dec.operands[i]. 1135 val); 1136 } 1137 else 1138 { 1139 (*info->fprintf_func) (info->stream, "%" PRIu64 " (0x%" PRIx64 ")", 1140 (uint64_t) dec. 1141 operands[i].val, 1142 (uint64_t) dec. 1143 operands[i].val); 1144 } 1145 } 1146 } 1147 break; 1148 default: 1149 break; 1150 1151 } 1152 } 1153 1154 while ((ch = *fmtp)) 1155 { 1156 (*info->fprintf_styled_func) (info->stream, dis_style_text, "%c", 1157 ch); 1158 fmtp++; 1159 } 1160 } 1161 else 1162 { 1163 (*info->fprintf_func) (info->stream, "*** invalid opcode ***\n"); 1164 insnindex = 0; 1165 readsofar = 4; 1166 } 1167 1168 if (found && (insnindex == insncount)) 1169 { 1170 (*info->fprintf_func) (info->stream, ";;"); 1171 if (!opt_compact_assembly) 1172 (*info->fprintf_func) (info->stream, "\n"); 1173 insnindex = 0; 1174 } 1175 1176 return readsofar; 1177} 1178 1179/* This function searches in the current bundle for the instructions required 1180 by unwinding. For prologue: 1181 (1) addd $r12 = $r12, <res_stack> 1182 (2) get <gpr_ra_reg> = $ra 1183 (3) sd <ofs>[$r12] = <gpr_ra_reg> or sq/so containing <gpr_ra_reg> 1184 (4) sd <ofs>[$r12] = $r14 or sq/so containing r14 1185 (5) addd $r14 = $r12, <fp_ofs> or copyd $r14 = $r12 1186 The only difference seen between the code generated by gcc and clang 1187 is the setting/resetting r14. gcc could also generate copyd $r14=$r12 1188 instead of add addd $r14 = $r12, <ofs> when <ofs> is 0. 1189 Vice-versa, <ofs> is not guaranteed to be 0 for clang, so, clang 1190 could also generate addd instead of copyd 1191 (6) call, icall, goto, igoto, cb., ret 1192 For epilogue: 1193 (1) addd $r12 = $r12, <res_stack> 1194 (2) addd $r12 = $r14, <offset> or copyd $r12 = $r14 1195 Same comment as prologue (5). 1196 (3) ret, goto 1197 (4) call, icall, igoto, cb. */ 1198 1199int 1200decode_prologue_epilogue_bundle (bfd_vma memaddr, 1201 struct disassemble_info *info, 1202 struct kvx_prologue_epilogue_bundle *peb) 1203{ 1204 int i, nb_insn, nb_syl; 1205 1206 peb->nb_insn = 0; 1207 1208 if (info->arch != bfd_arch_kvx) 1209 return -1; 1210 1211 if (!env.initialized_p) 1212 kvx_dis_init (info); 1213 1214 /* Read the bundle. */ 1215 for (nb_syl = 0; nb_syl < KVXMAXBUNDLEWORDS; nb_syl++) 1216 { 1217 if ((*info->read_memory_func) (memaddr + 4 * nb_syl, 1218 (bfd_byte *) &bundle_words[nb_syl], 4, 1219 info)) 1220 return -1; 1221 if (!kvx_has_parallel_bit (bundle_words[nb_syl])) 1222 break; 1223 } 1224 nb_syl++; 1225 if (!kvx_reassemble_bundle (nb_syl, &nb_insn)) 1226 return -1; 1227 1228 /* Check for extension to right if this is not the end of bundle 1229 find the format of this insn. */ 1230 for (int idx_insn = 0; idx_insn < nb_insn; idx_insn++) 1231 { 1232 insn_t *insn = &bundle_insn[idx_insn]; 1233 int is_add = 0, is_get = 0, is_a_peb_insn = 0, is_copyd = 0; 1234 1235 struct decoded_insn dec; 1236 memset (&dec, 0, sizeof dec); 1237 if (!decode_insn (memaddr, insn, &dec)) 1238 continue; 1239 1240 const char *op_name = dec.opc->as_op; 1241 struct kvx_prologue_epilogue_insn *crt_peb_insn; 1242 1243 crt_peb_insn = &peb->insn[peb->nb_insn]; 1244 crt_peb_insn->nb_gprs = 0; 1245 1246 if (!strcmp (op_name, "addd")) 1247 is_add = 1; 1248 else if (!strcmp (op_name, "copyd")) 1249 is_copyd = 1; 1250 else if (!strcmp (op_name, "get")) 1251 is_get = 1; 1252 else if (!strcmp (op_name, "sd")) 1253 { 1254 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SD; 1255 is_a_peb_insn = 1; 1256 } 1257 else if (!strcmp (op_name, "sq")) 1258 { 1259 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SQ; 1260 is_a_peb_insn = 1; 1261 } 1262 else if (!strcmp (op_name, "so")) 1263 { 1264 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SO; 1265 is_a_peb_insn = 1; 1266 } 1267 else if (!strcmp (op_name, "ret")) 1268 { 1269 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_RET; 1270 is_a_peb_insn = 1; 1271 } 1272 else if (!strcmp (op_name, "goto")) 1273 { 1274 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GOTO; 1275 is_a_peb_insn = 1; 1276 } 1277 else if (!strcmp (op_name, "igoto")) 1278 { 1279 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_IGOTO; 1280 is_a_peb_insn = 1; 1281 } 1282 else if (!strcmp (op_name, "call") || !strcmp (op_name, "icall")) 1283 { 1284 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CALL; 1285 is_a_peb_insn = 1; 1286 } 1287 else if (!strncmp (op_name, "cb", 2)) 1288 { 1289 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CB; 1290 is_a_peb_insn = 1; 1291 } 1292 else 1293 continue; 1294 1295 for (i = 0; dec.opc->format[i]; i++) 1296 { 1297 struct kvx_operand *fmt = dec.opc->format[i]; 1298 struct kvx_bitfield *bf = fmt->bfield; 1299 int bf_nb = fmt->bitfields; 1300 int width = fmt->width; 1301 int type = fmt->type; 1302 int flags = fmt->flags; 1303 int shift = fmt->shift; 1304 int bias = fmt->bias; 1305 uint64_t encoded_value, value = 0; 1306 1307 for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++) 1308 { 1309 int insn_idx = (int) bf[bf_idx].to_offset / 32; 1310 int to_offset = bf[bf_idx].to_offset % 32; 1311 encoded_value = insn->syllables[insn_idx] >> to_offset; 1312 encoded_value &= (1LL << bf[bf_idx].size) - 1; 1313 value |= encoded_value << bf[bf_idx].from_offset; 1314 } 1315 if (flags & kvxSIGNED) 1316 { 1317 uint64_t signbit = 1LL << (width - 1); 1318 value = (value ^ signbit) - signbit; 1319 } 1320 value = (value << shift) + bias; 1321 1322#define chk_type(core_, val_) \ 1323 (env.opc_table == kvx_## core_ ##_optab && type == (val_)) 1324 1325 if (chk_type (kv3_v1, RegClass_kv3_v1_singleReg) 1326 || chk_type (kv3_v2, RegClass_kv3_v2_singleReg) 1327 || chk_type (kv4_v1, RegClass_kv4_v1_singleReg)) 1328 { 1329 if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value 1330 >= env.kvx_max_dec_registers) 1331 return -1; 1332 if (is_add && i < 2) 1333 { 1334 if (i == 0) 1335 { 1336 if (value == KVX_GPR_REG_SP) 1337 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_SP; 1338 else if (value == KVX_GPR_REG_FP) 1339 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP; 1340 else 1341 is_add = 0; 1342 } 1343 else if (i == 1) 1344 { 1345 if (value == KVX_GPR_REG_SP) 1346 is_a_peb_insn = 1; 1347 else if (value == KVX_GPR_REG_FP 1348 && crt_peb_insn->insn_type 1349 == KVX_PROL_EPIL_INSN_ADD_SP) 1350 { 1351 crt_peb_insn->insn_type 1352 = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP; 1353 is_a_peb_insn = 1; 1354 } 1355 else 1356 is_add = 0; 1357 } 1358 } 1359 else if (is_copyd && i < 2) 1360 { 1361 if (i == 0) 1362 { 1363 if (value == KVX_GPR_REG_FP) 1364 { 1365 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP; 1366 crt_peb_insn->immediate = 0; 1367 } 1368 else if (value == KVX_GPR_REG_SP) 1369 { 1370 crt_peb_insn->insn_type 1371 = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP; 1372 crt_peb_insn->immediate = 0; 1373 } 1374 else 1375 is_copyd = 0; 1376 } 1377 else if (i == 1) 1378 { 1379 if (value == KVX_GPR_REG_SP 1380 && crt_peb_insn->insn_type 1381 == KVX_PROL_EPIL_INSN_ADD_FP) 1382 is_a_peb_insn = 1; 1383 else if (value == KVX_GPR_REG_FP 1384 && crt_peb_insn->insn_type 1385 == KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP) 1386 is_a_peb_insn = 1; 1387 else 1388 is_copyd = 0; 1389 } 1390 } 1391 else 1392 crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value; 1393 } 1394 else if (chk_type (kv3_v1, RegClass_kv3_v1_pairedReg) 1395 || chk_type (kv3_v2, RegClass_kv3_v2_pairedReg) 1396 || chk_type (kv4_v1, RegClass_kv4_v1_pairedReg)) 1397 crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 2; 1398 else if (chk_type (kv3_v1, RegClass_kv3_v1_quadReg) 1399 || chk_type (kv3_v2, RegClass_kv3_v2_quadReg) 1400 || chk_type (kv4_v1, RegClass_kv4_v1_quadReg)) 1401 crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 4; 1402 else if (chk_type (kv3_v1, RegClass_kv3_v1_systemReg) 1403 || chk_type (kv3_v2, RegClass_kv3_v2_systemReg) 1404 || chk_type (kv4_v1, RegClass_kv4_v1_systemReg) 1405 || chk_type (kv3_v1, RegClass_kv3_v1_aloneReg) 1406 || chk_type (kv3_v2, RegClass_kv3_v2_aloneReg) 1407 || chk_type (kv4_v1, RegClass_kv4_v1_aloneReg) 1408 || chk_type (kv3_v1, RegClass_kv3_v1_onlyraReg) 1409 || chk_type (kv3_v2, RegClass_kv3_v2_onlyraReg) 1410 || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg) 1411 || chk_type (kv3_v1, RegClass_kv3_v1_onlygetReg) 1412 || chk_type (kv3_v2, RegClass_kv3_v2_onlygetReg) 1413 || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg) 1414 || chk_type (kv3_v1, RegClass_kv3_v1_onlysetReg) 1415 || chk_type (kv3_v2, RegClass_kv3_v2_onlysetReg) 1416 || chk_type (kv4_v1, RegClass_kv4_v1_onlysetReg) 1417 || chk_type (kv3_v1, RegClass_kv3_v1_onlyfxReg) 1418 || chk_type (kv3_v2, RegClass_kv3_v2_onlyfxReg) 1419 || chk_type (kv4_v1, RegClass_kv4_v1_onlyfxReg)) 1420 { 1421 if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value 1422 >= env.kvx_max_dec_registers) 1423 return -1; 1424 if (is_get && !strcmp (env.kvx_registers[env.kvx_dec_registers[env.kvx_regfiles[KVX_REGFILE_DEC_SFR] + value]].name, "$ra")) 1425 { 1426 crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GET_RA; 1427 is_a_peb_insn = 1; 1428 } 1429 } 1430 else if (chk_type (kv3_v1, RegClass_kv3_v1_coproReg) 1431 || chk_type (kv3_v2, RegClass_kv3_v2_coproReg) 1432 || chk_type (kv4_v1, RegClass_kv4_v1_coproReg) 1433 || chk_type (kv3_v1, RegClass_kv3_v1_blockReg) 1434 || chk_type (kv3_v2, RegClass_kv3_v2_blockReg) 1435 || chk_type (kv4_v1, RegClass_kv4_v1_blockReg) 1436 || chk_type (kv3_v1, RegClass_kv3_v1_vectorReg) 1437 || chk_type (kv3_v2, RegClass_kv3_v2_vectorReg) 1438 || chk_type (kv4_v1, RegClass_kv4_v1_vectorReg) 1439 || chk_type (kv3_v1, RegClass_kv3_v1_tileReg) 1440 || chk_type (kv3_v2, RegClass_kv3_v2_tileReg) 1441 || chk_type (kv4_v1, RegClass_kv4_v1_tileReg) 1442 || chk_type (kv3_v1, RegClass_kv3_v1_matrixReg) 1443 || chk_type (kv3_v2, RegClass_kv3_v2_matrixReg) 1444 || chk_type (kv4_v1, RegClass_kv4_v1_matrixReg) 1445 || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond) 1446 || chk_type (kv3_v1, Modifier_kv3_v1_column) 1447 || chk_type (kv3_v1, Modifier_kv3_v1_comparison) 1448 || chk_type (kv3_v1, Modifier_kv3_v1_doscale) 1449 || chk_type (kv3_v1, Modifier_kv3_v1_exunum) 1450 || chk_type (kv3_v1, Modifier_kv3_v1_floatcomp) 1451 || chk_type (kv3_v1, Modifier_kv3_v1_qindex) 1452 || chk_type (kv3_v1, Modifier_kv3_v1_rectify) 1453 || chk_type (kv3_v1, Modifier_kv3_v1_rounding) 1454 || chk_type (kv3_v1, Modifier_kv3_v1_roundint) 1455 || chk_type (kv3_v1, Modifier_kv3_v1_saturate) 1456 || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond) 1457 || chk_type (kv3_v1, Modifier_kv3_v1_silent) 1458 || chk_type (kv3_v1, Modifier_kv3_v1_simplecond) 1459 || chk_type (kv3_v1, Modifier_kv3_v1_speculate) 1460 || chk_type (kv3_v1, Modifier_kv3_v1_splat32) 1461 || chk_type (kv3_v1, Modifier_kv3_v1_variant) 1462 || chk_type (kv3_v2, Modifier_kv3_v2_accesses) 1463 || chk_type (kv3_v2, Modifier_kv3_v2_boolcas) 1464 || chk_type (kv3_v2, Modifier_kv3_v2_cachelev) 1465 || chk_type (kv3_v2, Modifier_kv3_v2_channel) 1466 || chk_type (kv3_v2, Modifier_kv3_v2_coherency) 1467 || chk_type (kv3_v2, Modifier_kv3_v2_comparison) 1468 || chk_type (kv3_v2, Modifier_kv3_v2_conjugate) 1469 || chk_type (kv3_v2, Modifier_kv3_v2_doscale) 1470 || chk_type (kv3_v2, Modifier_kv3_v2_exunum) 1471 || chk_type (kv3_v2, Modifier_kv3_v2_floatcomp) 1472 || chk_type (kv3_v2, Modifier_kv3_v2_hindex) 1473 || chk_type (kv3_v2, Modifier_kv3_v2_lsomask) 1474 || chk_type (kv3_v2, Modifier_kv3_v2_lsumask) 1475 || chk_type (kv3_v2, Modifier_kv3_v2_lsupack) 1476 || chk_type (kv3_v2, Modifier_kv3_v2_qindex) 1477 || chk_type (kv3_v2, Modifier_kv3_v2_rounding) 1478 || chk_type (kv3_v2, Modifier_kv3_v2_scalarcond) 1479 || chk_type (kv3_v2, Modifier_kv3_v2_shuffleV) 1480 || chk_type (kv3_v2, Modifier_kv3_v2_shuffleX) 1481 || chk_type (kv3_v2, Modifier_kv3_v2_silent) 1482 || chk_type (kv3_v2, Modifier_kv3_v2_simplecond) 1483 || chk_type (kv3_v2, Modifier_kv3_v2_speculate) 1484 || chk_type (kv3_v2, Modifier_kv3_v2_splat32) 1485 || chk_type (kv3_v2, Modifier_kv3_v2_transpose) 1486 || chk_type (kv3_v2, Modifier_kv3_v2_variant) 1487 || chk_type (kv4_v1, Modifier_kv4_v1_accesses) 1488 || chk_type (kv4_v1, Modifier_kv4_v1_boolcas) 1489 || chk_type (kv4_v1, Modifier_kv4_v1_cachelev) 1490 || chk_type (kv4_v1, Modifier_kv4_v1_channel) 1491 || chk_type (kv4_v1, Modifier_kv4_v1_coherency) 1492 || chk_type (kv4_v1, Modifier_kv4_v1_comparison) 1493 || chk_type (kv4_v1, Modifier_kv4_v1_conjugate) 1494 || chk_type (kv4_v1, Modifier_kv4_v1_doscale) 1495 || chk_type (kv4_v1, Modifier_kv4_v1_exunum) 1496 || chk_type (kv4_v1, Modifier_kv4_v1_floatcomp) 1497 || chk_type (kv4_v1, Modifier_kv4_v1_hindex) 1498 || chk_type (kv4_v1, Modifier_kv4_v1_lsomask) 1499 || chk_type (kv4_v1, Modifier_kv4_v1_lsumask) 1500 || chk_type (kv4_v1, Modifier_kv4_v1_lsupack) 1501 || chk_type (kv4_v1, Modifier_kv4_v1_qindex) 1502 || chk_type (kv4_v1, Modifier_kv4_v1_rounding) 1503 || chk_type (kv4_v1, Modifier_kv4_v1_scalarcond) 1504 || chk_type (kv4_v1, Modifier_kv4_v1_shuffleV) 1505 || chk_type (kv4_v1, Modifier_kv4_v1_shuffleX) 1506 || chk_type (kv4_v1, Modifier_kv4_v1_silent) 1507 || chk_type (kv4_v1, Modifier_kv4_v1_simplecond) 1508 || chk_type (kv4_v1, Modifier_kv4_v1_speculate) 1509 || chk_type (kv4_v1, Modifier_kv4_v1_splat32) 1510 || chk_type (kv4_v1, Modifier_kv4_v1_transpose) 1511 || chk_type (kv4_v1, Modifier_kv4_v1_variant)) 1512 { 1513 /* Do nothing. */ 1514 } 1515 else if (chk_type (kv3_v1, Immediate_kv3_v1_sysnumber) 1516 || chk_type (kv3_v2, Immediate_kv3_v2_sysnumber) 1517 || chk_type (kv4_v1, Immediate_kv4_v1_sysnumber) 1518 || chk_type (kv3_v2, Immediate_kv3_v2_wrapped8) 1519 || chk_type (kv4_v1, Immediate_kv4_v1_wrapped8) 1520 || chk_type (kv3_v1, Immediate_kv3_v1_signed10) 1521 || chk_type (kv3_v2, Immediate_kv3_v2_signed10) 1522 || chk_type (kv4_v1, Immediate_kv4_v1_signed10) 1523 || chk_type (kv3_v1, Immediate_kv3_v1_signed16) 1524 || chk_type (kv3_v2, Immediate_kv3_v2_signed16) 1525 || chk_type (kv4_v1, Immediate_kv4_v1_signed16) 1526 || chk_type (kv3_v1, Immediate_kv3_v1_signed27) 1527 || chk_type (kv3_v2, Immediate_kv3_v2_signed27) 1528 || chk_type (kv4_v1, Immediate_kv4_v1_signed27) 1529 || chk_type (kv3_v1, Immediate_kv3_v1_wrapped32) 1530 || chk_type (kv3_v2, Immediate_kv3_v2_wrapped32) 1531 || chk_type (kv4_v1, Immediate_kv4_v1_wrapped32) 1532 || chk_type (kv3_v1, Immediate_kv3_v1_signed37) 1533 || chk_type (kv3_v2, Immediate_kv3_v2_signed37) 1534 || chk_type (kv4_v1, Immediate_kv4_v1_signed37) 1535 || chk_type (kv3_v1, Immediate_kv3_v1_signed43) 1536 || chk_type (kv3_v2, Immediate_kv3_v2_signed43) 1537 || chk_type (kv4_v1, Immediate_kv4_v1_signed43) 1538 || chk_type (kv3_v1, Immediate_kv3_v1_signed54) 1539 || chk_type (kv3_v2, Immediate_kv3_v2_signed54) 1540 || chk_type (kv4_v1, Immediate_kv4_v1_signed54) 1541 || chk_type (kv3_v1, Immediate_kv3_v1_wrapped64) 1542 || chk_type (kv3_v2, Immediate_kv3_v2_wrapped64) 1543 || chk_type (kv4_v1, Immediate_kv4_v1_wrapped64) 1544 || chk_type (kv3_v1, Immediate_kv3_v1_unsigned6) 1545 || chk_type (kv3_v2, Immediate_kv3_v2_unsigned6) 1546 || chk_type (kv4_v1, Immediate_kv4_v1_unsigned6)) 1547 crt_peb_insn->immediate = value; 1548 else if (chk_type (kv3_v1, Immediate_kv3_v1_pcrel17) 1549 || chk_type (kv3_v2, Immediate_kv3_v2_pcrel17) 1550 || chk_type (kv4_v1, Immediate_kv4_v1_pcrel17) 1551 || chk_type (kv3_v1, Immediate_kv3_v1_pcrel27) 1552 || chk_type (kv3_v2, Immediate_kv3_v2_pcrel27) 1553 || chk_type (kv4_v1, Immediate_kv4_v1_pcrel27)) 1554 crt_peb_insn->immediate = value + memaddr; 1555 else 1556 return -1; 1557 } 1558 1559 if (is_a_peb_insn) 1560 peb->nb_insn++; 1561 continue; 1562 } 1563 1564 return nb_syl * 4; 1565#undef chk_type 1566} 1567 1568void 1569print_kvx_disassembler_options (FILE * stream) 1570{ 1571 fprintf (stream, _("\n\ 1572The following KVX specific disassembler options are supported for use\n\ 1573with the -M switch (multiple options should be separated by commas):\n")); 1574 1575 fprintf (stream, _("\n\ 1576 pretty Print 32-bit words in natural order corresponding to \ 1577re-ordered instruction.\n")); 1578 1579 fprintf (stream, _("\n\ 1580 compact-assembly Do not emit a new line between bundles of instructions.\ 1581\n")); 1582 1583 fprintf (stream, _("\n\ 1584 no-compact-assembly Emit a new line between bundles of instructions.\n")); 1585 1586 fprintf (stream, _("\n")); 1587} 1588