Remove path name from test case
[binutils-gdb.git] / opcodes / kvx-dis.c
1 /* kvx-dis.c -- Kalray MPPA generic disassembler.
2 Copyright (C) 2009-2023 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
37 typedef enum
38 {
39 Steering_BCU,
40 Steering_LSU,
41 Steering_MAU,
42 Steering_ALU,
43 Steering__
44 } enum_Steering;
45 typedef uint8_t Steering;
46
47 /* BundleIssue enumeration. */
48
49 typedef 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;
59 typedef uint8_t BundleIssue;
60
61 /* An IMMX syllable is associated with the BundleIssue Extension_BundleIssue[extension]. */
62 static const BundleIssue Extension_BundleIssue[] = {
63 BundleIssue_ALU0,
64 BundleIssue_ALU1,
65 BundleIssue_MAU,
66 BundleIssue_LSU
67 };
68
69 static inline int
70 kvx_steering (uint32_t x)
71 {
72 return (((x) & 0x60000000) >> 29);
73 }
74
75 static inline int
76 kvx_extension (uint32_t x)
77 {
78 return (((x) & 0x18000000) >> 27);
79 }
80
81 static inline int
82 kvx_has_parallel_bit (uint32_t x)
83 {
84 return (((x) & 0x80000000) == 0x80000000);
85 }
86
87 static inline int
88 kvx_is_tca_opcode (uint32_t x)
89 {
90 unsigned major = ((x) >> 24) & 0x1F;
91 return (major > 1) && (major < 8);
92 }
93
94 static inline int
95 kvx_is_nop_opcode (uint32_t x)
96 {
97 return ((x) << 1) == 0xFFFFFFFE;
98 }
99
100 /* A raw instruction. */
101
102 struct insn_s
103 {
104 uint32_t syllables[KVXMAXSYLLABLES];
105 int len;
106 };
107 typedef struct insn_s insn_t;
108
109
110 static uint32_t bundle_words[KVXMAXBUNDLEWORDS];
111
112 static insn_t bundle_insn[KVXMAXBUNDLEISSUE];
113
114 /* A re-interpreted instruction. */
115
116 struct 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. */
127 static int opt_pretty = 0;
128 /* Option for not emiting a new line between all bundles. */
129 static int opt_compact_assembly = 0;
130
131 void
132 parse_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
157 static void
158 parse_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
187 struct 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
199 static 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
210 static void
211 kvx_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
260 static bool
261 kvx_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
513 struct 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
542 static int
543 decode_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
999 int
1000 print_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
1199 int
1200 decode_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
1568 void
1569 print_kvx_disassembler_options (FILE * stream)
1570 {
1571 fprintf (stream, _("\n\
1572 The following KVX specific disassembler options are supported for use\n\
1573 with 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 \
1577 re-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 }