| /* kvx-dis.c -- Kalray MPPA generic disassembler. | 
 |    Copyright (C) 2009-2024 Free Software Foundation, Inc. | 
 |    Contributed by Kalray SA. | 
 |  | 
 |    This file is part of the GNU opcodes library. | 
 |  | 
 |    This library is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3, or (at your option) | 
 |    any later version. | 
 |  | 
 |    It is distributed in the hope that it will be useful, but WITHOUT | 
 |    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | 
 |    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public | 
 |    License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program; see the file COPYING3. If not, | 
 |    see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #define STATIC_TABLE | 
 | #define DEFINE_TABLE | 
 |  | 
 | #include "sysdep.h" | 
 | #include "disassemble.h" | 
 | #include "libiberty.h" | 
 | #include "opintl.h" | 
 | #include <assert.h> | 
 | #include "elf-bfd.h" | 
 | #include "kvx-dis.h" | 
 |  | 
 | #include "elf/kvx.h" | 
 | #include "opcode/kvx.h" | 
 |  | 
 | /* Steering values for the kvx VLIW architecture.  */ | 
 |  | 
 | typedef enum | 
 | { | 
 |   Steering_BCU, | 
 |   Steering_LSU, | 
 |   Steering_MAU, | 
 |   Steering_ALU, | 
 |   Steering__ | 
 | } enum_Steering; | 
 | typedef uint8_t Steering; | 
 |  | 
 | /* BundleIssue enumeration.  */ | 
 |  | 
 | typedef enum | 
 | { | 
 |   BundleIssue_BCU, | 
 |   BundleIssue_TCA, | 
 |   BundleIssue_ALU0, | 
 |   BundleIssue_ALU1, | 
 |   BundleIssue_MAU, | 
 |   BundleIssue_LSU, | 
 |   BundleIssue__, | 
 | } enum_BundleIssue; | 
 | typedef uint8_t BundleIssue; | 
 |  | 
 | /* An IMMX syllable is associated with the BundleIssue Extension_BundleIssue[extension].  */ | 
 | static const BundleIssue Extension_BundleIssue[] = { | 
 |   BundleIssue_ALU0, | 
 |   BundleIssue_ALU1, | 
 |   BundleIssue_MAU, | 
 |   BundleIssue_LSU | 
 | }; | 
 |  | 
 | static inline int | 
 | kvx_steering (uint32_t x) | 
 | { | 
 |   return (((x) & 0x60000000) >> 29); | 
 | } | 
 |  | 
 | static inline int | 
 | kvx_extension (uint32_t x) | 
 | { | 
 |   return (((x) & 0x18000000) >> 27); | 
 | } | 
 |  | 
 | static inline int | 
 | kvx_has_parallel_bit (uint32_t x) | 
 | { | 
 |   return (((x) & 0x80000000) == 0x80000000); | 
 | } | 
 |  | 
 | static inline int | 
 | kvx_is_tca_opcode (uint32_t x) | 
 | { | 
 |   unsigned major = ((x) >> 24) & 0x1F; | 
 |   return (major > 1) && (major < 8); | 
 | } | 
 |  | 
 | static inline int | 
 | kvx_is_nop_opcode (uint32_t x) | 
 | { | 
 |   return ((x) << 1) == 0xFFFFFFFE; | 
 | } | 
 |  | 
 | /* A raw instruction.  */ | 
 |  | 
 | struct insn_s | 
 | { | 
 |   uint32_t syllables[KVXMAXSYLLABLES]; | 
 |   int len; | 
 | }; | 
 | typedef struct insn_s insn_t; | 
 |  | 
 |  | 
 | static uint32_t bundle_words[KVXMAXBUNDLEWORDS]; | 
 |  | 
 | static insn_t bundle_insn[KVXMAXBUNDLEISSUE]; | 
 |  | 
 | /* A re-interpreted instruction.  */ | 
 |  | 
 | struct instr_s | 
 | { | 
 |   int valid; | 
 |   int opcode; | 
 |   int immx[2]; | 
 |   int immx_valid[2]; | 
 |   int immx_count; | 
 |   int nb_syllables; | 
 | }; | 
 |  | 
 | /* Option for "pretty printing", ie, not the usual little endian objdump output.  */ | 
 | static int opt_pretty = 0; | 
 | /* Option for not emiting a new line between all bundles.  */ | 
 | static int opt_compact_assembly = 0; | 
 |  | 
 | void | 
 | parse_kvx_dis_option (const char *option) | 
 | { | 
 |   /* Try to match options that are simple flags.  */ | 
 |   if (startswith (option, "pretty")) | 
 |     { | 
 |       opt_pretty = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   if (startswith (option, "compact-assembly")) | 
 |     { | 
 |       opt_compact_assembly = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   if (startswith (option, "no-compact-assembly")) | 
 |     { | 
 |       opt_compact_assembly = 0; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Invalid option.  */ | 
 |   opcodes_error_handler (_("unrecognised disassembler option: %s"), option); | 
 | } | 
 |  | 
 | static void | 
 | parse_kvx_dis_options (const char *options) | 
 | { | 
 |   const char *option_end; | 
 |  | 
 |   if (options == NULL) | 
 |     return; | 
 |  | 
 |   while (*options != '\0') | 
 |     { | 
 |       /* Skip empty options.  */ | 
 |       if (*options == ',') | 
 | 	{ | 
 | 	  options++; | 
 | 	  continue; | 
 | 	} | 
 |  | 
 |       /* We know that *options is neither NUL or a comma.  */ | 
 |       option_end = options + 1; | 
 |       while (*option_end != ',' && *option_end != '\0') | 
 | 	option_end++; | 
 |  | 
 |       parse_kvx_dis_option (options); | 
 |  | 
 |       /* Go on to the next one.  If option_end points to a comma, it | 
 |          will be skipped above.  */ | 
 |       options = option_end; | 
 |     } | 
 | } | 
 |  | 
 | struct kvx_dis_env | 
 | { | 
 |   int kvx_arch_size; | 
 |   struct kvxopc *opc_table; | 
 |   struct kvx_Register *kvx_registers; | 
 |   const char ***kvx_modifiers; | 
 |   int *kvx_dec_registers; | 
 |   int *kvx_regfiles; | 
 |   unsigned int kvx_max_dec_registers; | 
 |   int initialized_p; | 
 | }; | 
 |  | 
 | static struct kvx_dis_env env = { | 
 |   .kvx_arch_size = 0, | 
 |   .opc_table = NULL, | 
 |   .kvx_registers = NULL, | 
 |   .kvx_modifiers = NULL, | 
 |   .kvx_dec_registers = NULL, | 
 |   .kvx_regfiles = NULL, | 
 |   .initialized_p = 0, | 
 |   .kvx_max_dec_registers = 0 | 
 | }; | 
 |  | 
 | static void | 
 | kvx_dis_init (struct disassemble_info *info) | 
 | { | 
 |   env.kvx_arch_size = 32; | 
 |   switch (info->mach) | 
 |     { | 
 |     case bfd_mach_kv3_1_64: | 
 |       env.kvx_arch_size = 64; | 
 |       /* fallthrough */ | 
 |     case bfd_mach_kv3_1_usr: | 
 |     case bfd_mach_kv3_1: | 
 |     default: | 
 |       env.opc_table = kvx_kv3_v1_optab; | 
 |       env.kvx_regfiles = kvx_kv3_v1_regfiles; | 
 |       env.kvx_registers = kvx_kv3_v1_registers; | 
 |       env.kvx_modifiers = kvx_kv3_v1_modifiers; | 
 |       env.kvx_dec_registers = kvx_kv3_v1_dec_registers; | 
 |       break; | 
 |     case bfd_mach_kv3_2_64: | 
 |       env.kvx_arch_size = 64; | 
 |       /* fallthrough */ | 
 |     case bfd_mach_kv3_2_usr: | 
 |     case bfd_mach_kv3_2: | 
 |       env.opc_table = kvx_kv3_v2_optab; | 
 |       env.kvx_regfiles = kvx_kv3_v2_regfiles; | 
 |       env.kvx_registers = kvx_kv3_v2_registers; | 
 |       env.kvx_modifiers = kvx_kv3_v2_modifiers; | 
 |       env.kvx_dec_registers = kvx_kv3_v2_dec_registers; | 
 |       break; | 
 |     case bfd_mach_kv4_1_64: | 
 |       env.kvx_arch_size = 64; | 
 |       /* fallthrough */ | 
 |     case bfd_mach_kv4_1_usr: | 
 |     case bfd_mach_kv4_1: | 
 |       env.opc_table = kvx_kv4_v1_optab; | 
 |       env.kvx_regfiles = kvx_kv4_v1_regfiles; | 
 |       env.kvx_registers = kvx_kv4_v1_registers; | 
 |       env.kvx_modifiers = kvx_kv4_v1_modifiers; | 
 |       env.kvx_dec_registers = kvx_kv4_v1_dec_registers; | 
 |       break; | 
 |     } | 
 |  | 
 |   env.kvx_max_dec_registers = env.kvx_regfiles[KVX_REGFILE_DEC_REGISTERS]; | 
 |  | 
 |   if (info->disassembler_options) | 
 |     parse_kvx_dis_options (info->disassembler_options); | 
 |  | 
 |   env.initialized_p = 1; | 
 | } | 
 |  | 
 | static bool | 
 | kvx_reassemble_bundle (int wordcount, int *_insncount) | 
 | { | 
 |  | 
 |   /* Debugging flag.  */ | 
 |   int debug = 0; | 
 |  | 
 |   /* Available resources.  */ | 
 |   int bcu_taken = 0; | 
 |   int tca_taken = 0; | 
 |   int alu0_taken = 0; | 
 |   int alu1_taken = 0; | 
 |   int mau_taken = 0; | 
 |   int lsu_taken = 0; | 
 |  | 
 |   if (debug) | 
 |     fprintf (stderr, "kvx_reassemble_bundle: wordcount = %d\n", wordcount); | 
 |  | 
 |   if (wordcount > KVXMAXBUNDLEWORDS) | 
 |     { | 
 |       if (debug) | 
 | 	fprintf (stderr, "bundle exceeds maximum size\n"); | 
 |       return false; | 
 |     } | 
 |  | 
 |   struct instr_s instr[KVXMAXBUNDLEISSUE]; | 
 |   memset (instr, 0, sizeof (instr)); | 
 |   assert (KVXMAXBUNDLEISSUE >= BundleIssue__); | 
 |  | 
 |   int i; | 
 |   unsigned int j; | 
 |  | 
 |   for (i = 0; i < wordcount; i++) | 
 |     { | 
 |       uint32_t syllable = bundle_words[i]; | 
 |       switch (kvx_steering (syllable)) | 
 | 	{ | 
 | 	case Steering_BCU: | 
 | 	  /* BCU or TCA instruction.  */ | 
 | 	  if (i == 0) | 
 | 	    { | 
 | 	      if (kvx_is_tca_opcode (syllable)) | 
 | 		{ | 
 | 		  if (tca_taken) | 
 | 		    { | 
 | 		      if (debug) | 
 | 			fprintf (stderr, "Too many TCA instructions"); | 
 | 		      return false; | 
 | 		    } | 
 | 		  if (debug) | 
 | 		    fprintf (stderr, | 
 | 			     "Syllable 0: Set valid on TCA for instr %d with 0x%x\n", | 
 | 			     BundleIssue_TCA, syllable); | 
 | 		  instr[BundleIssue_TCA].valid = 1; | 
 | 		  instr[BundleIssue_TCA].opcode = syllable; | 
 | 		  instr[BundleIssue_TCA].nb_syllables = 1; | 
 | 		  tca_taken = 1; | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | 		  if (debug) | 
 | 		    fprintf (stderr, | 
 | 			     "Syllable 0: Set valid on BCU for instr %d with 0x%x\n", | 
 | 			     BundleIssue_BCU, syllable); | 
 |  | 
 | 		  instr[BundleIssue_BCU].valid = 1; | 
 | 		  instr[BundleIssue_BCU].opcode = syllable; | 
 | 		  instr[BundleIssue_BCU].nb_syllables = 1; | 
 | 		  bcu_taken = 1; | 
 | 		} | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (i == 1 && bcu_taken && kvx_is_tca_opcode (syllable)) | 
 | 		{ | 
 | 		  if (tca_taken) | 
 | 		    { | 
 | 		      if (debug) | 
 | 			fprintf (stderr, "Too many TCA instructions"); | 
 | 		      return false; | 
 | 		    } | 
 | 		  if (debug) | 
 | 		    fprintf (stderr, | 
 | 			     "Syllable 0: Set valid on TCA for instr %d with 0x%x\n", | 
 | 			     BundleIssue_TCA, syllable); | 
 | 		  instr[BundleIssue_TCA].valid = 1; | 
 | 		  instr[BundleIssue_TCA].opcode = syllable; | 
 | 		  instr[BundleIssue_TCA].nb_syllables = 1; | 
 | 		  tca_taken = 1; | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | 		  /* Not first syllable in bundle, IMMX.  */ | 
 | 		  struct instr_s *instr_p = | 
 | 		    &(instr[Extension_BundleIssue[kvx_extension (syllable)]]); | 
 | 		  int immx_count = instr_p->immx_count; | 
 | 		  if (immx_count > 1) | 
 | 		    { | 
 | 		      if (debug) | 
 | 			fprintf (stderr, "Too many IMMX syllables"); | 
 | 		      return false; | 
 | 		    } | 
 | 		  instr_p->immx[immx_count] = syllable; | 
 | 		  instr_p->immx_valid[immx_count] = 1; | 
 | 		  instr_p->nb_syllables++; | 
 | 		  if (debug) | 
 | 		    fprintf (stderr, | 
 | 			     "Set IMMX[%d] on instr %d for extension %d @ %d\n", | 
 | 			     immx_count, | 
 | 			     Extension_BundleIssue[kvx_extension (syllable)], | 
 | 			     kvx_extension (syllable), i); | 
 | 		  instr_p->immx_count = immx_count + 1; | 
 | 		} | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case Steering_ALU: | 
 | 	  if (alu0_taken == 0) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Set valid on ALU0 for instr %d with 0x%x\n", | 
 | 			 BundleIssue_ALU0, syllable); | 
 | 	      instr[BundleIssue_ALU0].valid = 1; | 
 | 	      instr[BundleIssue_ALU0].opcode = syllable; | 
 | 	      instr[BundleIssue_ALU0].nb_syllables = 1; | 
 | 	      alu0_taken = 1; | 
 | 	    } | 
 | 	  else if (alu1_taken == 0) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Set valid on ALU1 for instr %d with 0x%x\n", | 
 | 			 BundleIssue_ALU1, syllable); | 
 | 	      instr[BundleIssue_ALU1].valid = 1; | 
 | 	      instr[BundleIssue_ALU1].opcode = syllable; | 
 | 	      instr[BundleIssue_ALU1].nb_syllables = 1; | 
 | 	      alu1_taken = 1; | 
 | 	    } | 
 | 	  else if (mau_taken == 0) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, | 
 | 			 "Set valid on MAU (ALU) for instr %d with 0x%x\n", | 
 | 			 BundleIssue_MAU, syllable); | 
 | 	      instr[BundleIssue_MAU].valid = 1; | 
 | 	      instr[BundleIssue_MAU].opcode = syllable; | 
 | 	      instr[BundleIssue_MAU].nb_syllables = 1; | 
 | 	      mau_taken = 1; | 
 | 	    } | 
 | 	  else if (lsu_taken == 0) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, | 
 | 			 "Set valid on LSU (ALU) for instr %d with 0x%x\n", | 
 | 			 BundleIssue_LSU, syllable); | 
 | 	      instr[BundleIssue_LSU].valid = 1; | 
 | 	      instr[BundleIssue_LSU].opcode = syllable; | 
 | 	      instr[BundleIssue_LSU].nb_syllables = 1; | 
 | 	      lsu_taken = 1; | 
 | 	    } | 
 | 	  else if (kvx_is_nop_opcode (syllable)) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Ignoring NOP (ALU) syllable\n"); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Too many ALU instructions"); | 
 | 	      return false; | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case Steering_MAU: | 
 | 	  if (mau_taken == 1) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Too many MAU instructions"); | 
 | 	      return false; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Set valid on MAU for instr %d with 0x%x\n", | 
 | 			 BundleIssue_MAU, syllable); | 
 | 	      instr[BundleIssue_MAU].valid = 1; | 
 | 	      instr[BundleIssue_MAU].opcode = syllable; | 
 | 	      instr[BundleIssue_MAU].nb_syllables = 1; | 
 | 	      mau_taken = 1; | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case Steering_LSU: | 
 | 	  if (lsu_taken == 1) | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Too many LSU instructions"); | 
 | 	      return false; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (debug) | 
 | 		fprintf (stderr, "Set valid on LSU for instr %d with 0x%x\n", | 
 | 			 BundleIssue_LSU, syllable); | 
 | 	      instr[BundleIssue_LSU].valid = 1; | 
 | 	      instr[BundleIssue_LSU].opcode = syllable; | 
 | 	      instr[BundleIssue_LSU].nb_syllables = 1; | 
 | 	      lsu_taken = 1; | 
 | 	    } | 
 | 	} | 
 |       if (debug) | 
 | 	fprintf (stderr, "Continue %d < %d?\n", i, wordcount); | 
 |     } | 
 |  | 
 |   /* Fill bundle_insn and count read syllables.  */ | 
 |   int instr_idx = 0; | 
 |   for (i = 0; i < KVXMAXBUNDLEISSUE; i++) | 
 |     { | 
 |       if (instr[i].valid == 1) | 
 | 	{ | 
 | 	  int syllable_idx = 0; | 
 |  | 
 | 	  /* First copy opcode.  */ | 
 | 	  bundle_insn[instr_idx].syllables[syllable_idx++] = instr[i].opcode; | 
 | 	  bundle_insn[instr_idx].len = 1; | 
 |  | 
 | 	  for (j = 0; j < 2; j++) | 
 | 	    { | 
 | 	      if (instr[i].immx_valid[j]) | 
 | 		{ | 
 | 		  if (debug) | 
 | 		    fprintf (stderr, "Instr %d valid immx[%d] is valid\n", i, | 
 | 			     j); | 
 | 		  bundle_insn[instr_idx].syllables[syllable_idx++] = | 
 | 		    instr[i].immx[j]; | 
 | 		  bundle_insn[instr_idx].len++; | 
 | 		} | 
 | 	    } | 
 |  | 
 | 	  if (debug) | 
 | 	    fprintf (stderr, | 
 | 		     "Instr %d valid, copying in bundle_insn (%d syllables <-> %d)\n", | 
 | 		     i, bundle_insn[instr_idx].len, instr[i].nb_syllables); | 
 | 	  instr_idx++; | 
 | 	} | 
 |     } | 
 |  | 
 |   if (debug) | 
 |     fprintf (stderr, "End => %d instructions\n", instr_idx); | 
 |  | 
 |   *_insncount = instr_idx; | 
 |   return true; | 
 | } | 
 |  | 
 | struct decoded_insn | 
 | { | 
 |   /* The entry in the opc_table. */ | 
 |   struct kvxopc *opc; | 
 |   /* The number of operands.  */ | 
 |   int nb_ops; | 
 |   /* The content of an operands.  */ | 
 |   struct | 
 |   { | 
 |     enum | 
 |     { | 
 |       CAT_REGISTER, | 
 |       CAT_MODIFIER, | 
 |       CAT_IMMEDIATE, | 
 |     } type; | 
 |     /* The value of the operands.  */ | 
 |     uint64_t val; | 
 |     /* If it is an immediate, its sign.  */ | 
 |     int sign; | 
 |     /* If it is an immediate, is it pc relative.  */ | 
 |     int pcrel; | 
 |     /* The width of the operand.  */ | 
 |     int width; | 
 |     /* If it is a modifier, the modifier category. | 
 |        An index in the modifier table.  */ | 
 |     int mod_idx; | 
 |   } operands[KVXMAXOPERANDS]; | 
 | }; | 
 |  | 
 | static int | 
 | decode_insn (bfd_vma memaddr, insn_t * insn, struct decoded_insn *res) | 
 | { | 
 |  | 
 |   int found = 0; | 
 |   int idx = 0; | 
 |   for (struct kvxopc * op = env.opc_table; | 
 |        op->as_op && (((char) op->as_op[0]) != 0); op++) | 
 |     { | 
 |       /* Find the format of this insn.  */ | 
 |       int opcode_match = 1; | 
 |  | 
 |       if (op->wordcount != insn->len) | 
 | 	continue; | 
 |  | 
 |       for (int i = 0; i < op->wordcount; i++) | 
 | 	if ((op->codewords[i].mask & insn->syllables[i]) != | 
 | 	    op->codewords[i].opcode) | 
 | 	  opcode_match = 0; | 
 |  | 
 |       int encoding_space_flags = env.kvx_arch_size == 32 | 
 | 	? kvxOPCODE_FLAG_MODE32 : kvxOPCODE_FLAG_MODE64; | 
 |  | 
 |       for (int i = 0; i < op->wordcount; i++) | 
 | 	if (!(op->codewords[i].flags & encoding_space_flags)) | 
 | 	  opcode_match = 0; | 
 |  | 
 |       if (opcode_match) | 
 | 	{ | 
 | 	  res->opc = op; | 
 |  | 
 | 	  for (int i = 0; op->format[i]; i++) | 
 | 	    { | 
 | 	      struct kvx_bitfield *bf = op->format[i]->bfield; | 
 | 	      int bf_nb = op->format[i]->bitfields; | 
 | 	      int width = op->format[i]->width; | 
 | 	      int type = op->format[i]->type; | 
 | 	      const char *type_name = op->format[i]->tname; | 
 | 	      int flags = op->format[i]->flags; | 
 | 	      int shift = op->format[i]->shift; | 
 | 	      int bias = op->format[i]->bias; | 
 | 	      uint64_t value = 0; | 
 |  | 
 | 	      for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++) | 
 | 		{ | 
 | 		  int insn_idx = (int) bf[bf_idx].to_offset / 32; | 
 | 		  int to_offset = bf[bf_idx].to_offset % 32; | 
 | 		  uint64_t encoded_value = | 
 | 		    insn->syllables[insn_idx] >> to_offset; | 
 | 		  encoded_value &= (1LL << bf[bf_idx].size) - 1; | 
 | 		  value |= encoded_value << bf[bf_idx].from_offset; | 
 | 		} | 
 | 	      if (flags & kvxSIGNED) | 
 | 		{ | 
 | 		  uint64_t signbit = 1LL << (width - 1); | 
 | 		  value = (value ^ signbit) - signbit; | 
 | 		} | 
 | 	      value = (value << shift) + bias; | 
 |  | 
 | #define KVX_PRINT_REG(regfile,value) \ | 
 |     if(env.kvx_regfiles[regfile]+value < env.kvx_max_dec_registers) { \ | 
 |         res->operands[idx].val = env.kvx_dec_registers[env.kvx_regfiles[regfile]+value]; \ | 
 |         res->operands[idx].type = CAT_REGISTER; \ | 
 | 	idx++; \ | 
 |     } else { \ | 
 |         res->operands[idx].val = ~0; \ | 
 |         res->operands[idx].type = CAT_REGISTER; \ | 
 | 	idx++; \ | 
 |     } | 
 |  | 
 | 	      if (env.opc_table == kvx_kv3_v1_optab) | 
 | 		{ | 
 | 		  switch (type) | 
 | 		    { | 
 | 		    case RegClass_kv3_v1_singleReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_pairedReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_quadReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_systemReg: | 
 | 		    case RegClass_kv3_v1_aloneReg: | 
 | 		    case RegClass_kv3_v1_onlyraReg: | 
 | 		    case RegClass_kv3_v1_onlygetReg: | 
 | 		    case RegClass_kv3_v1_onlysetReg: | 
 | 		    case RegClass_kv3_v1_onlyfxReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_coproReg0M4: | 
 | 		    case RegClass_kv3_v1_coproReg1M4: | 
 | 		    case RegClass_kv3_v1_coproReg2M4: | 
 | 		    case RegClass_kv3_v1_coproReg3M4: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_blockRegE: | 
 | 		    case RegClass_kv3_v1_blockRegO: | 
 | 		    case RegClass_kv3_v1_blockReg0M4: | 
 | 		    case RegClass_kv3_v1_blockReg1M4: | 
 | 		    case RegClass_kv3_v1_blockReg2M4: | 
 | 		    case RegClass_kv3_v1_blockReg3M4: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_vectorReg: | 
 | 		    case RegClass_kv3_v1_vectorRegE: | 
 | 		    case RegClass_kv3_v1_vectorRegO: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_tileReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v1_matrixReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) | 
 | 		      break; | 
 | 		    case Immediate_kv3_v1_sysnumber: | 
 | 		    case Immediate_kv3_v1_signed10: | 
 | 		    case Immediate_kv3_v1_signed16: | 
 | 		    case Immediate_kv3_v1_signed27: | 
 | 		    case Immediate_kv3_v1_wrapped32: | 
 | 		    case Immediate_kv3_v1_signed37: | 
 | 		    case Immediate_kv3_v1_signed43: | 
 | 		    case Immediate_kv3_v1_signed54: | 
 | 		    case Immediate_kv3_v1_wrapped64: | 
 | 		    case Immediate_kv3_v1_unsigned6: | 
 | 		      res->operands[idx].val = value; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 0; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Immediate_kv3_v1_pcrel17: | 
 | 		    case Immediate_kv3_v1_pcrel27: | 
 | 		      res->operands[idx].val = value + memaddr; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 1; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Modifier_kv3_v1_column: | 
 | 		    case Modifier_kv3_v1_comparison: | 
 | 		    case Modifier_kv3_v1_doscale: | 
 | 		    case Modifier_kv3_v1_exunum: | 
 | 		    case Modifier_kv3_v1_floatcomp: | 
 | 		    case Modifier_kv3_v1_qindex: | 
 | 		    case Modifier_kv3_v1_rectify: | 
 | 		    case Modifier_kv3_v1_rounding: | 
 | 		    case Modifier_kv3_v1_roundint: | 
 | 		    case Modifier_kv3_v1_saturate: | 
 | 		    case Modifier_kv3_v1_scalarcond: | 
 | 		    case Modifier_kv3_v1_silent: | 
 | 		    case Modifier_kv3_v1_simplecond: | 
 | 		    case Modifier_kv3_v1_speculate: | 
 | 		    case Modifier_kv3_v1_splat32: | 
 | 		    case Modifier_kv3_v1_variant: | 
 | 		      { | 
 | 			int sz = 0; | 
 | 			int mod_idx = type - Modifier_kv3_v1_column; | 
 | 			for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz); | 
 | 			const char *mod = value < (unsigned) sz | 
 | 			  ? env.kvx_modifiers[mod_idx][value] : NULL; | 
 | 			if (!mod) goto retry; | 
 | 			res->operands[idx].val = value; | 
 | 			res->operands[idx].type = CAT_MODIFIER; | 
 | 			res->operands[idx].mod_idx = mod_idx; | 
 | 			idx++; | 
 | 		      } | 
 | 		      break; | 
 | 		    default: | 
 | 		      fprintf (stderr, "error: unexpected operand type (%s)\n", | 
 | 			       type_name); | 
 | 		      exit (-1); | 
 | 		    }; | 
 | 		} | 
 | 	      else if (env.opc_table == kvx_kv3_v2_optab) | 
 | 		{ | 
 | 		  switch (type) | 
 | 		    { | 
 | 		    case RegClass_kv3_v2_singleReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_pairedReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_quadReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_systemReg: | 
 | 		    case RegClass_kv3_v2_aloneReg: | 
 | 		    case RegClass_kv3_v2_onlyraReg: | 
 | 		    case RegClass_kv3_v2_onlygetReg: | 
 | 		    case RegClass_kv3_v2_onlysetReg: | 
 | 		    case RegClass_kv3_v2_onlyfxReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_coproReg: | 
 | 		    case RegClass_kv3_v2_coproReg0M4: | 
 | 		    case RegClass_kv3_v2_coproReg1M4: | 
 | 		    case RegClass_kv3_v2_coproReg2M4: | 
 | 		    case RegClass_kv3_v2_coproReg3M4: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_blockReg: | 
 | 		    case RegClass_kv3_v2_blockRegE: | 
 | 		    case RegClass_kv3_v2_blockRegO: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_vectorReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_tileReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_matrixReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer2Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer4Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer8Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer16Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer32Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv3_v2_buffer64Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value) | 
 | 		      break; | 
 | 		    case Immediate_kv3_v2_brknumber: | 
 | 		    case Immediate_kv3_v2_sysnumber: | 
 | 		    case Immediate_kv3_v2_signed10: | 
 | 		    case Immediate_kv3_v2_signed16: | 
 | 		    case Immediate_kv3_v2_signed27: | 
 | 		    case Immediate_kv3_v2_wrapped32: | 
 | 		    case Immediate_kv3_v2_signed37: | 
 | 		    case Immediate_kv3_v2_signed43: | 
 | 		    case Immediate_kv3_v2_signed54: | 
 | 		    case Immediate_kv3_v2_wrapped64: | 
 | 		    case Immediate_kv3_v2_unsigned6: | 
 | 		      res->operands[idx].val = value; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 0; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Immediate_kv3_v2_pcrel27: | 
 | 		    case Immediate_kv3_v2_pcrel17: | 
 | 		      res->operands[idx].val = value + memaddr; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 1; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Modifier_kv3_v2_accesses: | 
 | 		    case Modifier_kv3_v2_boolcas: | 
 | 		    case Modifier_kv3_v2_cachelev: | 
 | 		    case Modifier_kv3_v2_channel: | 
 | 		    case Modifier_kv3_v2_coherency: | 
 | 		    case Modifier_kv3_v2_comparison: | 
 | 		    case Modifier_kv3_v2_conjugate: | 
 | 		    case Modifier_kv3_v2_doscale: | 
 | 		    case Modifier_kv3_v2_exunum: | 
 | 		    case Modifier_kv3_v2_floatcomp: | 
 | 		    case Modifier_kv3_v2_hindex: | 
 | 		    case Modifier_kv3_v2_lsomask: | 
 | 		    case Modifier_kv3_v2_lsumask: | 
 | 		    case Modifier_kv3_v2_lsupack: | 
 | 		    case Modifier_kv3_v2_qindex: | 
 | 		    case Modifier_kv3_v2_rounding: | 
 | 		    case Modifier_kv3_v2_scalarcond: | 
 | 		    case Modifier_kv3_v2_shuffleV: | 
 | 		    case Modifier_kv3_v2_shuffleX: | 
 | 		    case Modifier_kv3_v2_silent: | 
 | 		    case Modifier_kv3_v2_simplecond: | 
 | 		    case Modifier_kv3_v2_speculate: | 
 | 		    case Modifier_kv3_v2_splat32: | 
 | 		    case Modifier_kv3_v2_transpose: | 
 | 		    case Modifier_kv3_v2_variant: | 
 | 		      { | 
 | 			int sz = 0; | 
 | 			int mod_idx = type - Modifier_kv3_v2_accesses; | 
 | 			for (sz = 0; env.kvx_modifiers[mod_idx][sz]; | 
 | 			     ++sz); | 
 | 			const char *mod = value < (unsigned) sz | 
 | 			  ? env.kvx_modifiers[mod_idx][value] : NULL; | 
 | 			if (!mod) goto retry; | 
 | 			res->operands[idx].val = value; | 
 | 			res->operands[idx].type = CAT_MODIFIER; | 
 | 			res->operands[idx].mod_idx = mod_idx; | 
 | 			idx++; | 
 | 		      }; | 
 | 		      break; | 
 | 		    default: | 
 | 		      fprintf (stderr, | 
 | 			       "error: unexpected operand type (%s)\n", | 
 | 			       type_name); | 
 | 		      exit (-1); | 
 | 		    }; | 
 | 		} | 
 | 	      else if (env.opc_table == kvx_kv4_v1_optab) | 
 | 		{ | 
 | 		  switch (type) | 
 | 		    { | 
 |  | 
 | 		    case RegClass_kv4_v1_singleReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_pairedReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_quadReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_systemReg: | 
 | 		    case RegClass_kv4_v1_aloneReg: | 
 | 		    case RegClass_kv4_v1_onlyraReg: | 
 | 		    case RegClass_kv4_v1_onlygetReg: | 
 | 		    case RegClass_kv4_v1_onlysetReg: | 
 | 		    case RegClass_kv4_v1_onlyfxReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_coproReg: | 
 | 		    case RegClass_kv4_v1_coproReg0M4: | 
 | 		    case RegClass_kv4_v1_coproReg1M4: | 
 | 		    case RegClass_kv4_v1_coproReg2M4: | 
 | 		    case RegClass_kv4_v1_coproReg3M4: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_blockReg: | 
 | 		    case RegClass_kv4_v1_blockRegE: | 
 | 		    case RegClass_kv4_v1_blockRegO: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_vectorReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_tileReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_matrixReg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer2Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer4Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer8Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer16Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer32Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value) | 
 | 		      break; | 
 | 		    case RegClass_kv4_v1_buffer64Reg: | 
 | 		      KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value) | 
 | 		      break; | 
 | 		    case Immediate_kv4_v1_brknumber: | 
 | 		    case Immediate_kv4_v1_sysnumber: | 
 | 		    case Immediate_kv4_v1_signed10: | 
 | 		    case Immediate_kv4_v1_signed16: | 
 | 		    case Immediate_kv4_v1_signed27: | 
 | 		    case Immediate_kv4_v1_wrapped32: | 
 | 		    case Immediate_kv4_v1_signed37: | 
 | 		    case Immediate_kv4_v1_signed43: | 
 | 		    case Immediate_kv4_v1_signed54: | 
 | 		    case Immediate_kv4_v1_wrapped64: | 
 | 		    case Immediate_kv4_v1_unsigned6: | 
 | 		      res->operands[idx].val = value; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 0; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Immediate_kv4_v1_pcrel27: | 
 | 		    case Immediate_kv4_v1_pcrel17: | 
 | 		      res->operands[idx].val = value + memaddr; | 
 | 		      res->operands[idx].sign = flags & kvxSIGNED; | 
 | 		      res->operands[idx].width = width; | 
 | 		      res->operands[idx].type = CAT_IMMEDIATE; | 
 | 		      res->operands[idx].pcrel = 1; | 
 | 		      idx++; | 
 | 		      break; | 
 | 		    case Modifier_kv4_v1_accesses: | 
 | 		    case Modifier_kv4_v1_boolcas: | 
 | 		    case Modifier_kv4_v1_cachelev: | 
 | 		    case Modifier_kv4_v1_channel: | 
 | 		    case Modifier_kv4_v1_coherency: | 
 | 		    case Modifier_kv4_v1_comparison: | 
 | 		    case Modifier_kv4_v1_conjugate: | 
 | 		    case Modifier_kv4_v1_doscale: | 
 | 		    case Modifier_kv4_v1_exunum: | 
 | 		    case Modifier_kv4_v1_floatcomp: | 
 | 		    case Modifier_kv4_v1_hindex: | 
 | 		    case Modifier_kv4_v1_lsomask: | 
 | 		    case Modifier_kv4_v1_lsumask: | 
 | 		    case Modifier_kv4_v1_lsupack: | 
 | 		    case Modifier_kv4_v1_qindex: | 
 | 		    case Modifier_kv4_v1_rounding: | 
 | 		    case Modifier_kv4_v1_scalarcond: | 
 | 		    case Modifier_kv4_v1_shuffleV: | 
 | 		    case Modifier_kv4_v1_shuffleX: | 
 | 		    case Modifier_kv4_v1_silent: | 
 | 		    case Modifier_kv4_v1_simplecond: | 
 | 		    case Modifier_kv4_v1_speculate: | 
 | 		    case Modifier_kv4_v1_splat32: | 
 | 		    case Modifier_kv4_v1_transpose: | 
 | 		    case Modifier_kv4_v1_variant: | 
 | 		      { | 
 | 			int sz = 0; | 
 | 			int mod_idx = type - Modifier_kv4_v1_accesses; | 
 | 			for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz); | 
 | 			const char *mod = value < (unsigned) sz | 
 | 			  ? env.kvx_modifiers[mod_idx][value] : NULL; | 
 | 			if (!mod) goto retry; | 
 | 			res->operands[idx].val = value; | 
 | 			res->operands[idx].type = CAT_MODIFIER; | 
 | 			res->operands[idx].mod_idx = mod_idx; | 
 | 			idx++; | 
 | 		      } | 
 | 		      break; | 
 | 		    default: | 
 | 		      fprintf (stderr, "error: unexpected operand type (%s)\n", | 
 | 			       type_name); | 
 | 		      exit (-1); | 
 | 		    }; | 
 | 		} | 
 |  | 
 | #undef KVX_PRINT_REG | 
 | 	    } | 
 |  | 
 | 	  found = 1; | 
 | 	  break; | 
 | 	retry:; | 
 | 	  idx = 0; | 
 | 	  continue; | 
 | 	} | 
 |  } | 
 |   res->nb_ops = idx; | 
 |   return found; | 
 | } | 
 |  | 
 | int | 
 | print_insn_kvx (bfd_vma memaddr, struct disassemble_info *info) | 
 | { | 
 |   static int insnindex = 0; | 
 |   static int insncount = 0; | 
 |   insn_t *insn; | 
 |   int readsofar = 0; | 
 |   int found = 0; | 
 |   int invalid_bundle = 0; | 
 |  | 
 |   if (!env.initialized_p) | 
 |     kvx_dis_init (info); | 
 |  | 
 |   /* Clear instruction information field.  */ | 
 |   info->insn_info_valid = 0; | 
 |   info->branch_delay_insns = 0; | 
 |   info->data_size = 0; | 
 |   info->insn_type = dis_noninsn; | 
 |   info->target = 0; | 
 |   info->target2 = 0; | 
 |  | 
 |   /* Set line length.  */ | 
 |   info->bytes_per_line = 16; | 
 |  | 
 |  | 
 |   /* If this is the beginning of the bundle, read BUNDLESIZE words and apply | 
 |      decentrifugate function.  */ | 
 |   if (insnindex == 0) | 
 |     { | 
 |       int wordcount; | 
 |       for (wordcount = 0; wordcount < KVXMAXBUNDLEWORDS; wordcount++) | 
 | 	{ | 
 | 	  int status; | 
 | 	  status = | 
 | 	    (*info->read_memory_func) (memaddr + 4 * wordcount, | 
 | 				       (bfd_byte *) (bundle_words + | 
 | 						     wordcount), 4, info); | 
 | 	  if (status != 0) | 
 | 	    { | 
 | 	      (*info->memory_error_func) (status, memaddr + 4 * wordcount, | 
 | 					  info); | 
 | 	      return -1; | 
 | 	    } | 
 | 	  if (!kvx_has_parallel_bit (bundle_words[wordcount])) | 
 | 	    break; | 
 | 	} | 
 |       wordcount++; | 
 |       invalid_bundle = !kvx_reassemble_bundle (wordcount, &insncount); | 
 |     } | 
 |  | 
 |   assert (insnindex < KVXMAXBUNDLEISSUE); | 
 |   insn = &(bundle_insn[insnindex]); | 
 |   readsofar = insn->len * 4; | 
 |   insnindex++; | 
 |  | 
 |   if (opt_pretty) | 
 |     { | 
 |       (*info->fprintf_func) (info->stream, "[ "); | 
 |       for (int i = 0; i < insn->len; i++) | 
 | 	(*info->fprintf_func) (info->stream, "%08x ", insn->syllables[i]); | 
 |       (*info->fprintf_func) (info->stream, "] "); | 
 |     } | 
 |  | 
 |   /* Check for extension to right iff this is not the end of bundle.  */ | 
 |  | 
 |   struct decoded_insn dec; | 
 |   memset (&dec, 0, sizeof dec); | 
 |   if (!invalid_bundle && (found = decode_insn (memaddr, insn, &dec))) | 
 |     { | 
 |       int ch; | 
 |       (*info->fprintf_func) (info->stream, "%s", dec.opc->as_op); | 
 |       const char *fmtp = dec.opc->fmtstring; | 
 |       for (int i = 0; i < dec.nb_ops; ++i) | 
 | 	{ | 
 | 	  /* Print characters in the format string up to the following % or nul.  */ | 
 | 	  while ((ch = *fmtp) && ch != '%') | 
 | 	    { | 
 | 	      (*info->fprintf_func) (info->stream, "%c", ch); | 
 | 	      fmtp++; | 
 | 	    } | 
 |  | 
 | 	  /* Skip past %s.  */ | 
 | 	  if (ch == '%') | 
 | 	    { | 
 | 	      ch = *fmtp++; | 
 | 	      fmtp++; | 
 | 	    } | 
 |  | 
 | 	  switch (dec.operands[i].type) | 
 | 	    { | 
 | 	    case CAT_REGISTER: | 
 | 	      (*info->fprintf_func) (info->stream, "%s", | 
 | 				     env.kvx_registers[dec.operands[i].val].name); | 
 | 	      break; | 
 | 	    case CAT_MODIFIER: | 
 | 	      { | 
 | 		const char *mod = env.kvx_modifiers[dec.operands[i].mod_idx][dec.operands[i].val]; | 
 | 		(*info->fprintf_func) (info->stream, "%s", !mod || !strcmp (mod, ".") ? "" : mod); | 
 | 	      } | 
 | 	      break; | 
 | 	    case CAT_IMMEDIATE: | 
 | 	      { | 
 | 		if (dec.operands[i].pcrel) | 
 | 		  { | 
 | 		    /* Fill in instruction information.  */ | 
 | 		    info->insn_info_valid = 1; | 
 | 		    info->insn_type = | 
 | 		      dec.operands[i].width == | 
 | 		      17 ? dis_condbranch : dis_branch; | 
 | 		    info->target = dec.operands[i].val; | 
 |  | 
 | 		    info->print_address_func (dec.operands[i].val, info); | 
 | 		  } | 
 | 		else if (dec.operands[i].sign) | 
 | 		  { | 
 | 		    if (dec.operands[i].width <= 32) | 
 | 		      { | 
 | 			(*info->fprintf_func) (info->stream, "%" PRId32 " (0x%" PRIx32 ")", | 
 | 					       (int32_t) dec.operands[i].val, | 
 | 					       (int32_t) dec.operands[i].val); | 
 | 		      } | 
 | 		    else | 
 | 		      { | 
 | 			(*info->fprintf_func) (info->stream, "%" PRId64 " (0x%" PRIx64 ")", | 
 | 					       dec.operands[i].val, | 
 | 					       dec.operands[i].val); | 
 | 		      } | 
 | 		  } | 
 | 		else | 
 | 		  { | 
 | 		    if (dec.operands[i].width <= 32) | 
 | 		      { | 
 | 			(*info->fprintf_func) (info->stream, "%" PRIu32 " (0x%" PRIx32 ")", | 
 | 					       (uint32_t) dec.operands[i]. | 
 | 					       val, | 
 | 					       (uint32_t) dec.operands[i]. | 
 | 					       val); | 
 | 		      } | 
 | 		    else | 
 | 		      { | 
 | 			(*info->fprintf_func) (info->stream, "%" PRIu64 " (0x%" PRIx64 ")", | 
 | 					       (uint64_t) dec. | 
 | 					       operands[i].val, | 
 | 					       (uint64_t) dec. | 
 | 					       operands[i].val); | 
 | 		      } | 
 | 		  } | 
 | 	      } | 
 | 	      break; | 
 | 	    default: | 
 | 	      break; | 
 |  | 
 | 	    } | 
 | 	} | 
 |  | 
 |       while ((ch = *fmtp)) | 
 | 	{ | 
 | 	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "%c", | 
 | 					ch); | 
 | 	  fmtp++; | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       (*info->fprintf_func) (info->stream, "*** invalid opcode ***\n"); | 
 |       insnindex = 0; | 
 |       readsofar = 4; | 
 |     } | 
 |  | 
 |   if (found && (insnindex == insncount)) | 
 |     { | 
 |       (*info->fprintf_func) (info->stream, ";;"); | 
 |       if (!opt_compact_assembly) | 
 | 	(*info->fprintf_func) (info->stream, "\n"); | 
 |       insnindex = 0; | 
 |     } | 
 |  | 
 |   return readsofar; | 
 | } | 
 |  | 
 | /* This function searches in the current bundle for the instructions required | 
 |    by unwinding. For prologue: | 
 |      (1) addd $r12 = $r12, <res_stack> | 
 |      (2) get <gpr_ra_reg> = $ra | 
 |      (3) sd <ofs>[$r12] = <gpr_ra_reg> or sq/so containing <gpr_ra_reg> | 
 |      (4) sd <ofs>[$r12] = $r14 or sq/so containing r14 | 
 |      (5) addd $r14 = $r12, <fp_ofs> or copyd $r14 = $r12 | 
 | 	 The only difference seen between the code generated by gcc and clang | 
 | 	 is the setting/resetting r14. gcc could also generate copyd $r14=$r12 | 
 | 	 instead of add addd $r14 = $r12, <ofs> when <ofs> is 0. | 
 | 	 Vice-versa, <ofs> is not guaranteed to be 0 for clang, so, clang | 
 | 	 could also generate addd instead of copyd | 
 |      (6) call, icall, goto, igoto, cb., ret | 
 |   For epilogue: | 
 |      (1) addd $r12 = $r12, <res_stack> | 
 |      (2) addd $r12 = $r14, <offset> or copyd $r12 = $r14 | 
 | 	 Same comment as prologue (5). | 
 |      (3) ret, goto | 
 |      (4) call, icall, igoto, cb.  */ | 
 |  | 
 | int | 
 | decode_prologue_epilogue_bundle (bfd_vma memaddr, | 
 | 				 struct disassemble_info *info, | 
 | 				 struct kvx_prologue_epilogue_bundle *peb) | 
 | { | 
 |   int i, nb_insn, nb_syl; | 
 |  | 
 |   peb->nb_insn = 0; | 
 |  | 
 |   if (info->arch != bfd_arch_kvx) | 
 |     return -1; | 
 |  | 
 |   if (!env.initialized_p) | 
 |     kvx_dis_init (info); | 
 |  | 
 |   /* Read the bundle.  */ | 
 |   for (nb_syl = 0; nb_syl < KVXMAXBUNDLEWORDS; nb_syl++) | 
 |     { | 
 |       if ((*info->read_memory_func) (memaddr + 4 * nb_syl, | 
 | 				     (bfd_byte *) &bundle_words[nb_syl], 4, | 
 | 				     info)) | 
 | 	return -1; | 
 |       if (!kvx_has_parallel_bit (bundle_words[nb_syl])) | 
 | 	break; | 
 |     } | 
 |   nb_syl++; | 
 |   if (!kvx_reassemble_bundle (nb_syl, &nb_insn)) | 
 |     return -1; | 
 |  | 
 |   /* Check for extension to right if this is not the end of bundle | 
 |      find the format of this insn.  */ | 
 |   for (int idx_insn = 0; idx_insn < nb_insn; idx_insn++) | 
 |     { | 
 |       insn_t *insn = &bundle_insn[idx_insn]; | 
 |       int is_add = 0, is_get = 0, is_a_peb_insn = 0, is_copyd = 0; | 
 |  | 
 |       struct decoded_insn dec; | 
 |       memset (&dec, 0, sizeof dec); | 
 |       if (!decode_insn (memaddr, insn, &dec)) | 
 | 	continue; | 
 |  | 
 |       const char *op_name = dec.opc->as_op; | 
 |       struct kvx_prologue_epilogue_insn *crt_peb_insn; | 
 |  | 
 |       crt_peb_insn = &peb->insn[peb->nb_insn]; | 
 |       crt_peb_insn->nb_gprs = 0; | 
 |  | 
 |       if (!strcmp (op_name, "addd")) | 
 | 	is_add = 1; | 
 |       else if (!strcmp (op_name, "copyd")) | 
 | 	is_copyd = 1; | 
 |       else if (!strcmp (op_name, "get")) | 
 | 	is_get = 1; | 
 |       else if (!strcmp (op_name, "sd")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SD; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "sq")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SQ; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "so")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SO; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "ret")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_RET; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "goto")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GOTO; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "igoto")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_IGOTO; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strcmp (op_name, "call") || !strcmp (op_name, "icall")) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CALL; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else if (!strncmp (op_name, "cb", 2)) | 
 | 	{ | 
 | 	  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CB; | 
 | 	  is_a_peb_insn = 1; | 
 | 	} | 
 |       else | 
 | 	continue; | 
 |  | 
 |       for (i = 0; dec.opc->format[i]; i++) | 
 | 	{ | 
 | 	  struct kvx_operand *fmt = dec.opc->format[i]; | 
 | 	  struct kvx_bitfield *bf = fmt->bfield; | 
 | 	  int bf_nb = fmt->bitfields; | 
 | 	  int width = fmt->width; | 
 | 	  int type = fmt->type; | 
 | 	  int flags = fmt->flags; | 
 | 	  int shift = fmt->shift; | 
 | 	  int bias = fmt->bias; | 
 | 	  uint64_t encoded_value, value = 0; | 
 |  | 
 | 	  for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++) | 
 | 	    { | 
 | 	      int insn_idx = (int) bf[bf_idx].to_offset / 32; | 
 | 	      int to_offset = bf[bf_idx].to_offset % 32; | 
 | 	      encoded_value = insn->syllables[insn_idx] >> to_offset; | 
 | 	      encoded_value &= (1LL << bf[bf_idx].size) - 1; | 
 | 	      value |= encoded_value << bf[bf_idx].from_offset; | 
 | 	    } | 
 | 	  if (flags & kvxSIGNED) | 
 | 	    { | 
 | 	      uint64_t signbit = 1LL << (width - 1); | 
 | 	      value = (value ^ signbit) - signbit; | 
 | 	    } | 
 | 	  value = (value << shift) + bias; | 
 |  | 
 | #define chk_type(core_, val_) \ | 
 |       (env.opc_table == kvx_## core_ ##_optab && type == (val_)) | 
 |  | 
 | 	  if (chk_type (kv3_v1, RegClass_kv3_v1_singleReg) | 
 | 	      || chk_type (kv3_v2, RegClass_kv3_v2_singleReg) | 
 | 	      || chk_type (kv4_v1, RegClass_kv4_v1_singleReg)) | 
 | 	    { | 
 | 	      if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value | 
 | 		  >= env.kvx_max_dec_registers) | 
 | 		return -1; | 
 | 	      if (is_add && i < 2) | 
 | 		{ | 
 | 		  if (i == 0) | 
 | 		    { | 
 | 		      if (value == KVX_GPR_REG_SP) | 
 | 			crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_SP; | 
 | 		      else if (value == KVX_GPR_REG_FP) | 
 | 			crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP; | 
 | 		      else | 
 | 			is_add = 0; | 
 | 		    } | 
 | 		  else if (i == 1) | 
 | 		    { | 
 | 		      if (value == KVX_GPR_REG_SP) | 
 | 			is_a_peb_insn = 1; | 
 | 		      else if (value == KVX_GPR_REG_FP | 
 | 			       && crt_peb_insn->insn_type | 
 | 			       == KVX_PROL_EPIL_INSN_ADD_SP) | 
 | 			{ | 
 | 			  crt_peb_insn->insn_type | 
 | 			    = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP; | 
 | 			  is_a_peb_insn = 1; | 
 | 			} | 
 | 		      else | 
 | 			is_add = 0; | 
 | 		    } | 
 | 		} | 
 | 	      else if (is_copyd && i < 2) | 
 | 		{ | 
 | 		  if (i == 0) | 
 | 		    { | 
 | 		      if (value == KVX_GPR_REG_FP) | 
 | 			{ | 
 | 			  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP; | 
 | 			  crt_peb_insn->immediate = 0; | 
 | 			} | 
 | 		      else if (value == KVX_GPR_REG_SP) | 
 | 			{ | 
 | 			  crt_peb_insn->insn_type | 
 | 			    = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP; | 
 | 			  crt_peb_insn->immediate = 0; | 
 | 			} | 
 | 		      else | 
 | 			is_copyd = 0; | 
 | 		    } | 
 | 		  else if (i == 1) | 
 | 		    { | 
 | 		      if (value == KVX_GPR_REG_SP | 
 | 			  && crt_peb_insn->insn_type | 
 | 			  == KVX_PROL_EPIL_INSN_ADD_FP) | 
 | 			is_a_peb_insn = 1; | 
 | 		      else if (value == KVX_GPR_REG_FP | 
 | 			       && crt_peb_insn->insn_type | 
 | 			       == KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP) | 
 | 			is_a_peb_insn = 1; | 
 | 		      else | 
 | 			is_copyd = 0; | 
 | 		    } | 
 | 		} | 
 | 	      else | 
 | 		crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value; | 
 | 	    } | 
 | 	  else if (chk_type (kv3_v1, RegClass_kv3_v1_pairedReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_pairedReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_pairedReg)) | 
 | 	    crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 2; | 
 | 	  else if (chk_type (kv3_v1, RegClass_kv3_v1_quadReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_quadReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_quadReg)) | 
 | 	    crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 4; | 
 | 	  else if (chk_type (kv3_v1, RegClass_kv3_v1_systemReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_systemReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_systemReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_aloneReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_aloneReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_aloneReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_onlyraReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_onlyraReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_onlygetReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_onlygetReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_onlysetReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_onlysetReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_onlysetReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_onlyfxReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_onlyfxReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_onlyfxReg)) | 
 | 	    { | 
 | 	      if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value | 
 | 		  >= env.kvx_max_dec_registers) | 
 | 		return -1; | 
 | 	      if (is_get && !strcmp (env.kvx_registers[env.kvx_dec_registers[env.kvx_regfiles[KVX_REGFILE_DEC_SFR] + value]].name, "$ra")) | 
 | 		{ | 
 | 		  crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GET_RA; | 
 | 		  is_a_peb_insn = 1; | 
 | 		} | 
 | 	    } | 
 | 	  else if (chk_type (kv3_v1, RegClass_kv3_v1_coproReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_coproReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_coproReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_blockReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_blockReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_blockReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_vectorReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_vectorReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_vectorReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_tileReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_tileReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_tileReg) | 
 | 		   || chk_type (kv3_v1, RegClass_kv3_v1_matrixReg) | 
 | 		   || chk_type (kv3_v2, RegClass_kv3_v2_matrixReg) | 
 | 		   || chk_type (kv4_v1, RegClass_kv4_v1_matrixReg) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_column) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_comparison) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_doscale) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_exunum) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_floatcomp) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_qindex) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_rectify) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_rounding) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_roundint) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_saturate) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_silent) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_simplecond) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_speculate) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_splat32) | 
 | 		   || chk_type (kv3_v1, Modifier_kv3_v1_variant) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_accesses) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_boolcas) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_cachelev) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_channel) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_coherency) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_comparison) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_conjugate) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_doscale) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_exunum) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_floatcomp) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_hindex) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_lsomask) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_lsumask) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_lsupack) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_qindex) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_rounding) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_scalarcond) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_shuffleV) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_shuffleX) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_silent) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_simplecond) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_speculate) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_splat32) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_transpose) | 
 | 		   || chk_type (kv3_v2, Modifier_kv3_v2_variant) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_accesses) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_boolcas) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_cachelev) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_channel) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_coherency) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_comparison) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_conjugate) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_doscale) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_exunum) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_floatcomp) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_hindex) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_lsomask) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_lsumask) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_lsupack) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_qindex) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_rounding) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_scalarcond) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_shuffleV) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_shuffleX) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_silent) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_simplecond) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_speculate) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_splat32) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_transpose) | 
 | 		   || chk_type (kv4_v1, Modifier_kv4_v1_variant)) | 
 | 	    { | 
 | 	      /* Do nothing.  */ | 
 | 	    } | 
 | 	  else if (chk_type (kv3_v1, Immediate_kv3_v1_sysnumber) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_sysnumber) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_sysnumber) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_wrapped8) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_wrapped8) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed10) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed10) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed10) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed16) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed16) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed16) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed27) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed27) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed27) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_wrapped32) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_wrapped32) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_wrapped32) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed37) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed37) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed37) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed43) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed43) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed43) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_signed54) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_signed54) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_signed54) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_wrapped64) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_wrapped64) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_wrapped64) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_unsigned6) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_unsigned6) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_unsigned6)) | 
 | 	    crt_peb_insn->immediate = value; | 
 | 	  else if (chk_type (kv3_v1, Immediate_kv3_v1_pcrel17) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_pcrel17) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_pcrel17) | 
 | 		   || chk_type (kv3_v1, Immediate_kv3_v1_pcrel27) | 
 | 		   || chk_type (kv3_v2, Immediate_kv3_v2_pcrel27) | 
 | 		   || chk_type (kv4_v1, Immediate_kv4_v1_pcrel27)) | 
 | 	    crt_peb_insn->immediate = value + memaddr; | 
 | 	  else | 
 | 	    return -1; | 
 | 	} | 
 |  | 
 |       if (is_a_peb_insn) | 
 | 	peb->nb_insn++; | 
 |       continue; | 
 |     } | 
 |  | 
 |   return nb_syl * 4; | 
 | #undef chk_type | 
 | } | 
 |  | 
 | void | 
 | print_kvx_disassembler_options (FILE * stream) | 
 | { | 
 |   fprintf (stream, _("\n\ | 
 | The following KVX specific disassembler options are supported for use\n\ | 
 | with the -M switch (multiple options should be separated by commas):\n")); | 
 |  | 
 |   fprintf (stream, _("\n\ | 
 |   pretty               Print 32-bit words in natural order corresponding to \ | 
 | re-ordered instruction.\n")); | 
 |  | 
 |   fprintf (stream, _("\n\ | 
 |   compact-assembly     Do not emit a new line between bundles of instructions.\ | 
 | \n")); | 
 |  | 
 |   fprintf (stream, _("\n\ | 
 |   no-compact-assembly  Emit a new line between bundles of instructions.\n")); | 
 |  | 
 |   fprintf (stream, _("\n")); | 
 | } |