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