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