Home | History | Annotate | Download | only in opcodes
      1 /* TI C6X disassembler.
      2    Copyright (C) 2010-2014 Free Software Foundation, Inc.
      3    Contributed by Joseph Myers <joseph (at) codesourcery.com>
      4    		  Bernd Schmidt  <bernds (at) codesourcery.com>
      5 
      6    This file is part of libopcodes.
      7 
      8    This library is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    It is distributed in the hope that it will be useful, but WITHOUT
     14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16    License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21    MA 02110-1301, USA.  */
     22 
     23 #include "sysdep.h"
     24 #include "dis-asm.h"
     25 #include "opcode/tic6x.h"
     26 #include "libiberty.h"
     27 
     28 /* Define the instruction format table.  */
     29 const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max] =
     30   {
     31 #define FMT(name, num_bits, cst_bits, mask, fields) \
     32     { num_bits, cst_bits, mask, fields },
     33 #include "opcode/tic6x-insn-formats.h"
     34 #undef FMT
     35   };
     36 
     37 /* Define the control register table.  */
     38 const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max] =
     39   {
     40 #define CTRL(name, isa, rw, crlo, crhi_mask)	\
     41     {						\
     42       STRINGX(name),				\
     43       CONCAT2(TIC6X_INSN_,isa),			\
     44       CONCAT2(tic6x_rw_,rw),			\
     45       crlo,					\
     46       crhi_mask					\
     47     },
     48 #include "opcode/tic6x-control-registers.h"
     49 #undef CTRL
     50   };
     51 
     52 /* Define the opcode table.  */
     53 const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max] =
     54   {
     55 #define INSNU(name, func_unit, format, type, isa, flags, fixed, ops, var) \
     56     {									\
     57       STRINGX(name),							\
     58       CONCAT2(tic6x_func_unit_,func_unit),				\
     59       CONCAT3(tic6x_insn_format,_,format),	      			\
     60       CONCAT2(tic6x_pipeline_,type),					\
     61       CONCAT2(TIC6X_INSN_,isa),						\
     62       flags,								\
     63       fixed,								\
     64       ops,								\
     65       var								\
     66     },
     67 #define INSNUE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
     68     {									\
     69       STRINGX(name),							\
     70       CONCAT2(tic6x_func_unit_,func_unit),				\
     71       CONCAT3(tic6x_insn_format,_,format),	      			\
     72       CONCAT2(tic6x_pipeline_,type),					\
     73       CONCAT2(TIC6X_INSN_,isa),						\
     74       flags,								\
     75       fixed,								\
     76       ops,								\
     77       var								\
     78     },
     79 #define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
     80     {									\
     81       STRINGX(name),							\
     82       CONCAT2(tic6x_func_unit_,func_unit),				\
     83       CONCAT4(tic6x_insn_format_,func_unit,_,format),			\
     84       CONCAT2(tic6x_pipeline_,type),					\
     85       CONCAT2(TIC6X_INSN_,isa),						\
     86       flags,								\
     87       fixed,								\
     88       ops,								\
     89       var								\
     90     },
     91 #define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
     92     {									\
     93       STRINGX(name),							\
     94       CONCAT2(tic6x_func_unit_,func_unit),				\
     95       CONCAT4(tic6x_insn_format_,func_unit,_,format),			\
     96       CONCAT2(tic6x_pipeline_,type),					\
     97       CONCAT2(TIC6X_INSN_,isa),						\
     98       flags,								\
     99       fixed,								\
    100       ops,								\
    101       var								\
    102     },
    103 #include "opcode/tic6x-opcode-table.h"
    104 #undef INSN
    105 #undef INSNE
    106 #undef INSNU
    107 #undef INSNUE
    108   };
    109 
    110 /* If instruction format FMT has a field FIELD, return a pointer to
    111    the description of that field; otherwise return NULL.  */
    112 
    113 const tic6x_insn_field *
    114 tic6x_field_from_fmt (const tic6x_insn_format *fmt, tic6x_insn_field_id field)
    115 {
    116   unsigned int f;
    117 
    118   for (f = 0; f < fmt->num_fields; f++)
    119     if (fmt->fields[f].field_id == field)
    120       return &fmt->fields[f];
    121 
    122   return NULL;
    123 }
    124 
    125 /* Extract the field width.  */
    126 
    127 static unsigned int
    128 tic6x_field_width (const tic6x_insn_field *field)
    129 {
    130   unsigned int i;
    131   unsigned int width = 0;
    132 
    133   if (!field->num_bitfields)
    134     return field->bitfields[0].width;
    135 
    136   for (i = 0 ; i < field->num_bitfields ; i++)
    137     width += field->bitfields[i].width;
    138 
    139   return width;
    140 }
    141 
    142 /* Extract the bits corresponding to FIELD from OPCODE.  */
    143 
    144 static unsigned int
    145 tic6x_field_bits (unsigned int opcode, const tic6x_insn_field *field)
    146 {
    147   unsigned int i;
    148   unsigned int val = 0;
    149 
    150   if (!field->num_bitfields)
    151     return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1);
    152 
    153   for (i = 0 ; i < field->num_bitfields ; i++)
    154     val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1))
    155       << field->bitfields[i].pos;
    156 
    157   return val;
    158 }
    159 
    160 /* Extract a 32-bit value read from the instruction stream.  */
    161 
    162 static unsigned int
    163 tic6x_extract_32 (unsigned char *p, struct disassemble_info *info)
    164 {
    165   if (info->endian == BFD_ENDIAN_LITTLE)
    166     return (p[0]) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
    167   else
    168     return (p[3]) | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
    169 }
    170 
    171 /* Extract a 16-bit value read from the instruction stream.  */
    172 
    173 static unsigned int
    174 tic6x_extract_16 (unsigned char *p, tic6x_fetch_packet_header *header,
    175                   struct disassemble_info *info)
    176 {
    177   unsigned int op16;
    178 
    179   if (info->endian == BFD_ENDIAN_LITTLE)
    180     op16 = (p[0]) | (p[1] << 8);
    181   else
    182     op16 = (p[1]) | (p[0] << 8);
    183   op16 |= (header->sat << TIC6X_COMPACT_SAT_POS);
    184   op16 |= (header->br << TIC6X_COMPACT_BR_POS);
    185   op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS);
    186   return op16;
    187 }
    188 
    189 /* FP points to a fetch packet.  Return whether it is header-based; if
    190    it is, fill in HEADER.  */
    191 
    192 static bfd_boolean
    193 tic6x_check_fetch_packet_header (unsigned char *fp,
    194 				 tic6x_fetch_packet_header *header,
    195 				 struct disassemble_info *info)
    196 {
    197   int i;
    198 
    199   header->header = tic6x_extract_32 (fp + 28, info);
    200 
    201   if ((header->header & 0xf0000000) != 0xe0000000)
    202     {
    203       header->prot = 0;
    204       header->rs = 0;
    205       header->dsz = 0;
    206       header->br = 0;
    207       header->sat = 0;
    208       for (i = 0; i < 7; i++)
    209 	header->word_compact[i] = FALSE;
    210       for (i = 0; i < 14; i++)
    211 	header->p_bits[i] = FALSE;
    212       return FALSE;
    213     }
    214 
    215   for (i = 0; i < 7; i++)
    216     header->word_compact[i]
    217       = (header->header & (1u << (21 + i))) ? TRUE : FALSE;
    218 
    219   header->prot = (header->header & (1u << 20)) ? TRUE : FALSE;
    220   header->rs = (header->header & (1u << 19)) ? TRUE : FALSE;
    221   header->dsz = (header->header >> 16) & 0x7;
    222   header->br = (header->header & (1u << 15)) ? TRUE : FALSE;
    223   header->sat = (header->header & (1u << 14)) ? TRUE : FALSE;
    224 
    225   for (i = 0; i < 14; i++)
    226     header->p_bits[i]
    227       = (header->header & (1u << i)) ? TRUE : FALSE;
    228 
    229   return TRUE;
    230 }
    231 
    232 /* Disassemble the instruction at ADDR and print it using
    233    INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes
    234    consumed.  */
    235 
    236 int
    237 print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
    238 {
    239   int status;
    240   bfd_vma fp_addr;
    241   bfd_vma fp_offset;
    242   unsigned char fp[32];
    243   unsigned int opcode;
    244   tic6x_opcode_id opcode_id;
    245   bfd_boolean fetch_packet_header_based;
    246   tic6x_fetch_packet_header header;
    247   unsigned int num_bits;
    248   bfd_boolean bad_offset = FALSE;
    249 
    250   fp_offset = addr & 0x1f;
    251   fp_addr = addr - fp_offset;
    252   status = info->read_memory_func (fp_addr, fp, 32, info);
    253   if (status)
    254     {
    255       info->memory_error_func (status, addr, info);
    256       return -1;
    257     }
    258 
    259   fetch_packet_header_based
    260     = tic6x_check_fetch_packet_header (fp, &header, info);
    261   if (fetch_packet_header_based)
    262     {
    263       if (fp_offset & 0x1)
    264 	bad_offset = TRUE;
    265       if ((fp_offset & 0x3) && (fp_offset >= 28
    266 				|| !header.word_compact[fp_offset >> 2]))
    267 	bad_offset = TRUE;
    268       if (fp_offset == 28)
    269 	{
    270 	  info->bytes_per_chunk = 4;
    271 	  info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
    272 			      header.header);
    273 	  return 4;
    274 	}
    275       num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
    276     }
    277   else
    278     {
    279       num_bits = 32;
    280       if (fp_offset & 0x3)
    281 	bad_offset = TRUE;
    282     }
    283 
    284   if (bad_offset)
    285     {
    286       info->bytes_per_chunk = 1;
    287       info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
    288       return 1;
    289     }
    290 
    291   if (num_bits == 16)
    292     {
    293       /* The least-significant part of a 32-bit word comes logically
    294 	 before the most-significant part.  For big-endian, follow the
    295 	 TI assembler in showing instructions in logical order by
    296 	 pretending that the two halves of the word are in opposite
    297 	 locations to where they actually are.  */
    298       if (info->endian == BFD_ENDIAN_LITTLE)
    299 	opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
    300       else
    301 	opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
    302     }
    303   else
    304     opcode = tic6x_extract_32 (fp + fp_offset, info);
    305 
    306   for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
    307     {
    308       const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
    309       const tic6x_insn_format *const fmt
    310 	= &tic6x_insn_format_table[opc->format];
    311       const tic6x_insn_field *creg_field;
    312       bfd_boolean p_bit;
    313       const char *parallel;
    314       const char *cond = "";
    315       const char *func_unit;
    316       char func_unit_buf[7];
    317       unsigned int func_unit_side = 0;
    318       unsigned int func_unit_data_side = 0;
    319       unsigned int func_unit_cross = 0;
    320       unsigned int t_val = 0;
    321       /* The maximum length of the text of a non-PC-relative operand
    322 	 is 24 bytes (SPMASK masking all eight functional units, with
    323 	 separating commas and trailing NUL).  */
    324       char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
    325       bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
    326       bfd_boolean operands_text[TIC6X_MAX_OPERANDS] = { FALSE };
    327       bfd_boolean operands_pcrel[TIC6X_MAX_OPERANDS] = { FALSE };
    328       unsigned int fix;
    329       unsigned int num_operands;
    330       unsigned int op_num;
    331       bfd_boolean fixed_ok;
    332       bfd_boolean operands_ok;
    333       bfd_boolean have_t = FALSE;
    334 
    335       if (opc->flags & TIC6X_FLAG_MACRO)
    336 	continue;
    337       if (fmt->num_bits != num_bits)
    338 	continue;
    339       if ((opcode & fmt->mask) != fmt->cst_bits)
    340 	continue;
    341 
    342       /* If the format has a creg field, it is only a candidate for a
    343 	 match if the creg and z fields have values indicating a valid
    344 	 condition; reserved values indicate either an instruction
    345 	 format without a creg field, or an invalid instruction.  */
    346       creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
    347       if (creg_field)
    348 	{
    349 	  const tic6x_insn_field *z_field;
    350 	  unsigned int creg_value, z_value;
    351 	  static const char *const conds[8][2] =
    352 	    {
    353 	      { "", NULL },
    354 	      { "[b0] ", "[!b0] " },
    355 	      { "[b1] ", "[!b1] " },
    356 	      { "[b2] ", "[!b2] " },
    357 	      { "[a1] ", "[!a1] " },
    358 	      { "[a2] ", "[!a2] " },
    359 	      { "[a0] ", "[!a0] " },
    360 	      { NULL, NULL }
    361 	    };
    362 
    363 	  /* A creg field is not meaningful without a z field, so if
    364 	     the z field is not present this is an error in the format
    365 	     table.  */
    366 	  z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
    367 	  if (!z_field)
    368 	    {
    369 	      printf ("*** opcode %x: missing z field", opcode);
    370 	      abort ();
    371 	    }
    372 
    373 	  creg_value = tic6x_field_bits (opcode, creg_field);
    374 	  z_value = tic6x_field_bits (opcode, z_field);
    375 	  cond = conds[creg_value][z_value];
    376 	  if (cond == NULL)
    377 	    continue;
    378 	}
    379 
    380       if (opc->flags & TIC6X_FLAG_INSN16_SPRED)
    381 	{
    382 	  const tic6x_insn_field *cc_field;
    383           unsigned int s_value = 0;
    384           unsigned int z_value = 0;
    385           bfd_boolean cond_known = FALSE;
    386           static const char *const conds[2][2] =
    387             {
    388               { "[a0] ", "[!a0] " },
    389               { "[b0] ", "[!b0] " }
    390             };
    391 
    392           cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc);
    393 
    394           if (cc_field)
    395 	    {
    396 	      unsigned int cc_value;
    397 
    398 	      cc_value = tic6x_field_bits (opcode, cc_field);
    399 	      s_value = (cc_value & 0x2) >> 1;
    400 	      z_value = (cc_value & 0x1);
    401 	      cond_known = TRUE;
    402 	    }
    403 	  else
    404 	    {
    405 	      const tic6x_insn_field *z_field;
    406 	      const tic6x_insn_field *s_field;
    407 
    408 	      s_field = tic6x_field_from_fmt (fmt, tic6x_field_s);
    409 
    410 	      if (!s_field)
    411 		{
    412 		  printf ("opcode %x: missing compact insn predicate register field (s field)\n",
    413 			  opcode);
    414 		  abort ();
    415 		}
    416 	      s_value = tic6x_field_bits (opcode, s_field);
    417 	      z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
    418 	      if (!z_field)
    419 		{
    420 		  printf ("opcode %x: missing compact insn predicate z_value (z field)\n", opcode);
    421 		  abort ();
    422 		}
    423 
    424 	      z_value = tic6x_field_bits (opcode, z_field);
    425 	      cond_known = TRUE;
    426 	    }
    427 
    428           if (!cond_known)
    429 	    {
    430 	      printf ("opcode %x: unspecified ompact insn predicate\n", opcode);
    431 	      abort ();
    432 	    }
    433           cond = conds[s_value][z_value];
    434 	}
    435 
    436       /* All fixed fields must have matching values; all fields with
    437 	 restricted ranges must have values within those ranges.  */
    438       fixed_ok = TRUE;
    439       for (fix = 0; fix < opc->num_fixed_fields; fix++)
    440 	{
    441 	  unsigned int field_bits;
    442 	  const tic6x_insn_field *const field
    443 	    = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
    444 
    445 	  if (!field)
    446 	    {
    447 	      printf ("opcode %x: missing field #%d for FIX #%d\n",
    448 		      opcode, opc->fixed_fields[fix].field_id, fix);
    449 	      abort ();
    450 	    }
    451 
    452 	  field_bits = tic6x_field_bits (opcode, field);
    453 	  if (field_bits < opc->fixed_fields[fix].min_val
    454 	      || field_bits > opc->fixed_fields[fix].max_val)
    455 	    {
    456 	      fixed_ok = FALSE;
    457 	      break;
    458 	    }
    459 	}
    460       if (!fixed_ok)
    461 	continue;
    462 
    463       /* The instruction matches.  */
    464 
    465       /* The p-bit indicates whether this instruction is in parallel
    466 	 with the *next* instruction, whereas the parallel bars
    467 	 indicate the instruction is in parallel with the *previous*
    468 	 instruction.  Thus, we must find the p-bit for the previous
    469 	 instruction.  */
    470       if (num_bits == 16 && (fp_offset & 0x2) == 2)
    471 	{
    472 	  /* This is the logically second (most significant; second in
    473 	     fp_offset terms because fp_offset relates to logical not
    474 	     physical addresses) instruction of a compact pair; find
    475 	     the p-bit for the first (least significant).  */
    476 	  p_bit = header.p_bits[(fp_offset >> 2) << 1];
    477 	}
    478       else if (fp_offset >= 4)
    479 	{
    480 	  /* Find the last instruction of the previous word in this
    481 	     fetch packet.  For compact instructions, this is the most
    482 	     significant 16 bits.  */
    483 	  if (fetch_packet_header_based
    484 	      && header.word_compact[(fp_offset >> 2) - 1])
    485 	    p_bit = header.p_bits[(fp_offset >> 1) - 1];
    486 	  else
    487 	    {
    488 	      unsigned int prev_opcode
    489 		= tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
    490 	      p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
    491 	    }
    492 	}
    493       else
    494 	{
    495 	  /* Find the last instruction of the previous fetch
    496 	     packet.  */
    497 	  unsigned char fp_prev[32];
    498 
    499 	  status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
    500 	  if (status)
    501 	    /* No previous instruction to be parallel with.  */
    502 	    p_bit = FALSE;
    503 	  else
    504 	    {
    505 	      bfd_boolean prev_header_based;
    506 	      tic6x_fetch_packet_header prev_header;
    507 
    508 	      prev_header_based
    509 		= tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
    510 	      if (prev_header_based && prev_header.word_compact[6])
    511 		p_bit = prev_header.p_bits[13];
    512 	      else
    513 		{
    514 		  unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
    515 							       info);
    516 		  p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
    517 		}
    518 	    }
    519 	}
    520       parallel = p_bit ? "|| " : "";
    521 
    522       if (opc->func_unit == tic6x_func_unit_nfu)
    523 	func_unit = "";
    524       else
    525 	{
    526 	  unsigned int fld_num;
    527 	  char func_unit_char;
    528 	  const char *data_str;
    529 	  bfd_boolean have_areg = FALSE;
    530 	  bfd_boolean have_cross = FALSE;
    531 
    532 	  func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
    533 	  func_unit_cross = 0;
    534 	  func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
    535 
    536 	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
    537 	    {
    538 	      const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
    539 	      const tic6x_insn_field *field;
    540 	      unsigned int fld_val;
    541 
    542 	      field = tic6x_field_from_fmt (fmt, enc->field_id);
    543 
    544 	      if (!field)
    545 		{
    546 		  printf ("opcode %x: could not retrieve field (field_id:%d)\n",
    547 			  opcode, fld_num);
    548 		  abort ();
    549 		}
    550 
    551 	      fld_val = tic6x_field_bits (opcode, field);
    552 
    553 	      switch (enc->coding_method)
    554 		{
    555 		case tic6x_coding_fu:
    556 		  /* The side must be specified exactly once.  */
    557 		  if (func_unit_side)
    558 		    {
    559 		      printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
    560 			      opcode, fld_num);
    561 		      abort ();
    562 		    }
    563 		  func_unit_side = (fld_val ? 2 : 1);
    564 		  break;
    565 
    566 		case tic6x_coding_data_fu:
    567 		  /* The data side must be specified exactly once.  */
    568 		  if (func_unit_data_side)
    569 		    {
    570 		      printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
    571 			      opcode, fld_num);
    572 		      abort ();
    573 		    }
    574 		  func_unit_data_side = (fld_val ? 2 : 1);
    575 		  break;
    576 
    577 		case tic6x_coding_xpath:
    578 		  /* Cross path use must be specified exactly
    579 		     once.  */
    580 		  if (have_cross)
    581 		    {
    582 		      printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
    583 			      opcode, fld_num);
    584 		      abort ();
    585 		    }
    586 		  have_cross = TRUE;
    587 		  func_unit_cross = fld_val;
    588 		  break;
    589 
    590                 case tic6x_coding_rside:
    591                   /* If the format has a t field, use it for src/dst register side.  */
    592                   have_t = TRUE;
    593                   t_val = fld_val;
    594                   func_unit_data_side = (t_val ? 2 : 1);
    595                   break;
    596 
    597 		case tic6x_coding_areg:
    598 		  have_areg = TRUE;
    599 		  break;
    600 
    601 		default:
    602 		  /* Don't relate to functional units.  */
    603 		  break;
    604 		}
    605 	    }
    606 
    607 	  /* The side of the functional unit used must now have been
    608 	     determined either from the flags or from an instruction
    609 	     field.  */
    610 	  if (func_unit_side != 1 && func_unit_side != 2)
    611 	    {
    612 	      printf ("opcode %x: func_unit_side is not encoded!\n", opcode);
    613 	      abort ();
    614 	    }
    615 
    616 	  /* Cross paths are not applicable when sides are specified
    617 	     for both address and data paths.  */
    618 	  if (func_unit_data_side && have_cross)
    619 	    {
    620 	      printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n",
    621 		      opcode);
    622 	      abort ();
    623 	    }
    624 
    625 	  /* Separate address and data paths are only applicable for
    626 	     the D unit.  */
    627 	  if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
    628 	    {
    629 	      printf ("opcode %x: separate address and data paths only applicable for D unit!\n",
    630 		      opcode);
    631 	      abort ();
    632           }
    633 
    634 	  /* If an address register is being used but in ADDA rather
    635 	     than a load or store, it uses a cross path for side-A
    636 	     instructions, and the cross path use is not specified by
    637 	     an instruction field.  */
    638 	  if (have_areg && !func_unit_data_side)
    639 	    {
    640 	      if (have_cross)
    641 		{
    642 		  printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode);
    643 		  abort ();
    644 		}
    645 	      func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
    646 	    }
    647 
    648 	  switch (opc->func_unit)
    649 	    {
    650 	    case tic6x_func_unit_d:
    651 	      func_unit_char = 'D';
    652 	      break;
    653 
    654 	    case tic6x_func_unit_l:
    655 	      func_unit_char = 'L';
    656 	      break;
    657 
    658 	    case tic6x_func_unit_m:
    659 	      func_unit_char = 'M';
    660 	      break;
    661 
    662 	    case tic6x_func_unit_s:
    663 	      func_unit_char = 'S';
    664 	      break;
    665 
    666 	    default:
    667               printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
    668 	      abort ();
    669 	    }
    670 
    671 	  switch (func_unit_data_side)
    672 	    {
    673 	    case 0:
    674 	      data_str = "";
    675 	      break;
    676 
    677 	    case 1:
    678 	      data_str = "T1";
    679 	      break;
    680 
    681 	    case 2:
    682 	      data_str = "T2";
    683 	      break;
    684 
    685 	    default:
    686               printf ("opcode %x: illegal data func_unit specifier %d\n",
    687 		      opcode, func_unit_data_side);
    688 	      abort ();
    689 	    }
    690 
    691 	  if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
    692 	      func_unit_cross = 1;
    693 
    694 	  snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
    695 		    func_unit_side, (func_unit_cross ? "X" : ""), data_str);
    696 	  func_unit = func_unit_buf;
    697 	}
    698 
    699       /* For each operand there must be one or more fields set based
    700 	 on that operand, that can together be used to derive the
    701 	 operand value.  */
    702       operands_ok = TRUE;
    703       num_operands = opc->num_operands;
    704       for (op_num = 0; op_num < num_operands; op_num++)
    705 	{
    706 	  unsigned int fld_num;
    707 	  unsigned int mem_base_reg = 0;
    708 	  bfd_boolean mem_base_reg_known = FALSE;
    709 	  bfd_boolean mem_base_reg_known_long = FALSE;
    710 	  unsigned int mem_offset = 0;
    711 	  bfd_boolean mem_offset_known = FALSE;
    712 	  bfd_boolean mem_offset_known_long = FALSE;
    713 	  unsigned int mem_mode = 0;
    714 	  bfd_boolean mem_mode_known = FALSE;
    715 	  unsigned int mem_scaled = 0;
    716 	  bfd_boolean mem_scaled_known = FALSE;
    717 	  unsigned int crlo = 0;
    718 	  bfd_boolean crlo_known = FALSE;
    719 	  unsigned int crhi = 0;
    720 	  bfd_boolean crhi_known = FALSE;
    721 	  bfd_boolean spmask_skip_operand = FALSE;
    722 	  unsigned int fcyc_bits = 0;
    723 	  bfd_boolean prev_sploop_found = FALSE;
    724 
    725 	  switch (opc->operand_info[op_num].form)
    726 	    {
    727 	    case tic6x_operand_b15reg:
    728 	      /* Fully determined by the functional unit.  */
    729 	      operands_text[op_num] = TRUE;
    730 	      snprintf (operands[op_num], 24, "b15");
    731 	      continue;
    732 
    733 	    case tic6x_operand_zreg:
    734 	      /* Fully determined by the functional unit.  */
    735 	      operands_text[op_num] = TRUE;
    736 	      snprintf (operands[op_num], 24, "%c0",
    737 			(func_unit_side == 2 ? 'b' : 'a'));
    738 	      continue;
    739 
    740 	    case tic6x_operand_retreg:
    741 	      /* Fully determined by the functional unit.  */
    742 	      operands_text[op_num] = TRUE;
    743 	      snprintf (operands[op_num], 24, "%c3",
    744 			(func_unit_side == 2 ? 'b' : 'a'));
    745 	      continue;
    746 
    747 	    case tic6x_operand_irp:
    748 	      operands_text[op_num] = TRUE;
    749 	      snprintf (operands[op_num], 24, "irp");
    750 	      continue;
    751 
    752 	    case tic6x_operand_nrp:
    753 	      operands_text[op_num] = TRUE;
    754 	      snprintf (operands[op_num], 24, "nrp");
    755 	      continue;
    756 
    757 	    case tic6x_operand_ilc:
    758 	      operands_text[op_num] = TRUE;
    759 	      snprintf (operands[op_num], 24, "ilc");
    760 	      continue;
    761 
    762 	    case tic6x_operand_hw_const_minus_1:
    763 	      operands_text[op_num] = TRUE;
    764 	      snprintf (operands[op_num], 24, "-1");
    765 	      continue;
    766 
    767 	    case tic6x_operand_hw_const_0:
    768 	      operands_text[op_num] = TRUE;
    769 	      snprintf (operands[op_num], 24, "0");
    770 	      continue;
    771 
    772 	    case tic6x_operand_hw_const_1:
    773 	      operands_text[op_num] = TRUE;
    774 	      snprintf (operands[op_num], 24, "1");
    775 	      continue;
    776 
    777 	    case tic6x_operand_hw_const_5:
    778 	      operands_text[op_num] = TRUE;
    779 	      snprintf (operands[op_num], 24, "5");
    780 	      continue;
    781 
    782 	    case tic6x_operand_hw_const_16:
    783 	      operands_text[op_num] = TRUE;
    784 	      snprintf (operands[op_num], 24, "16");
    785 	      continue;
    786 
    787 	    case tic6x_operand_hw_const_24:
    788 	      operands_text[op_num] = TRUE;
    789 	      snprintf (operands[op_num], 24, "24");
    790 	      continue;
    791 
    792 	    case tic6x_operand_hw_const_31:
    793 	      operands_text[op_num] = TRUE;
    794 	      snprintf (operands[op_num], 24, "31");
    795 	      continue;
    796 
    797 	    default:
    798 	      break;
    799 	    }
    800 
    801 	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
    802 	    {
    803 	      const tic6x_coding_field *const enc
    804 		= &opc->variable_fields[fld_num];
    805 	      const tic6x_insn_field *field;
    806 	      unsigned int fld_val;
    807 	      unsigned int reg_base = 0;
    808 	      signed int signed_fld_val;
    809               char reg_side = '?';
    810 
    811 	      if (enc->operand_num != op_num)
    812 		continue;
    813 	      field = tic6x_field_from_fmt (fmt, enc->field_id);
    814 	      if (!field)
    815 		{
    816 		  printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
    817 		  abort ();
    818 		}
    819               fld_val = tic6x_field_bits (opcode, field);
    820 	      switch (enc->coding_method)
    821 		{
    822                 case tic6x_coding_cst_s3i:
    823                   (fld_val == 0x00) && (fld_val = 0x10);
    824                   (fld_val == 0x07) && (fld_val = 0x08);
    825                   /* Fall through.  */
    826 		case tic6x_coding_ucst:
    827 		case tic6x_coding_ulcst_dpr_byte:
    828 		case tic6x_coding_ulcst_dpr_half:
    829 		case tic6x_coding_ulcst_dpr_word:
    830 		case tic6x_coding_lcst_low16:
    831 		  switch (opc->operand_info[op_num].form)
    832 		    {
    833 		    case tic6x_operand_asm_const:
    834 		    case tic6x_operand_link_const:
    835 		      operands_text[op_num] = TRUE;
    836 		      snprintf (operands[op_num], 24, "%u", fld_val);
    837 		      break;
    838 
    839 		    case tic6x_operand_mem_long:
    840 		      mem_offset = fld_val;
    841 		      mem_offset_known_long = TRUE;
    842 		      break;
    843 
    844 		    default:
    845                       printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
    846 		      abort ();
    847 		    }
    848 		  break;
    849 
    850 		case tic6x_coding_lcst_high16:
    851 		  operands_text[op_num] = TRUE;
    852 		  snprintf (operands[op_num], 24, "%u", fld_val << 16);
    853 		  break;
    854 
    855                 case tic6x_coding_scst_l3i:
    856 		  operands_text[op_num] = TRUE;
    857                   if (fld_val == 0)
    858 		    {
    859 		      signed_fld_val = 8;
    860 		    }
    861 		  else
    862 		    {
    863 		      signed_fld_val = (signed int) fld_val;
    864 		      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
    865 		      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
    866 		    }
    867 		  snprintf (operands[op_num], 24, "%d", signed_fld_val);
    868 		  break;
    869 
    870 		case tic6x_coding_scst:
    871 		  operands_text[op_num] = TRUE;
    872 		  signed_fld_val = (signed int) fld_val;
    873 		  signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
    874 		  signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
    875 		  snprintf (operands[op_num], 24, "%d", signed_fld_val);
    876 		  break;
    877 
    878 		case tic6x_coding_ucst_minus_one:
    879 		  operands_text[op_num] = TRUE;
    880 		  snprintf (operands[op_num], 24, "%u", fld_val + 1);
    881 		  break;
    882 
    883 		case tic6x_coding_pcrel:
    884 		case tic6x_coding_pcrel_half:
    885 		  signed_fld_val = (signed int) fld_val;
    886 		  signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
    887 		  signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
    888 		  if (fetch_packet_header_based
    889 		      && enc->coding_method == tic6x_coding_pcrel_half)
    890 		    signed_fld_val *= 2;
    891 		  else
    892 		    signed_fld_val *= 4;
    893 		  operands_pcrel[op_num] = TRUE;
    894 		  operands_addresses[op_num] = fp_addr + signed_fld_val;
    895 		  break;
    896 
    897 		case tic6x_coding_regpair_msb:
    898 		  if (opc->operand_info[op_num].form != tic6x_operand_regpair)
    899 		    abort ();
    900 		  operands_text[op_num] = TRUE;
    901 		  snprintf (operands[op_num], 24, "%c%u:%c%u",
    902 			    (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
    903 			    (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
    904 		  break;
    905 
    906 		case tic6x_coding_pcrel_half_unsigned:
    907 		  operands_pcrel[op_num] = TRUE;
    908 		  operands_addresses[op_num] = fp_addr + 2 * fld_val;
    909 		  break;
    910 
    911 		case tic6x_coding_reg_shift:
    912 		  fld_val <<= 1;
    913 		  /* Fall through.  */
    914 		case tic6x_coding_reg:
    915                   if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
    916                     {
    917 		      reg_base = 16;
    918                     }
    919 		  switch (opc->operand_info[op_num].form)
    920 		    {
    921 		    case tic6x_operand_treg:
    922                       if (!have_t)
    923 			{
    924 			  printf ("opcode %x: operand treg but missing t field\n", opcode);
    925 			  abort ();
    926 			}
    927 		      operands_text[op_num] = TRUE;
    928                       reg_side = t_val ? 'b' : 'a';
    929 		      snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
    930 		      break;
    931 
    932 		    case tic6x_operand_reg:
    933 		      operands_text[op_num] = TRUE;
    934                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
    935 		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
    936 		      break;
    937 
    938 		    case tic6x_operand_reg_nors:
    939 		      operands_text[op_num] = TRUE;
    940                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
    941 		      snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
    942 		      break;
    943 
    944 		    case tic6x_operand_reg_bside:
    945 		      operands_text[op_num] = TRUE;
    946 		      snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
    947 		      break;
    948 
    949 		    case tic6x_operand_reg_bside_nors:
    950 		      operands_text[op_num] = TRUE;
    951 		      snprintf (operands[op_num], 24, "b%u", fld_val);
    952 		      break;
    953 
    954 		    case tic6x_operand_xreg:
    955 		      operands_text[op_num] = TRUE;
    956                       reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
    957 		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
    958 		      break;
    959 
    960 		    case tic6x_operand_dreg:
    961 		      operands_text[op_num] = TRUE;
    962                       reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
    963 		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
    964 		      break;
    965 
    966 		    case tic6x_operand_regpair:
    967 		      operands_text[op_num] = TRUE;
    968 		      if (fld_val & 1)
    969 			operands_ok = FALSE;
    970                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
    971 		      snprintf (operands[op_num], 24, "%c%u:%c%u",
    972                                 reg_side, reg_base + fld_val + 1,
    973 				reg_side, reg_base + fld_val);
    974 		      break;
    975 
    976 		    case tic6x_operand_xregpair:
    977 		      operands_text[op_num] = TRUE;
    978 		      if (fld_val & 1)
    979 			operands_ok = FALSE;
    980                       reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
    981 		      snprintf (operands[op_num], 24, "%c%u:%c%u",
    982 				reg_side, reg_base + fld_val + 1,
    983 				reg_side, reg_base + fld_val);
    984 		      break;
    985 
    986 		    case tic6x_operand_tregpair:
    987                       if (!have_t)
    988 			{
    989 			  printf ("opcode %x: operand tregpair but missing t field\n", opcode);
    990 			  abort ();
    991 			}
    992 		      operands_text[op_num] = TRUE;
    993 		      if (fld_val & 1)
    994 			operands_ok = FALSE;
    995                       reg_side = t_val ? 'b' : 'a';
    996 		      snprintf (operands[op_num], 24, "%c%u:%c%u",
    997 				reg_side, reg_base + fld_val + 1,
    998 				reg_side, reg_base + fld_val);
    999 		      break;
   1000 
   1001 		    case tic6x_operand_dregpair:
   1002 		      operands_text[op_num] = TRUE;
   1003 		      if (fld_val & 1)
   1004 			operands_ok = FALSE;
   1005                       reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
   1006 		      snprintf (operands[op_num], 24, "%c%u:%c%u",
   1007 				reg_side, reg_base + fld_val + 1,
   1008 				reg_side, reg_base + fld_val);
   1009 		      break;
   1010 
   1011 		    case tic6x_operand_mem_deref:
   1012 		      operands_text[op_num] = TRUE;
   1013                       reg_side = func_unit_side == 2 ? 'b' : 'a';
   1014 		      snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
   1015 		      break;
   1016 
   1017 		    case tic6x_operand_mem_short:
   1018 		    case tic6x_operand_mem_ndw:
   1019 		      mem_base_reg = fld_val;
   1020 		      mem_base_reg_known = TRUE;
   1021 		      break;
   1022 
   1023 		    default:
   1024                       printf ("opcode %x: unexpected operand form %d for operand #%d",
   1025 			      opcode, opc->operand_info[op_num].form, op_num);
   1026 		      abort ();
   1027 		    }
   1028 		  break;
   1029 
   1030                 case tic6x_coding_reg_ptr:
   1031 		  switch (opc->operand_info[op_num].form)
   1032 		    {
   1033 		    case tic6x_operand_mem_short:
   1034 		    case tic6x_operand_mem_ndw:
   1035                       if (fld_val > 0x3u)
   1036 			{
   1037 			  printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
   1038 				 opcode, op_num, fld_val);
   1039 			  abort ();
   1040 			}
   1041 		      mem_base_reg = 0x4 | fld_val;
   1042 		      mem_base_reg_known = TRUE;
   1043 		      break;
   1044 
   1045 		    default:
   1046                       printf ("opcode %x: unexpected operand form %d for operand #%d",
   1047 			      opcode, opc->operand_info[op_num].form, op_num);
   1048 		      abort ();
   1049 		    }
   1050 		  break;
   1051 
   1052 		case tic6x_coding_areg:
   1053 		  switch (opc->operand_info[op_num].form)
   1054 		    {
   1055 		    case tic6x_operand_areg:
   1056 		      operands_text[op_num] = TRUE;
   1057 		      snprintf (operands[op_num], 24, "b%u",
   1058 				fld_val ? 15u : 14u);
   1059 		      break;
   1060 
   1061 		    case tic6x_operand_mem_long:
   1062 		      mem_base_reg = fld_val ? 15u : 14u;
   1063 		      mem_base_reg_known_long = TRUE;
   1064 		      break;
   1065 
   1066 		    default:
   1067                       printf ("opcode %x: bad operand form\n", opcode);
   1068 		      abort ();
   1069 		    }
   1070 		  break;
   1071 
   1072 		case tic6x_coding_mem_offset_minus_one_noscale:
   1073 		case tic6x_coding_mem_offset_minus_one:
   1074 		  fld_val += 1;
   1075 		case tic6x_coding_mem_offset_noscale:
   1076 		case tic6x_coding_mem_offset:
   1077 		  mem_offset = fld_val;
   1078 		  mem_offset_known = TRUE;
   1079 		  if (num_bits == 16)
   1080 		    {
   1081 		      mem_mode_known = TRUE;
   1082 		      mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
   1083 		      mem_scaled_known = TRUE;
   1084 		      mem_scaled = TRUE;
   1085 		      if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
   1086 			{
   1087 			  mem_base_reg_known = TRUE;
   1088 			  mem_base_reg = 15;
   1089 			}
   1090 		      if ( enc->coding_method == tic6x_coding_mem_offset_noscale
   1091 			   || enc->coding_method == tic6x_coding_mem_offset_noscale )
   1092 			mem_scaled = FALSE;
   1093 		    }
   1094 		  break;
   1095 
   1096 		case tic6x_coding_mem_mode:
   1097 		  mem_mode = fld_val;
   1098 		  mem_mode_known = TRUE;
   1099 		  break;
   1100 
   1101 		case tic6x_coding_scaled:
   1102 		  mem_scaled = fld_val;
   1103 		  mem_scaled_known = TRUE;
   1104 		  break;
   1105 
   1106 		case tic6x_coding_crlo:
   1107 		  crlo = fld_val;
   1108 		  crlo_known = TRUE;
   1109 		  break;
   1110 
   1111 		case tic6x_coding_crhi:
   1112 		  crhi = fld_val;
   1113 		  crhi_known = TRUE;
   1114 		  break;
   1115 
   1116 		case tic6x_coding_fstg:
   1117 		case tic6x_coding_fcyc:
   1118 		  if (!prev_sploop_found)
   1119 		    {
   1120 		      bfd_vma search_fp_addr = fp_addr;
   1121 		      bfd_vma search_fp_offset = fp_offset;
   1122 		      bfd_boolean search_fp_header_based
   1123 			= fetch_packet_header_based;
   1124 		      tic6x_fetch_packet_header search_fp_header = header;
   1125 		      unsigned char search_fp[32];
   1126 		      unsigned int search_num_bits;
   1127 		      unsigned int search_opcode;
   1128 		      unsigned int sploop_ii = 0;
   1129 		      int i;
   1130 
   1131 		      memcpy (search_fp, fp, 32);
   1132 
   1133 		      /* To interpret these bits in an SPKERNEL
   1134 			 instruction, we must find the previous
   1135 			 SPLOOP-family instruction.  It may come up to
   1136 			 48 execute packets earlier.  */
   1137 		      for (i = 0; i < 48 * 8; i++)
   1138 			{
   1139 			  /* Find the previous instruction.  */
   1140 			  if (search_fp_offset & 2)
   1141 			    search_fp_offset -= 2;
   1142 			  else if (search_fp_offset >= 4)
   1143 			    {
   1144 			      if (search_fp_header_based
   1145 				  && (search_fp_header.word_compact
   1146 				      [(search_fp_offset >> 2) - 1]))
   1147 				search_fp_offset -= 2;
   1148 			      else
   1149 				search_fp_offset -= 4;
   1150 			    }
   1151 			  else
   1152 			    {
   1153 			      search_fp_addr -= 32;
   1154 			      status = info->read_memory_func (search_fp_addr,
   1155 							       search_fp,
   1156 							       32, info);
   1157 			      if (status)
   1158 				/* No previous SPLOOP instruction.  */
   1159 				break;
   1160 			      search_fp_header_based
   1161 				= (tic6x_check_fetch_packet_header
   1162 				   (search_fp, &search_fp_header, info));
   1163 			      if (search_fp_header_based)
   1164 				search_fp_offset
   1165 				  = search_fp_header.word_compact[6] ? 26 : 24;
   1166 			      else
   1167 				search_fp_offset = 28;
   1168 			    }
   1169 
   1170 			  /* Extract the previous instruction.  */
   1171 			  if (search_fp_header_based)
   1172 			    search_num_bits
   1173 			      = (search_fp_header.word_compact[search_fp_offset
   1174 							       >> 2]
   1175 				 ? 16
   1176 				 : 32);
   1177 			  else
   1178 			    search_num_bits = 32;
   1179 			  if (search_num_bits == 16)
   1180 			    {
   1181 			      if (info->endian == BFD_ENDIAN_LITTLE)
   1182 				search_opcode
   1183 				  = (tic6x_extract_16
   1184 				     (search_fp + search_fp_offset, &header, info));
   1185 			      else
   1186 				search_opcode
   1187 				  = (tic6x_extract_16
   1188 				     (search_fp + (search_fp_offset ^ 2), &header,
   1189 				      info));
   1190 			    }
   1191 			  else
   1192 			    search_opcode
   1193 			      = tic6x_extract_32 (search_fp + search_fp_offset,
   1194 						  info);
   1195 
   1196 			  /* Check whether it is an SPLOOP-family
   1197 			     instruction.  */
   1198 			  if (search_num_bits == 32
   1199 			      && ((search_opcode & 0x003ffffe) == 0x00038000
   1200 				  || (search_opcode & 0x003ffffe) == 0x0003a000
   1201 				  || ((search_opcode & 0x003ffffe)
   1202 				      == 0x0003e000)))
   1203 			    {
   1204 			      prev_sploop_found = TRUE;
   1205 			      sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
   1206 			    }
   1207 			  else if (search_num_bits == 16
   1208 				   && (search_opcode & 0x3c7e) == 0x0c66)
   1209 			    {
   1210 			      prev_sploop_found = TRUE;
   1211 			      sploop_ii
   1212 				= (((search_opcode >> 7) & 0x7)
   1213 				   | ((search_opcode >> 11) & 0x8)) + 1;
   1214 			    }
   1215 			  if (prev_sploop_found)
   1216 			    {
   1217 			      if (sploop_ii <= 0)
   1218 				{
   1219 				  printf ("opcode %x:  sloop index not found (%d)\n", opcode, sploop_ii);
   1220 				  abort ();
   1221 				}
   1222 			      else if (sploop_ii <= 1)
   1223 				fcyc_bits = 0;
   1224 			      else if (sploop_ii <= 2)
   1225 				fcyc_bits = 1;
   1226 			      else if (sploop_ii <= 4)
   1227 				fcyc_bits = 2;
   1228 			      else if (sploop_ii <= 8)
   1229 				fcyc_bits = 3;
   1230 			      else if (sploop_ii <= 14)
   1231 				fcyc_bits = 4;
   1232 			      else
   1233 				prev_sploop_found = FALSE;
   1234 			    }
   1235 			  if (prev_sploop_found)
   1236 			    break;
   1237 			}
   1238 		    }
   1239 		  if (!prev_sploop_found)
   1240 		    {
   1241 		      operands_ok = FALSE;
   1242 		      operands_text[op_num] = TRUE;
   1243 		      break;
   1244 		    }
   1245 		  if (fcyc_bits > tic6x_field_width(field))
   1246 		    {
   1247 		      printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
   1248 		      abort ();
   1249 		    }
   1250 		  if (enc->coding_method == tic6x_coding_fstg)
   1251 		    {
   1252 		      int i, t;
   1253 		      for (t = 0, i = fcyc_bits; i < 6; i++)
   1254 			t = (t << 1) | ((fld_val >> i) & 1);
   1255 		      operands_text[op_num] = TRUE;
   1256 		      snprintf (operands[op_num], 24, "%u", t);
   1257 		    }
   1258 		  else
   1259 		    {
   1260 		      operands_text[op_num] = TRUE;
   1261 		      snprintf (operands[op_num], 24, "%u",
   1262 				fld_val & ((1 << fcyc_bits) - 1));
   1263 		    }
   1264 		  break;
   1265 
   1266 		case tic6x_coding_spmask:
   1267 		  if (fld_val == 0)
   1268 		    spmask_skip_operand = TRUE;
   1269 		  else
   1270 		    {
   1271 		      char *p;
   1272 		      unsigned int i;
   1273 
   1274 		      operands_text[op_num] = TRUE;
   1275 		      p = operands[op_num];
   1276 		      for (i = 0; i < 8; i++)
   1277 			if (fld_val & (1 << i))
   1278 			  {
   1279 			    *p++ = "LSDM"[i/2];
   1280 			    *p++ = '1' + (i & 1);
   1281 			    *p++ = ',';
   1282 			  }
   1283 		      p[-1] = 0;
   1284 		    }
   1285 		  break;
   1286 
   1287 		case tic6x_coding_fu:
   1288 		case tic6x_coding_data_fu:
   1289 		case tic6x_coding_xpath:
   1290 		case tic6x_coding_rside:
   1291 		  /* Don't relate to operands, so operand number is
   1292 		     meaningless.  */
   1293 		  break;
   1294 
   1295 		default:
   1296                   printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
   1297 		  abort ();
   1298 		}
   1299 
   1300 	      if (mem_base_reg_known_long && mem_offset_known_long)
   1301 		{
   1302 		  if (operands_text[op_num] || operands_pcrel[op_num])
   1303 		    {
   1304 		      printf ("opcode %x: long access but operands already known ?\n", opcode);
   1305 		      abort ();
   1306 		    }
   1307 		  operands_text[op_num] = TRUE;
   1308 		  snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
   1309 			    mem_offset * opc->operand_info[op_num].size);
   1310 		}
   1311 
   1312 	      if (mem_base_reg_known && mem_offset_known && mem_mode_known
   1313 		  && (mem_scaled_known
   1314 		      || (opc->operand_info[op_num].form
   1315 			  != tic6x_operand_mem_ndw)))
   1316 		{
   1317 		  char side;
   1318 		  char base[4];
   1319 		  bfd_boolean offset_is_reg;
   1320 		  bfd_boolean offset_scaled;
   1321 		  char offset[4];
   1322 		  char offsetp[6];
   1323 
   1324 		  if (operands_text[op_num] || operands_pcrel[op_num])
   1325 		    {
   1326 		      printf ("opcode %x: mem access operands already known ?\n", opcode);
   1327 		      abort ();
   1328 		    }
   1329 
   1330 		  side = func_unit_side == 2 ? 'b' : 'a';
   1331 		  snprintf (base, 4, "%c%u", side, mem_base_reg);
   1332 
   1333 		  offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
   1334 		  if (offset_is_reg)
   1335 		    {
   1336 
   1337 		      if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
   1338 			{
   1339 			  reg_base = 16;
   1340 			}
   1341 		      snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
   1342 		      if (opc->operand_info[op_num].form
   1343 			  == tic6x_operand_mem_ndw)
   1344 			offset_scaled = mem_scaled ? TRUE : FALSE;
   1345 		      else
   1346 			offset_scaled = TRUE;
   1347 		    }
   1348 		  else
   1349 		    {
   1350 		      if (opc->operand_info[op_num].form
   1351 			  == tic6x_operand_mem_ndw)
   1352 			{
   1353 			  offset_scaled = mem_scaled ? TRUE : FALSE;
   1354 			  snprintf (offset, 4, "%u", mem_offset);
   1355 			}
   1356 		      else
   1357 			{
   1358 			  offset_scaled = FALSE;
   1359 			  snprintf (offset, 4, "%u",
   1360 				    (mem_offset
   1361 				     * opc->operand_info[op_num].size));
   1362 			}
   1363 		    }
   1364 
   1365 		  if (offset_scaled)
   1366 		    snprintf (offsetp, 6, "[%s]", offset);
   1367 		  else
   1368 		    snprintf (offsetp, 6, "(%s)", offset);
   1369 
   1370 		  operands_text[op_num] = TRUE;
   1371 		  switch (mem_mode & ~4u)
   1372 		    {
   1373 		    case 0:
   1374 		      snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
   1375 		      break;
   1376 
   1377 		    case 1:
   1378 		      snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
   1379 		      break;
   1380 
   1381 		    case 2:
   1382 		    case 3:
   1383 		      operands_ok = FALSE;
   1384 		      break;
   1385 
   1386 		    case 8:
   1387 		      snprintf (operands[op_num], 24, "*--%s%s", base,
   1388 				offsetp);
   1389 		      break;
   1390 
   1391 		    case 9:
   1392 		      snprintf (operands[op_num], 24, "*++%s%s", base,
   1393 				offsetp);
   1394 		      break;
   1395 
   1396 		    case 10:
   1397 		      snprintf (operands[op_num], 24, "*%s--%s", base,
   1398 				offsetp);
   1399 		      break;
   1400 
   1401 		    case 11:
   1402 		      snprintf (operands[op_num], 24, "*%s++%s", base,
   1403 				offsetp);
   1404 		      break;
   1405 
   1406 		    default:
   1407                       printf ("*** unknown mem_mode : %d \n", mem_mode);
   1408 		      abort ();
   1409 		    }
   1410 		}
   1411 
   1412 	      if (crlo_known && crhi_known)
   1413 		{
   1414 		  tic6x_rw rw;
   1415 		  tic6x_ctrl_id crid;
   1416 
   1417 		  if (operands_text[op_num] || operands_pcrel[op_num])
   1418 		    {
   1419 		      printf ("*** abort crlo crli\n");
   1420 		      abort ();
   1421 		    }
   1422 
   1423 		  rw = opc->operand_info[op_num].rw;
   1424 		  if (rw != tic6x_rw_read
   1425 		      && rw != tic6x_rw_write)
   1426 		    {
   1427 		      printf ("*** abort rw : %d\n", rw);
   1428 		      abort ();
   1429 		    }
   1430 
   1431 		  for (crid = 0; crid < tic6x_ctrl_max; crid++)
   1432 		    {
   1433 		      if (crlo == tic6x_ctrl_table[crid].crlo
   1434 			  && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
   1435 			  && (rw == tic6x_rw_read
   1436 			      ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
   1437 				 || (tic6x_ctrl_table[crid].rw
   1438 				     == tic6x_rw_read_write))
   1439 			      : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
   1440 				 || (tic6x_ctrl_table[crid].rw
   1441 				     == tic6x_rw_read_write))))
   1442 			break;
   1443 		    }
   1444 		  if (crid == tic6x_ctrl_max)
   1445 		    {
   1446 		      operands_text[op_num] = TRUE;
   1447 		      operands_ok = FALSE;
   1448 		    }
   1449 		  else
   1450 		    {
   1451 		      operands_text[op_num] = TRUE;
   1452 		      snprintf (operands[op_num], 24, "%s",
   1453 				tic6x_ctrl_table[crid].name);
   1454 		    }
   1455 		}
   1456 
   1457 	      if (operands_text[op_num] || operands_pcrel[op_num]
   1458 		  || spmask_skip_operand)
   1459 		break;
   1460 	    }
   1461           /* end for fld_num */
   1462 
   1463 	  if (spmask_skip_operand)
   1464 	    {
   1465 	      /* SPMASK operands are only valid as the single operand
   1466 		 in the opcode table.  */
   1467 	      if (num_operands != 1)
   1468 		{
   1469 		  printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
   1470 		  abort ();
   1471 		}
   1472 	      num_operands = 0;
   1473 	      break;
   1474 	    }
   1475 
   1476 	  /* The operand must by now have been decoded.  */
   1477 	  if (!operands_text[op_num] && !operands_pcrel[op_num])
   1478             {
   1479               printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
   1480               abort ();
   1481             }
   1482         }
   1483       /* end for op_num */
   1484 
   1485       if (!operands_ok)
   1486 	continue;
   1487 
   1488       info->bytes_per_chunk = num_bits / 8;
   1489       info->fprintf_func (info->stream, "%s", parallel);
   1490       info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
   1491                           func_unit);
   1492       for (op_num = 0; op_num < num_operands; op_num++)
   1493 	{
   1494 	  info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
   1495 	  if (operands_pcrel[op_num])
   1496 	    info->print_address_func (operands_addresses[op_num], info);
   1497 	  else
   1498 	    info->fprintf_func (info->stream, "%s", operands[op_num]);
   1499 	}
   1500       if (fetch_packet_header_based && header.prot)
   1501 	info->fprintf_func (info->stream, " || nop 5");
   1502 
   1503       return num_bits / 8;
   1504     }
   1505 
   1506   info->bytes_per_chunk = num_bits / 8;
   1507   info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
   1508 		      (int) num_bits / 4, opcode);
   1509   return num_bits / 8;
   1510 }
   1511