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