xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/kvx-dis.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* kvx-dis.c -- Kalray MPPA generic disassembler.
2    Copyright (C) 2009-2024 Free Software Foundation, Inc.
3    Contributed by Kalray SA.
4 
5    This file is part of the GNU opcodes library.
6 
7    This library is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11 
12    It is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; see the file COPYING3. If not,
19    see <http://www.gnu.org/licenses/>.  */
20 
21 #define STATIC_TABLE
22 #define DEFINE_TABLE
23 
24 #include "sysdep.h"
25 #include "disassemble.h"
26 #include "libiberty.h"
27 #include "opintl.h"
28 #include <assert.h>
29 #include "elf-bfd.h"
30 #include "kvx-dis.h"
31 
32 #include "elf/kvx.h"
33 #include "opcode/kvx.h"
34 
35 /* Steering values for the kvx VLIW architecture.  */
36 
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
kvx_steering(uint32_t x)70 kvx_steering (uint32_t x)
71 {
72   return (((x) & 0x60000000) >> 29);
73 }
74 
75 static inline int
kvx_extension(uint32_t x)76 kvx_extension (uint32_t x)
77 {
78   return (((x) & 0x18000000) >> 27);
79 }
80 
81 static inline int
kvx_has_parallel_bit(uint32_t x)82 kvx_has_parallel_bit (uint32_t x)
83 {
84   return (((x) & 0x80000000) == 0x80000000);
85 }
86 
87 static inline int
kvx_is_tca_opcode(uint32_t x)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
kvx_is_nop_opcode(uint32_t x)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
parse_kvx_dis_option(const char * option)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
parse_kvx_dis_options(const char * options)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
kvx_dis_init(struct disassemble_info * info)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
kvx_reassemble_bundle(int wordcount,int * _insncount)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
decode_insn(bfd_vma memaddr,insn_t * insn,struct decoded_insn * res)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
print_insn_kvx(bfd_vma memaddr,struct disassemble_info * info)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
decode_prologue_epilogue_bundle(bfd_vma memaddr,struct disassemble_info * info,struct kvx_prologue_epilogue_bundle * peb)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
print_kvx_disassembler_options(FILE * stream)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 }
1588