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