1/* TI C6X disassembler.
2   Copyright (C) 2010-2017 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 "dis-asm.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) | (p[3] << 24);
167  else
168    return (p[3]) | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
169}
170
171/* Extract a 16-bit value read from the instruction stream.  */
172
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[7];
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 && prev_header.word_compact[6])
514		p_bit = prev_header.p_bits[13];
515	      else
516		{
517		  unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
518							       info);
519		  p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
520		}
521	    }
522	}
523      parallel = p_bit ? "|| " : "";
524
525      if (opc->func_unit == tic6x_func_unit_nfu)
526	func_unit = "";
527      else
528	{
529	  unsigned int fld_num;
530	  char func_unit_char;
531	  const char *data_str;
532	  bfd_boolean have_areg = FALSE;
533	  bfd_boolean have_cross = FALSE;
534
535	  func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
536	  func_unit_cross = 0;
537	  func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
538
539	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
540	    {
541	      const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
542	      const tic6x_insn_field *field;
543	      unsigned int fld_val;
544
545	      field = tic6x_field_from_fmt (fmt, enc->field_id);
546
547	      if (!field)
548		{
549		  printf ("opcode %x: could not retrieve field (field_id:%d)\n",
550			  opcode, fld_num);
551		  abort ();
552		}
553
554	      fld_val = tic6x_field_bits (opcode, field);
555
556	      switch (enc->coding_method)
557		{
558		case tic6x_coding_fu:
559		  /* The side must be specified exactly once.  */
560		  if (func_unit_side)
561		    {
562		      printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
563			      opcode, fld_num);
564		      abort ();
565		    }
566		  func_unit_side = (fld_val ? 2 : 1);
567		  break;
568
569		case tic6x_coding_data_fu:
570		  /* The data side must be specified exactly once.  */
571		  if (func_unit_data_side)
572		    {
573		      printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
574			      opcode, fld_num);
575		      abort ();
576		    }
577		  func_unit_data_side = (fld_val ? 2 : 1);
578		  break;
579
580		case tic6x_coding_xpath:
581		  /* Cross path use must be specified exactly
582		     once.  */
583		  if (have_cross)
584		    {
585		      printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
586			      opcode, fld_num);
587		      abort ();
588		    }
589		  have_cross = TRUE;
590		  func_unit_cross = fld_val;
591		  break;
592
593                case tic6x_coding_rside:
594                  /* If the format has a t field, use it for src/dst register side.  */
595                  have_t = TRUE;
596                  t_val = fld_val;
597                  func_unit_data_side = (t_val ? 2 : 1);
598                  break;
599
600		case tic6x_coding_areg:
601		  have_areg = TRUE;
602		  break;
603
604		default:
605		  /* Don't relate to functional units.  */
606		  break;
607		}
608	    }
609
610	  /* The side of the functional unit used must now have been
611	     determined either from the flags or from an instruction
612	     field.  */
613	  if (func_unit_side != 1 && func_unit_side != 2)
614	    {
615	      printf ("opcode %x: func_unit_side is not encoded!\n", opcode);
616	      abort ();
617	    }
618
619	  /* Cross paths are not applicable when sides are specified
620	     for both address and data paths.  */
621	  if (func_unit_data_side && have_cross)
622	    {
623	      printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n",
624		      opcode);
625	      abort ();
626	    }
627
628	  /* Separate address and data paths are only applicable for
629	     the D unit.  */
630	  if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
631	    {
632	      printf ("opcode %x: separate address and data paths only applicable for D unit!\n",
633		      opcode);
634	      abort ();
635          }
636
637	  /* If an address register is being used but in ADDA rather
638	     than a load or store, it uses a cross path for side-A
639	     instructions, and the cross path use is not specified by
640	     an instruction field.  */
641	  if (have_areg && !func_unit_data_side)
642	    {
643	      if (have_cross)
644		{
645		  printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode);
646		  abort ();
647		}
648	      func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
649	    }
650
651	  switch (opc->func_unit)
652	    {
653	    case tic6x_func_unit_d:
654	      func_unit_char = 'D';
655	      break;
656
657	    case tic6x_func_unit_l:
658	      func_unit_char = 'L';
659	      break;
660
661	    case tic6x_func_unit_m:
662	      func_unit_char = 'M';
663	      break;
664
665	    case tic6x_func_unit_s:
666	      func_unit_char = 'S';
667	      break;
668
669	    default:
670              printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
671	      abort ();
672	    }
673
674	  switch (func_unit_data_side)
675	    {
676	    case 0:
677	      data_str = "";
678	      break;
679
680	    case 1:
681	      data_str = "T1";
682	      break;
683
684	    case 2:
685	      data_str = "T2";
686	      break;
687
688	    default:
689              printf ("opcode %x: illegal data func_unit specifier %d\n",
690		      opcode, func_unit_data_side);
691	      abort ();
692	    }
693
694	  if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
695	      func_unit_cross = 1;
696
697	  snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
698		    func_unit_side, (func_unit_cross ? "X" : ""), data_str);
699	  func_unit = func_unit_buf;
700	}
701
702      /* For each operand there must be one or more fields set based
703	 on that operand, that can together be used to derive the
704	 operand value.  */
705      operands_ok = TRUE;
706      num_operands = opc->num_operands;
707      for (op_num = 0; op_num < num_operands; op_num++)
708	{
709	  unsigned int fld_num;
710	  unsigned int mem_base_reg = 0;
711	  bfd_boolean mem_base_reg_known = FALSE;
712	  bfd_boolean mem_base_reg_known_long = FALSE;
713	  unsigned int mem_offset = 0;
714	  bfd_boolean mem_offset_known = FALSE;
715	  bfd_boolean mem_offset_known_long = FALSE;
716	  unsigned int mem_mode = 0;
717	  bfd_boolean mem_mode_known = FALSE;
718	  unsigned int mem_scaled = 0;
719	  bfd_boolean mem_scaled_known = FALSE;
720	  unsigned int crlo = 0;
721	  bfd_boolean crlo_known = FALSE;
722	  unsigned int crhi = 0;
723	  bfd_boolean crhi_known = FALSE;
724	  bfd_boolean spmask_skip_operand = FALSE;
725	  unsigned int fcyc_bits = 0;
726	  bfd_boolean prev_sploop_found = FALSE;
727
728	  switch (opc->operand_info[op_num].form)
729	    {
730	    case tic6x_operand_b15reg:
731	      /* Fully determined by the functional unit.  */
732	      operands_text[op_num] = TRUE;
733	      snprintf (operands[op_num], 24, "b15");
734	      continue;
735
736	    case tic6x_operand_zreg:
737	      /* Fully determined by the functional unit.  */
738	      operands_text[op_num] = TRUE;
739	      snprintf (operands[op_num], 24, "%c0",
740			(func_unit_side == 2 ? 'b' : 'a'));
741	      continue;
742
743	    case tic6x_operand_retreg:
744	      /* Fully determined by the functional unit.  */
745	      operands_text[op_num] = TRUE;
746	      snprintf (operands[op_num], 24, "%c3",
747			(func_unit_side == 2 ? 'b' : 'a'));
748	      continue;
749
750	    case tic6x_operand_irp:
751	      operands_text[op_num] = TRUE;
752	      snprintf (operands[op_num], 24, "irp");
753	      continue;
754
755	    case tic6x_operand_nrp:
756	      operands_text[op_num] = TRUE;
757	      snprintf (operands[op_num], 24, "nrp");
758	      continue;
759
760	    case tic6x_operand_ilc:
761	      operands_text[op_num] = TRUE;
762	      snprintf (operands[op_num], 24, "ilc");
763	      continue;
764
765	    case tic6x_operand_hw_const_minus_1:
766	      operands_text[op_num] = TRUE;
767	      snprintf (operands[op_num], 24, "-1");
768	      continue;
769
770	    case tic6x_operand_hw_const_0:
771	      operands_text[op_num] = TRUE;
772	      snprintf (operands[op_num], 24, "0");
773	      continue;
774
775	    case tic6x_operand_hw_const_1:
776	      operands_text[op_num] = TRUE;
777	      snprintf (operands[op_num], 24, "1");
778	      continue;
779
780	    case tic6x_operand_hw_const_5:
781	      operands_text[op_num] = TRUE;
782	      snprintf (operands[op_num], 24, "5");
783	      continue;
784
785	    case tic6x_operand_hw_const_16:
786	      operands_text[op_num] = TRUE;
787	      snprintf (operands[op_num], 24, "16");
788	      continue;
789
790	    case tic6x_operand_hw_const_24:
791	      operands_text[op_num] = TRUE;
792	      snprintf (operands[op_num], 24, "24");
793	      continue;
794
795	    case tic6x_operand_hw_const_31:
796	      operands_text[op_num] = TRUE;
797	      snprintf (operands[op_num], 24, "31");
798	      continue;
799
800	    default:
801	      break;
802	    }
803
804	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
805	    {
806	      const tic6x_coding_field *const enc
807		= &opc->variable_fields[fld_num];
808	      const tic6x_insn_field *field;
809	      unsigned int fld_val;
810	      unsigned int reg_base = 0;
811	      signed int signed_fld_val;
812              char reg_side = '?';
813
814	      if (enc->operand_num != op_num)
815		continue;
816	      field = tic6x_field_from_fmt (fmt, enc->field_id);
817	      if (!field)
818		{
819		  printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
820		  abort ();
821		}
822              fld_val = tic6x_field_bits (opcode, field);
823	      switch (enc->coding_method)
824		{
825                case tic6x_coding_cst_s3i:
826                  (fld_val == 0x00) && (fld_val = 0x10);
827                  (fld_val == 0x07) && (fld_val = 0x08);
828                  /* Fall through.  */
829		case tic6x_coding_ucst:
830		case tic6x_coding_ulcst_dpr_byte:
831		case tic6x_coding_ulcst_dpr_half:
832		case tic6x_coding_ulcst_dpr_word:
833		case tic6x_coding_lcst_low16:
834		  switch (opc->operand_info[op_num].form)
835		    {
836		    case tic6x_operand_asm_const:
837		    case tic6x_operand_link_const:
838		      operands_text[op_num] = TRUE;
839		      snprintf (operands[op_num], 24, "%u", fld_val);
840		      break;
841
842		    case tic6x_operand_mem_long:
843		      mem_offset = fld_val;
844		      mem_offset_known_long = TRUE;
845		      break;
846
847		    default:
848                      printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
849		      abort ();
850		    }
851		  break;
852
853		case tic6x_coding_lcst_high16:
854		  operands_text[op_num] = TRUE;
855		  snprintf (operands[op_num], 24, "%u", fld_val << 16);
856		  break;
857
858                case tic6x_coding_scst_l3i:
859		  operands_text[op_num] = TRUE;
860                  if (fld_val == 0)
861		    {
862		      signed_fld_val = 8;
863		    }
864		  else
865		    {
866		      signed_fld_val = (signed int) fld_val;
867		      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
868		      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
869		    }
870		  snprintf (operands[op_num], 24, "%d", signed_fld_val);
871		  break;
872
873		case tic6x_coding_scst:
874		  operands_text[op_num] = TRUE;
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		  snprintf (operands[op_num], 24, "%d", signed_fld_val);
879		  break;
880
881		case tic6x_coding_ucst_minus_one:
882		  operands_text[op_num] = TRUE;
883		  snprintf (operands[op_num], 24, "%u", fld_val + 1);
884		  break;
885
886		case tic6x_coding_pcrel:
887		case tic6x_coding_pcrel_half:
888		  signed_fld_val = (signed int) fld_val;
889		  signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
890		  signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
891		  if (fetch_packet_header_based
892		      && enc->coding_method == tic6x_coding_pcrel_half)
893		    signed_fld_val *= 2;
894		  else
895		    signed_fld_val *= 4;
896		  operands_pcrel[op_num] = TRUE;
897		  operands_addresses[op_num] = fp_addr + signed_fld_val;
898		  break;
899
900		case tic6x_coding_regpair_msb:
901		  if (opc->operand_info[op_num].form != tic6x_operand_regpair)
902		    abort ();
903		  operands_text[op_num] = TRUE;
904		  snprintf (operands[op_num], 24, "%c%u:%c%u",
905			    (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
906			    (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
907		  break;
908
909		case tic6x_coding_pcrel_half_unsigned:
910		  operands_pcrel[op_num] = TRUE;
911		  operands_addresses[op_num] = fp_addr + 2 * fld_val;
912		  break;
913
914		case tic6x_coding_reg_shift:
915		  fld_val <<= 1;
916		  /* Fall through.  */
917		case tic6x_coding_reg:
918                  if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
919                    {
920		      reg_base = 16;
921                    }
922		  switch (opc->operand_info[op_num].form)
923		    {
924		    case tic6x_operand_treg:
925                      if (!have_t)
926			{
927			  printf ("opcode %x: operand treg but missing t field\n", opcode);
928			  abort ();
929			}
930		      operands_text[op_num] = TRUE;
931                      reg_side = t_val ? 'b' : 'a';
932		      snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
933		      break;
934
935		    case tic6x_operand_reg:
936		      operands_text[op_num] = TRUE;
937                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
938		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
939		      break;
940
941		    case tic6x_operand_reg_nors:
942		      operands_text[op_num] = TRUE;
943                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
944		      snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
945		      break;
946
947		    case tic6x_operand_reg_bside:
948		      operands_text[op_num] = TRUE;
949		      snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
950		      break;
951
952		    case tic6x_operand_reg_bside_nors:
953		      operands_text[op_num] = TRUE;
954		      snprintf (operands[op_num], 24, "b%u", fld_val);
955		      break;
956
957		    case tic6x_operand_xreg:
958		      operands_text[op_num] = TRUE;
959                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
960		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
961		      break;
962
963		    case tic6x_operand_dreg:
964		      operands_text[op_num] = TRUE;
965                      reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
966		      snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
967		      break;
968
969		    case tic6x_operand_regpair:
970		      operands_text[op_num] = TRUE;
971		      if (fld_val & 1)
972			operands_ok = FALSE;
973                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
974		      snprintf (operands[op_num], 24, "%c%u:%c%u",
975                                reg_side, reg_base + fld_val + 1,
976				reg_side, reg_base + fld_val);
977		      break;
978
979		    case tic6x_operand_xregpair:
980		      operands_text[op_num] = TRUE;
981		      if (fld_val & 1)
982			operands_ok = FALSE;
983                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? '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_tregpair:
990                      if (!have_t)
991			{
992			  printf ("opcode %x: operand tregpair but missing t field\n", opcode);
993			  abort ();
994			}
995		      operands_text[op_num] = TRUE;
996		      if (fld_val & 1)
997			operands_ok = FALSE;
998                      reg_side = t_val ? 'b' : 'a';
999		      snprintf (operands[op_num], 24, "%c%u:%c%u",
1000				reg_side, reg_base + fld_val + 1,
1001				reg_side, reg_base + fld_val);
1002		      break;
1003
1004		    case tic6x_operand_dregpair:
1005		      operands_text[op_num] = TRUE;
1006		      if (fld_val & 1)
1007			operands_ok = FALSE;
1008                      reg_side = (func_unit_data_side) == 2 ? '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_mem_deref:
1015		      operands_text[op_num] = TRUE;
1016                      reg_side = func_unit_side == 2 ? 'b' : 'a';
1017		      snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1018		      break;
1019
1020		    case tic6x_operand_mem_short:
1021		    case tic6x_operand_mem_ndw:
1022		      mem_base_reg = fld_val;
1023		      mem_base_reg_known = TRUE;
1024		      break;
1025
1026		    default:
1027                      printf ("opcode %x: unexpected operand form %d for operand #%d",
1028			      opcode, opc->operand_info[op_num].form, op_num);
1029		      abort ();
1030		    }
1031		  break;
1032
1033                case tic6x_coding_reg_ptr:
1034		  switch (opc->operand_info[op_num].form)
1035		    {
1036		    case tic6x_operand_mem_short:
1037		    case tic6x_operand_mem_ndw:
1038                      if (fld_val > 0x3u)
1039			{
1040			  printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
1041				 opcode, op_num, fld_val);
1042			  abort ();
1043			}
1044		      mem_base_reg = 0x4 | fld_val;
1045		      mem_base_reg_known = TRUE;
1046		      break;
1047
1048		    default:
1049                      printf ("opcode %x: unexpected operand form %d for operand #%d",
1050			      opcode, opc->operand_info[op_num].form, op_num);
1051		      abort ();
1052		    }
1053		  break;
1054
1055		case tic6x_coding_areg:
1056		  switch (opc->operand_info[op_num].form)
1057		    {
1058		    case tic6x_operand_areg:
1059		      operands_text[op_num] = TRUE;
1060		      snprintf (operands[op_num], 24, "b%u",
1061				fld_val ? 15u : 14u);
1062		      break;
1063
1064		    case tic6x_operand_mem_long:
1065		      mem_base_reg = fld_val ? 15u : 14u;
1066		      mem_base_reg_known_long = TRUE;
1067		      break;
1068
1069		    default:
1070                      printf ("opcode %x: bad operand form\n", opcode);
1071		      abort ();
1072		    }
1073		  break;
1074
1075		case tic6x_coding_mem_offset_minus_one_noscale:
1076		case tic6x_coding_mem_offset_minus_one:
1077		  fld_val += 1;
1078		  /* Fall through.  */
1079		case tic6x_coding_mem_offset_noscale:
1080		case tic6x_coding_mem_offset:
1081		  mem_offset = fld_val;
1082		  mem_offset_known = TRUE;
1083		  if (num_bits == 16)
1084		    {
1085		      mem_mode_known = TRUE;
1086		      mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1087		      mem_scaled_known = TRUE;
1088		      mem_scaled = TRUE;
1089		      if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1090			{
1091			  mem_base_reg_known = TRUE;
1092			  mem_base_reg = 15;
1093			}
1094		      if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1095			   || enc->coding_method == tic6x_coding_mem_offset_noscale )
1096			mem_scaled = FALSE;
1097		    }
1098		  break;
1099
1100		case tic6x_coding_mem_mode:
1101		  mem_mode = fld_val;
1102		  mem_mode_known = TRUE;
1103		  break;
1104
1105		case tic6x_coding_scaled:
1106		  mem_scaled = fld_val;
1107		  mem_scaled_known = TRUE;
1108		  break;
1109
1110		case tic6x_coding_crlo:
1111		  crlo = fld_val;
1112		  crlo_known = TRUE;
1113		  break;
1114
1115		case tic6x_coding_crhi:
1116		  crhi = fld_val;
1117		  crhi_known = TRUE;
1118		  break;
1119
1120		case tic6x_coding_fstg:
1121		case tic6x_coding_fcyc:
1122		  if (!prev_sploop_found)
1123		    {
1124		      bfd_vma search_fp_addr = fp_addr;
1125		      bfd_vma search_fp_offset = fp_offset;
1126		      bfd_boolean search_fp_header_based
1127			= fetch_packet_header_based;
1128		      tic6x_fetch_packet_header search_fp_header = header;
1129		      unsigned char search_fp[32];
1130		      unsigned int search_num_bits;
1131		      unsigned int search_opcode;
1132		      unsigned int sploop_ii = 0;
1133		      int i;
1134
1135		      memcpy (search_fp, fp, 32);
1136
1137		      /* To interpret these bits in an SPKERNEL
1138			 instruction, we must find the previous
1139			 SPLOOP-family instruction.  It may come up to
1140			 48 execute packets earlier.  */
1141		      for (i = 0; i < 48 * 8; i++)
1142			{
1143			  /* Find the previous instruction.  */
1144			  if (search_fp_offset & 2)
1145			    search_fp_offset -= 2;
1146			  else if (search_fp_offset >= 4)
1147			    {
1148			      if (search_fp_header_based
1149				  && (search_fp_header.word_compact
1150				      [(search_fp_offset >> 2) - 1]))
1151				search_fp_offset -= 2;
1152			      else
1153				search_fp_offset -= 4;
1154			    }
1155			  else
1156			    {
1157			      search_fp_addr -= 32;
1158			      status = info->read_memory_func (search_fp_addr,
1159							       search_fp,
1160							       32, info);
1161			      if (status)
1162				/* No previous SPLOOP instruction.  */
1163				break;
1164			      search_fp_header_based
1165				= (tic6x_check_fetch_packet_header
1166				   (search_fp, &search_fp_header, info));
1167			      if (search_fp_header_based)
1168				search_fp_offset
1169				  = search_fp_header.word_compact[6] ? 26 : 24;
1170			      else
1171				search_fp_offset = 28;
1172			    }
1173
1174			  /* Extract the previous instruction.  */
1175			  if (search_fp_header_based)
1176			    search_num_bits
1177			      = (search_fp_header.word_compact[search_fp_offset
1178							       >> 2]
1179				 ? 16
1180				 : 32);
1181			  else
1182			    search_num_bits = 32;
1183			  if (search_num_bits == 16)
1184			    {
1185			      if (info->endian == BFD_ENDIAN_LITTLE)
1186				search_opcode
1187				  = (tic6x_extract_16
1188				     (search_fp + search_fp_offset, &header, info));
1189			      else
1190				search_opcode
1191				  = (tic6x_extract_16
1192				     (search_fp + (search_fp_offset ^ 2), &header,
1193				      info));
1194			    }
1195			  else
1196			    search_opcode
1197			      = tic6x_extract_32 (search_fp + search_fp_offset,
1198						  info);
1199
1200			  /* Check whether it is an SPLOOP-family
1201			     instruction.  */
1202			  if (search_num_bits == 32
1203			      && ((search_opcode & 0x003ffffe) == 0x00038000
1204				  || (search_opcode & 0x003ffffe) == 0x0003a000
1205				  || ((search_opcode & 0x003ffffe)
1206				      == 0x0003e000)))
1207			    {
1208			      prev_sploop_found = TRUE;
1209			      sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1210			    }
1211			  else if (search_num_bits == 16
1212				   && (search_opcode & 0x3c7e) == 0x0c66)
1213			    {
1214			      prev_sploop_found = TRUE;
1215			      sploop_ii
1216				= (((search_opcode >> 7) & 0x7)
1217				   | ((search_opcode >> 11) & 0x8)) + 1;
1218			    }
1219			  if (prev_sploop_found)
1220			    {
1221			      if (sploop_ii <= 0)
1222				{
1223				  printf ("opcode %x:  sloop index not found (%d)\n", opcode, sploop_ii);
1224				  abort ();
1225				}
1226			      else if (sploop_ii <= 1)
1227				fcyc_bits = 0;
1228			      else if (sploop_ii <= 2)
1229				fcyc_bits = 1;
1230			      else if (sploop_ii <= 4)
1231				fcyc_bits = 2;
1232			      else if (sploop_ii <= 8)
1233				fcyc_bits = 3;
1234			      else if (sploop_ii <= 14)
1235				fcyc_bits = 4;
1236			      else
1237				prev_sploop_found = FALSE;
1238			    }
1239			  if (prev_sploop_found)
1240			    break;
1241			}
1242		    }
1243		  if (!prev_sploop_found)
1244		    {
1245		      operands_ok = FALSE;
1246		      operands_text[op_num] = TRUE;
1247		      break;
1248		    }
1249		  if (fcyc_bits > tic6x_field_width(field))
1250		    {
1251		      printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1252		      abort ();
1253		    }
1254		  if (enc->coding_method == tic6x_coding_fstg)
1255		    {
1256		      int i, t;
1257		      for (t = 0, i = fcyc_bits; i < 6; i++)
1258			t = (t << 1) | ((fld_val >> i) & 1);
1259		      operands_text[op_num] = TRUE;
1260		      snprintf (operands[op_num], 24, "%u", t);
1261		    }
1262		  else
1263		    {
1264		      operands_text[op_num] = TRUE;
1265		      snprintf (operands[op_num], 24, "%u",
1266				fld_val & ((1 << fcyc_bits) - 1));
1267		    }
1268		  break;
1269
1270		case tic6x_coding_spmask:
1271		  if (fld_val == 0)
1272		    spmask_skip_operand = TRUE;
1273		  else
1274		    {
1275		      char *p;
1276		      unsigned int i;
1277
1278		      operands_text[op_num] = TRUE;
1279		      p = operands[op_num];
1280		      for (i = 0; i < 8; i++)
1281			if (fld_val & (1 << i))
1282			  {
1283			    *p++ = "LSDM"[i/2];
1284			    *p++ = '1' + (i & 1);
1285			    *p++ = ',';
1286			  }
1287		      p[-1] = 0;
1288		    }
1289		  break;
1290
1291		case tic6x_coding_fu:
1292		case tic6x_coding_data_fu:
1293		case tic6x_coding_xpath:
1294		case tic6x_coding_rside:
1295		  /* Don't relate to operands, so operand number is
1296		     meaningless.  */
1297		  break;
1298
1299		default:
1300                  printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1301		  abort ();
1302		}
1303
1304	      if (mem_base_reg_known_long && mem_offset_known_long)
1305		{
1306		  if (operands_text[op_num] || operands_pcrel[op_num])
1307		    {
1308		      printf ("opcode %x: long access but operands already known ?\n", opcode);
1309		      abort ();
1310		    }
1311		  operands_text[op_num] = TRUE;
1312		  snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1313			    mem_offset * opc->operand_info[op_num].size);
1314		}
1315
1316	      if (mem_base_reg_known && mem_offset_known && mem_mode_known
1317		  && (mem_scaled_known
1318		      || (opc->operand_info[op_num].form
1319			  != tic6x_operand_mem_ndw)))
1320		{
1321		  char side;
1322		  char base[4];
1323		  bfd_boolean offset_is_reg;
1324		  bfd_boolean offset_scaled;
1325		  char offset[4];
1326		  char offsetp[6];
1327
1328		  if (operands_text[op_num] || operands_pcrel[op_num])
1329		    {
1330		      printf ("opcode %x: mem access operands already known ?\n", opcode);
1331		      abort ();
1332		    }
1333
1334		  side = func_unit_side == 2 ? 'b' : 'a';
1335		  snprintf (base, 4, "%c%u", side, mem_base_reg);
1336
1337		  offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
1338		  if (offset_is_reg)
1339		    {
1340
1341		      if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1342			{
1343			  reg_base = 16;
1344			}
1345		      snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1346		      if (opc->operand_info[op_num].form
1347			  == tic6x_operand_mem_ndw)
1348			offset_scaled = mem_scaled ? TRUE : FALSE;
1349		      else
1350			offset_scaled = TRUE;
1351		    }
1352		  else
1353		    {
1354		      if (opc->operand_info[op_num].form
1355			  == tic6x_operand_mem_ndw)
1356			{
1357			  offset_scaled = mem_scaled ? TRUE : FALSE;
1358			  snprintf (offset, 4, "%u", mem_offset);
1359			}
1360		      else
1361			{
1362			  offset_scaled = FALSE;
1363			  snprintf (offset, 4, "%u",
1364				    (mem_offset
1365				     * opc->operand_info[op_num].size));
1366			}
1367		    }
1368
1369		  if (offset_scaled)
1370		    snprintf (offsetp, 6, "[%s]", offset);
1371		  else
1372		    snprintf (offsetp, 6, "(%s)", offset);
1373
1374		  operands_text[op_num] = TRUE;
1375		  switch (mem_mode & ~4u)
1376		    {
1377		    case 0:
1378		      snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1379		      break;
1380
1381		    case 1:
1382		      snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1383		      break;
1384
1385		    case 2:
1386		    case 3:
1387		      operands_ok = FALSE;
1388		      break;
1389
1390		    case 8:
1391		      snprintf (operands[op_num], 24, "*--%s%s", base,
1392				offsetp);
1393		      break;
1394
1395		    case 9:
1396		      snprintf (operands[op_num], 24, "*++%s%s", base,
1397				offsetp);
1398		      break;
1399
1400		    case 10:
1401		      snprintf (operands[op_num], 24, "*%s--%s", base,
1402				offsetp);
1403		      break;
1404
1405		    case 11:
1406		      snprintf (operands[op_num], 24, "*%s++%s", base,
1407				offsetp);
1408		      break;
1409
1410		    default:
1411                      printf ("*** unknown mem_mode : %d \n", mem_mode);
1412		      abort ();
1413		    }
1414		}
1415
1416	      if (crlo_known && crhi_known)
1417		{
1418		  tic6x_rw rw;
1419		  tic6x_ctrl_id crid;
1420
1421		  if (operands_text[op_num] || operands_pcrel[op_num])
1422		    {
1423		      printf ("*** abort crlo crli\n");
1424		      abort ();
1425		    }
1426
1427		  rw = opc->operand_info[op_num].rw;
1428		  if (rw != tic6x_rw_read
1429		      && rw != tic6x_rw_write)
1430		    {
1431		      printf ("*** abort rw : %d\n", rw);
1432		      abort ();
1433		    }
1434
1435		  for (crid = 0; crid < tic6x_ctrl_max; crid++)
1436		    {
1437		      if (crlo == tic6x_ctrl_table[crid].crlo
1438			  && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1439			  && (rw == tic6x_rw_read
1440			      ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1441				 || (tic6x_ctrl_table[crid].rw
1442				     == tic6x_rw_read_write))
1443			      : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1444				 || (tic6x_ctrl_table[crid].rw
1445				     == tic6x_rw_read_write))))
1446			break;
1447		    }
1448		  if (crid == tic6x_ctrl_max)
1449		    {
1450		      operands_text[op_num] = TRUE;
1451		      operands_ok = FALSE;
1452		    }
1453		  else
1454		    {
1455		      operands_text[op_num] = TRUE;
1456		      snprintf (operands[op_num], 24, "%s",
1457				tic6x_ctrl_table[crid].name);
1458		    }
1459		}
1460
1461	      if (operands_text[op_num] || operands_pcrel[op_num]
1462		  || spmask_skip_operand)
1463		break;
1464	    }
1465          /* end for fld_num */
1466
1467	  if (spmask_skip_operand)
1468	    {
1469	      /* SPMASK operands are only valid as the single operand
1470		 in the opcode table.  */
1471	      if (num_operands != 1)
1472		{
1473		  printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
1474		  abort ();
1475		}
1476	      num_operands = 0;
1477	      break;
1478	    }
1479
1480	  /* The operand must by now have been decoded.  */
1481	  if (!operands_text[op_num] && !operands_pcrel[op_num])
1482            {
1483              printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
1484              abort ();
1485            }
1486        }
1487      /* end for op_num */
1488
1489      if (!operands_ok)
1490	continue;
1491
1492      info->bytes_per_chunk = num_bits / 8;
1493      info->fprintf_func (info->stream, "%s", parallel);
1494      info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1495                          func_unit);
1496      for (op_num = 0; op_num < num_operands; op_num++)
1497	{
1498	  info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1499	  if (operands_pcrel[op_num])
1500	    info->print_address_func (operands_addresses[op_num], info);
1501	  else
1502	    info->fprintf_func (info->stream, "%s", operands[op_num]);
1503	}
1504      if (fetch_packet_header_based && header.prot)
1505	info->fprintf_func (info->stream, " || nop 5");
1506
1507      return num_bits / 8;
1508    }
1509
1510  info->bytes_per_chunk = num_bits / 8;
1511  info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1512		      (int) num_bits / 4, opcode);
1513  return num_bits / 8;
1514}
1515