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