1/* TI C6X disassembler.
2   Copyright 2010
3   Free Software Foundation, Inc.
4   Contributed by Joseph Myers <joseph@codesourcery.com>
5   		  Bernd Schmidt  <bernds@codesourcery.com>
6
7   This file is part of libopcodes.
8
9   This library is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   It is distributed in the hope that it will be useful, but WITHOUT
15   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17   License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22   MA 02110-1301, USA.  */
23
24#include "sysdep.h"
25#include "dis-asm.h"
26#include "opcode/tic6x.h"
27#include "libiberty.h"
28
29/* Define the instruction format table.  */
30const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max] =
31  {
32#define FMT(name, num_bits, cst_bits, mask, fields) \
33    { num_bits, cst_bits, mask, fields },
34#include "opcode/tic6x-insn-formats.h"
35#undef FMT
36  };
37
38/* Define the control register table.  */
39const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max] =
40  {
41#define CTRL(name, isa, rw, crlo, crhi_mask)	\
42    {						\
43      STRINGX(name),				\
44      CONCAT2(TIC6X_INSN_,isa),			\
45      CONCAT2(tic6x_rw_,rw),			\
46      crlo,					\
47      crhi_mask					\
48    },
49#include "opcode/tic6x-control-registers.h"
50#undef CTRL
51  };
52
53/* Define the opcode table.  */
54const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max] =
55  {
56#define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
57    {									\
58      STRINGX(name),							\
59      CONCAT2(tic6x_func_unit_,func_unit),				\
60      CONCAT4(tic6x_insn_format_,func_unit,_,format),			\
61      CONCAT2(tic6x_pipeline_,type),					\
62      CONCAT2(TIC6X_INSN_,isa),						\
63      flags,								\
64      fixed,								\
65      ops,								\
66      var								\
67    },
68#define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
69    {									\
70      STRINGX(name),							\
71      CONCAT2(tic6x_func_unit_,func_unit),				\
72      CONCAT4(tic6x_insn_format_,func_unit,_,format),			\
73      CONCAT2(tic6x_pipeline_,type),					\
74      CONCAT2(TIC6X_INSN_,isa),						\
75      flags,								\
76      fixed,								\
77      ops,								\
78      var								\
79    },
80#include "opcode/tic6x-opcode-table.h"
81#undef INSN
82#undef INSNE
83  };
84
85/* If instruction format FMT has a field FIELD, return a pointer to
86   the description of that field; otherwise return NULL.  */
87
88const tic6x_insn_field *
89tic6x_field_from_fmt (const tic6x_insn_format *fmt, tic6x_insn_field_id field)
90{
91  unsigned int f;
92
93  for (f = 0; f < fmt->num_fields; f++)
94    if (fmt->fields[f].field_id == field)
95      return &fmt->fields[f];
96
97  return NULL;
98}
99
100/* Extract the bits corresponding to FIELD from OPCODE.  */
101
102static unsigned int
103tic6x_field_bits (unsigned int opcode, const tic6x_insn_field *field)
104{
105  return (opcode >> field->low_pos) & ((1u << field->width) - 1);
106}
107
108/* Extract a 32-bit value read from the instruction stream.  */
109
110static unsigned int
111tic6x_extract_32 (unsigned char *p, struct disassemble_info *info)
112{
113  if (info->endian == BFD_ENDIAN_LITTLE)
114    return (p[0]) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
115  else
116    return (p[3]) | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
117}
118
119/* Extract a 16-bit value read from the instruction stream.  */
120
121static unsigned int
122tic6x_extract_16 (unsigned char *p, struct disassemble_info *info)
123{
124  if (info->endian == BFD_ENDIAN_LITTLE)
125    return (p[0]) | (p[1] << 8);
126  else
127    return (p[1]) | (p[0] << 8);
128}
129
130/* FP points to a fetch packet.  Return whether it is header-based; if
131   it is, fill in HEADER.  */
132
133static bfd_boolean
134tic6x_check_fetch_packet_header (unsigned char *fp,
135				 tic6x_fetch_packet_header *header,
136				 struct disassemble_info *info)
137{
138  int i;
139
140  header->header = tic6x_extract_32 (fp + 28, info);
141  if ((header->header & 0xf0000000) != 0xe0000000)
142    return FALSE;
143
144  for (i = 0; i < 7; i++)
145    header->word_compact[i]
146      = (header->header & (1u << (21 + i))) ? TRUE : FALSE;
147
148  header->prot = (header->header & (1u << 20)) ? TRUE : FALSE;
149  header->rs = (header->header & (1u << 19)) ? TRUE : FALSE;
150  header->dsz = (header->header >> 16) & 0x7;
151  header->br = (header->header & (1u << 15)) ? TRUE : FALSE;
152  header->sat = (header->header & (1u << 14)) ? TRUE : FALSE;
153
154  for (i = 0; i < 14; i++)
155    header->p_bits[i]
156      = (header->header & (1u << i)) ? TRUE : FALSE;
157
158  return TRUE;
159}
160
161/* Disassemble the instruction at ADDR and print it using
162   INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes
163   consumed.  */
164
165int
166print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
167{
168  int status;
169  bfd_vma fp_addr;
170  bfd_vma fp_offset;
171  unsigned char fp[32];
172  unsigned int opcode;
173  tic6x_opcode_id opcode_id;
174  bfd_boolean fetch_packet_header_based;
175  tic6x_fetch_packet_header header;
176  unsigned int num_bits;
177  bfd_boolean bad_offset = FALSE;
178
179  fp_offset = addr & 0x1f;
180  fp_addr = addr - fp_offset;
181  status = info->read_memory_func (fp_addr, fp, 32, info);
182  if (status)
183    {
184      info->memory_error_func (status, addr, info);
185      return -1;
186    }
187
188  fetch_packet_header_based
189    = tic6x_check_fetch_packet_header (fp, &header, info);
190  if (fetch_packet_header_based)
191    {
192      if (fp_offset & 0x1)
193	bad_offset = TRUE;
194      if ((fp_offset & 0x3) && (fp_offset >= 28
195				|| !header.word_compact[fp_offset >> 2]))
196	bad_offset = TRUE;
197      if (fp_offset == 28)
198	{
199	  info->bytes_per_chunk = 4;
200	  info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
201			      header.header);
202	  return 4;
203	}
204      num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
205    }
206  else
207    {
208      num_bits = 32;
209      if (fp_offset & 0x3)
210	bad_offset = TRUE;
211    }
212
213  if (bad_offset)
214    {
215      info->bytes_per_chunk = 1;
216      info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
217      return 1;
218    }
219
220  if (num_bits == 16)
221    {
222      /* The least-significant part of a 32-bit word comes logically
223	 before the most-significant part.  For big-endian, follow the
224	 TI assembler in showing instructions in logical order by
225	 pretending that the two halves of the word are in opposite
226	 locations to where they actually are.  */
227      if (info->endian == BFD_ENDIAN_LITTLE)
228	opcode = tic6x_extract_16 (fp + fp_offset, info);
229      else
230	opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), info);
231    }
232  else
233    opcode = tic6x_extract_32 (fp + fp_offset, info);
234
235  for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
236    {
237      const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
238      const tic6x_insn_format *const fmt
239	= &tic6x_insn_format_table[opc->format];
240      const tic6x_insn_field *creg_field;
241      bfd_boolean p_bit;
242      const char *parallel;
243      const char *cond = "";
244      const char *func_unit;
245      char func_unit_buf[7];
246      unsigned int func_unit_side = 0;
247      unsigned int func_unit_data_side = 0;
248      unsigned int func_unit_cross = 0;
249      /* The maximum length of the text of a non-PC-relative operand
250	 is 24 bytes (SPMASK masking all eight functional units, with
251	 separating commas and trailing NUL).  */
252      char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
253      bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
254      bfd_boolean operands_text[TIC6X_MAX_OPERANDS] = { FALSE };
255      bfd_boolean operands_pcrel[TIC6X_MAX_OPERANDS] = { FALSE };
256      unsigned int fix;
257      unsigned int num_operands;
258      unsigned int op_num;
259      bfd_boolean fixed_ok;
260      bfd_boolean operands_ok;
261
262      if (opc->flags & TIC6X_FLAG_MACRO)
263	continue;
264      if (fmt->num_bits != num_bits)
265	continue;
266      if ((opcode & fmt->mask) != fmt->cst_bits)
267	continue;
268
269      /* If the format has a creg field, it is only a candidate for a
270	 match if the creg and z fields have values indicating a valid
271	 condition; reserved values indicate either an instruction
272	 format without a creg field, or an invalid instruction.  */
273      creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
274      if (creg_field)
275	{
276	  const tic6x_insn_field *z_field;
277	  unsigned int creg_value, z_value;
278	  static const char *const conds[8][2] =
279	    {
280	      { "", NULL },
281	      { "[b0] ", "[!b0] " },
282	      { "[b1] ", "[!b1] " },
283	      { "[b2] ", "[!b2] " },
284	      { "[a1] ", "[!a1] " },
285	      { "[a2] ", "[!a2] " },
286	      { "[a0] ", "[!a0] " },
287	      { NULL, NULL }
288	    };
289
290	  /* A creg field is not meaningful without a z field, so if
291	     the z field is not present this is an error in the format
292	     table.  */
293	  z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
294	  if (!z_field)
295	    abort ();
296
297	  creg_value = tic6x_field_bits (opcode, creg_field);
298	  z_value = tic6x_field_bits (opcode, z_field);
299	  cond = conds[creg_value][z_value];
300	  if (cond == NULL)
301	    continue;
302	}
303
304      /* All fixed fields must have matching values; all fields with
305	 restricted ranges must have values within those ranges.  */
306      fixed_ok = TRUE;
307      for (fix = 0; fix < opc->num_fixed_fields; fix++)
308	{
309	  unsigned int field_bits;
310	  const tic6x_insn_field *const field
311	    = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
312
313	  if (!field)
314	    abort ();
315	  field_bits = tic6x_field_bits (opcode, field);
316	  if (field_bits < opc->fixed_fields[fix].min_val
317	      || field_bits > opc->fixed_fields[fix].max_val)
318	    {
319	      fixed_ok = FALSE;
320	      break;
321	    }
322	}
323      if (!fixed_ok)
324	continue;
325
326      /* The instruction matches.  */
327
328      /* The p-bit indicates whether this instruction is in parallel
329	 with the *next* instruction, whereas the parallel bars
330	 indicate the instruction is in parallel with the *previous*
331	 instruction.  Thus, we must find the p-bit for the previous
332	 instruction.  */
333      if (num_bits == 16 && (fp_offset & 0x2) == 2)
334	{
335	  /* This is the logically second (most significant; second in
336	     fp_offset terms because fp_offset relates to logical not
337	     physical addresses) instruction of a compact pair; find
338	     the p-bit for the first (least significant).  */
339	  p_bit = header.p_bits[(fp_offset >> 2) << 1];
340	}
341      else if (fp_offset >= 4)
342	{
343	  /* Find the last instruction of the previous word in this
344	     fetch packet.  For compact instructions, this is the most
345	     significant 16 bits.  */
346	  if (fetch_packet_header_based
347	      && header.word_compact[(fp_offset >> 2) - 1])
348	    p_bit = header.p_bits[(fp_offset >> 1) - 1];
349	  else
350	    {
351	      unsigned int prev_opcode
352		= tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
353	      p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
354	    }
355	}
356      else
357	{
358	  /* Find the last instruction of the previous fetch
359	     packet.  */
360	  unsigned char fp_prev[32];
361	  status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
362	  if (status)
363	    /* No previous instruction to be parallel with.  */
364	    p_bit = FALSE;
365	  else
366	    {
367	      bfd_boolean prev_header_based;
368	      tic6x_fetch_packet_header prev_header;
369
370	      prev_header_based
371		= tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
372	      if (prev_header_based && prev_header.word_compact[6])
373		p_bit = prev_header.p_bits[13];
374	      else
375		{
376		  unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
377							       info);
378		  p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
379		}
380	    }
381	}
382      parallel = p_bit ? "|| " : "";
383
384      if (opc->func_unit == tic6x_func_unit_nfu)
385	func_unit = "";
386      else
387	{
388	  unsigned int fld_num;
389	  char func_unit_char;
390	  const char *data_str;
391	  bfd_boolean have_areg = FALSE;
392	  bfd_boolean have_cross = FALSE;
393
394	  func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
395	  func_unit_cross = 0;
396	  func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
397
398	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
399	    {
400	      const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
401	      const tic6x_insn_field *field;
402	      unsigned int fld_val;
403
404	      field = tic6x_field_from_fmt (fmt, enc->field_id);
405	      if (!field)
406		abort ();
407	      fld_val = tic6x_field_bits (opcode, field);
408	      switch (enc->coding_method)
409		{
410		case tic6x_coding_fu:
411		  /* The side must be specified exactly once.  */
412		  if (func_unit_side)
413		    abort ();
414		  func_unit_side = (fld_val ? 2 : 1);
415		  break;
416
417		case tic6x_coding_data_fu:
418		  /* The data side must be specified exactly once.  */
419		  if (func_unit_data_side)
420		    abort ();
421		  func_unit_data_side = (fld_val ? 2 : 1);
422		  break;
423
424		case tic6x_coding_xpath:
425		  /* Cross path use must be specified exactly
426		     once.  */
427		  if (have_cross)
428		    abort ();
429		  have_cross = TRUE;
430		  func_unit_cross = fld_val;
431		  break;
432
433		case tic6x_coding_areg:
434		  have_areg = TRUE;
435		  break;
436
437		default:
438		  /* Don't relate to functional units.  */
439		  break;
440		}
441	    }
442
443	  /* The side of the functional unit used must now have been
444	     determined either from the flags or from an instruction
445	     field.  */
446	  if (func_unit_side != 1 && func_unit_side != 2)
447	    abort ();
448
449	  /* Cross paths are not applicable when sides are specified
450	     for both address and data paths.  */
451	  if (func_unit_data_side && have_cross)
452	    abort ();
453
454	  /* Separate address and data paths are only applicable for
455	     the D unit.  */
456	  if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
457	    abort ();
458
459	  /* If an address register is being used but in ADDA rather
460	     than a load or store, it uses a cross path for side-A
461	     instructions, and the cross path use is not specified by
462	     an instruction field.  */
463	  if (have_areg && !func_unit_data_side)
464	    {
465	      if (have_cross)
466		abort ();
467	      func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
468	    }
469
470	  switch (opc->func_unit)
471	    {
472	    case tic6x_func_unit_d:
473	      func_unit_char = 'D';
474	      break;
475
476	    case tic6x_func_unit_l:
477	      func_unit_char = 'L';
478	      break;
479
480	    case tic6x_func_unit_m:
481	      func_unit_char = 'M';
482	      break;
483
484	    case tic6x_func_unit_s:
485	      func_unit_char = 'S';
486	      break;
487
488	    default:
489	      abort ();
490	    }
491
492	  switch (func_unit_data_side)
493	    {
494	    case 0:
495	      data_str = "";
496	      break;
497
498	    case 1:
499	      data_str = "T1";
500	      break;
501
502	    case 2:
503	      data_str = "T2";
504	      break;
505
506	    default:
507	      abort ();
508	    }
509
510	  snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
511		    func_unit_side, (func_unit_cross ? "X" : ""), data_str);
512	  func_unit = func_unit_buf;
513	}
514
515      /* For each operand there must be one or more fields set based
516	 on that operand, that can together be used to derive the
517	 operand value.  */
518      operands_ok = TRUE;
519      num_operands = opc->num_operands;
520      for (op_num = 0; op_num < num_operands; op_num++)
521	{
522	  unsigned int fld_num;
523	  unsigned int mem_base_reg = 0;
524	  bfd_boolean mem_base_reg_known = FALSE;
525	  bfd_boolean mem_base_reg_known_long = FALSE;
526	  unsigned int mem_offset = 0;
527	  bfd_boolean mem_offset_known = FALSE;
528	  bfd_boolean mem_offset_known_long = FALSE;
529	  unsigned int mem_mode = 0;
530	  bfd_boolean mem_mode_known = FALSE;
531	  unsigned int mem_scaled = 0;
532	  bfd_boolean mem_scaled_known = FALSE;
533	  unsigned int crlo = 0;
534	  bfd_boolean crlo_known = FALSE;
535	  unsigned int crhi = 0;
536	  bfd_boolean crhi_known = FALSE;
537	  bfd_boolean spmask_skip_operand = FALSE;
538	  unsigned int fcyc_bits = 0;
539	  bfd_boolean prev_sploop_found = FALSE;
540
541	  switch (opc->operand_info[op_num].form)
542	    {
543	    case tic6x_operand_retreg:
544	      /* Fully determined by the functional unit.  */
545	      operands_text[op_num] = TRUE;
546	      snprintf (operands[op_num], 24, "%c3",
547			(func_unit_side == 2 ? 'b' : 'a'));
548	      continue;
549
550	    case tic6x_operand_irp:
551	      operands_text[op_num] = TRUE;
552	      snprintf (operands[op_num], 24, "irp");
553	      continue;
554
555	    case tic6x_operand_nrp:
556	      operands_text[op_num] = TRUE;
557	      snprintf (operands[op_num], 24, "nrp");
558	      continue;
559
560	    default:
561	      break;
562	    }
563
564	  for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
565	    {
566	      const tic6x_coding_field *const enc
567		= &opc->variable_fields[fld_num];
568	      const tic6x_insn_field *field;
569	      unsigned int fld_val;
570	      signed int signed_fld_val;
571
572	      if (enc->operand_num != op_num)
573		continue;
574	      field = tic6x_field_from_fmt (fmt, enc->field_id);
575	      if (!field)
576		abort ();
577	      fld_val = tic6x_field_bits (opcode, field);
578	      switch (enc->coding_method)
579		{
580		case tic6x_coding_ucst:
581		case tic6x_coding_ulcst_dpr_byte:
582		case tic6x_coding_ulcst_dpr_half:
583		case tic6x_coding_ulcst_dpr_word:
584		case tic6x_coding_lcst_low16:
585		  switch (opc->operand_info[op_num].form)
586		    {
587		    case tic6x_operand_asm_const:
588		    case tic6x_operand_link_const:
589		      operands_text[op_num] = TRUE;
590		      snprintf (operands[op_num], 24, "%u", fld_val);
591		      break;
592
593		    case tic6x_operand_mem_long:
594		      mem_offset = fld_val;
595		      mem_offset_known_long = TRUE;
596		      break;
597
598		    default:
599		      abort ();
600		    }
601		  break;
602
603		case tic6x_coding_lcst_high16:
604		  operands_text[op_num] = TRUE;
605		  snprintf (operands[op_num], 24, "%u", fld_val << 16);
606		  break;
607
608		case tic6x_coding_scst:
609		  operands_text[op_num] = TRUE;
610		  signed_fld_val = (signed int) fld_val;
611		  signed_fld_val ^= (1 << (field->width - 1));
612		  signed_fld_val -= (1 << (field->width - 1));
613		  snprintf (operands[op_num], 24, "%d", signed_fld_val);
614		  break;
615
616		case tic6x_coding_ucst_minus_one:
617		  operands_text[op_num] = TRUE;
618		  snprintf (operands[op_num], 24, "%u", fld_val + 1);
619		  break;
620
621		case tic6x_coding_pcrel:
622		case tic6x_coding_pcrel_half:
623		  signed_fld_val = (signed int) fld_val;
624		  signed_fld_val ^= (1 << (field->width - 1));
625		  signed_fld_val -= (1 << (field->width - 1));
626		  if (fetch_packet_header_based
627		      && enc->coding_method == tic6x_coding_pcrel_half)
628		    signed_fld_val *= 2;
629		  else
630		    signed_fld_val *= 4;
631		  operands_pcrel[op_num] = TRUE;
632		  operands_addresses[op_num] = fp_addr + signed_fld_val;
633		  break;
634
635		case tic6x_coding_reg_shift:
636		  fld_val <<= 1;
637		  /* Fall through.  */
638		case tic6x_coding_reg:
639		  switch (opc->operand_info[op_num].form)
640		    {
641		    case tic6x_operand_reg:
642		      operands_text[op_num] = TRUE;
643		      snprintf (operands[op_num], 24, "%c%u",
644				(func_unit_side == 2 ? 'b' : 'a'), fld_val);
645		      break;
646
647		    case tic6x_operand_xreg:
648		      operands_text[op_num] = TRUE;
649		      snprintf (operands[op_num], 24, "%c%u",
650				(((func_unit_side == 2) ^ func_unit_cross)
651				 ? 'b'
652				 : 'a'), fld_val);
653		      break;
654
655		    case tic6x_operand_dreg:
656		      operands_text[op_num] = TRUE;
657		      snprintf (operands[op_num], 24, "%c%u",
658				(func_unit_data_side == 2 ? 'b' : 'a'),
659				fld_val);
660		      break;
661
662		    case tic6x_operand_regpair:
663		      operands_text[op_num] = TRUE;
664		      if (fld_val & 1)
665			operands_ok = FALSE;
666		      snprintf (operands[op_num], 24, "%c%u:%c%u",
667				(func_unit_side == 2 ? 'b' : 'a'), fld_val + 1,
668				(func_unit_side == 2 ? 'b' : 'a'), fld_val);
669		      break;
670
671		    case tic6x_operand_xregpair:
672		      operands_text[op_num] = TRUE;
673		      if (fld_val & 1)
674			operands_ok = FALSE;
675		      snprintf (operands[op_num], 24, "%c%u:%c%u",
676				(((func_unit_side == 2) ^ func_unit_cross)
677				 ? 'b'
678				 : 'a'), fld_val + 1,
679				(((func_unit_side == 2) ^ func_unit_cross)
680				 ? 'b'
681				 : 'a'), fld_val);
682		      break;
683
684		    case tic6x_operand_dregpair:
685		      operands_text[op_num] = TRUE;
686		      if (fld_val & 1)
687			operands_ok = FALSE;
688		      snprintf (operands[op_num], 24, "%c%u:%c%u",
689				(func_unit_data_side == 2 ? 'b' : 'a'),
690				fld_val + 1,
691				(func_unit_data_side == 2 ? 'b' : 'a'),
692				fld_val);
693		      break;
694
695		    case tic6x_operand_mem_deref:
696		      operands_text[op_num] = TRUE;
697		      snprintf (operands[op_num], 24, "*%c%u",
698				(func_unit_side == 2 ? 'b' : 'a'), fld_val);
699		      break;
700
701		    case tic6x_operand_mem_short:
702		    case tic6x_operand_mem_ndw:
703		      mem_base_reg = fld_val;
704		      mem_base_reg_known = TRUE;
705		      break;
706
707		    default:
708		      abort ();
709		    }
710		  break;
711
712		case tic6x_coding_areg:
713		  switch (opc->operand_info[op_num].form)
714		    {
715		    case tic6x_operand_areg:
716		      operands_text[op_num] = TRUE;
717		      snprintf (operands[op_num], 24, "b%u",
718				fld_val ? 15u : 14u);
719		      break;
720
721		    case tic6x_operand_mem_long:
722		      mem_base_reg = fld_val ? 15u : 14u;
723		      mem_base_reg_known_long = TRUE;
724		      break;
725
726		    default:
727		      abort ();
728		    }
729		  break;
730
731		case tic6x_coding_mem_offset:
732		case tic6x_coding_mem_offset_noscale:
733		  mem_offset = fld_val;
734		  mem_offset_known = TRUE;
735		  break;
736
737		case tic6x_coding_mem_mode:
738		  mem_mode = fld_val;
739		  mem_mode_known = TRUE;
740		  break;
741
742		case tic6x_coding_scaled:
743		  mem_scaled = fld_val;
744		  mem_scaled_known = TRUE;
745		  break;
746
747		case tic6x_coding_crlo:
748		  crlo = fld_val;
749		  crlo_known = TRUE;
750		  break;
751
752		case tic6x_coding_crhi:
753		  crhi = fld_val;
754		  crhi_known = TRUE;
755		  break;
756
757		case tic6x_coding_fstg:
758		case tic6x_coding_fcyc:
759		  if (!prev_sploop_found)
760		    {
761		      bfd_vma search_fp_addr = fp_addr;
762		      bfd_vma search_fp_offset = fp_offset;
763		      bfd_boolean search_fp_header_based
764			= fetch_packet_header_based;
765		      tic6x_fetch_packet_header search_fp_header = header;
766		      unsigned char search_fp[32];
767		      unsigned int search_num_bits;
768		      unsigned int search_opcode;
769		      unsigned int sploop_ii = 0;
770		      int i;
771
772		      memcpy (search_fp, fp, 32);
773
774		      /* To interpret these bits in an SPKERNEL
775			 instruction, we must find the previous
776			 SPLOOP-family instruction.  It may come up to
777			 48 execute packets earlier.  */
778		      for (i = 0; i < 48 * 8; i++)
779			{
780			  /* Find the previous instruction.  */
781			  if (search_fp_offset & 2)
782			    search_fp_offset -= 2;
783			  else if (search_fp_offset >= 4)
784			    {
785			      if (search_fp_header_based
786				  && (search_fp_header.word_compact
787				      [(search_fp_offset >> 2) - 1]))
788				search_fp_offset -= 2;
789			      else
790				search_fp_offset -= 4;
791			    }
792			  else
793			    {
794			      search_fp_addr -= 32;
795			      status = info->read_memory_func (search_fp_addr,
796							       search_fp,
797							       32, info);
798			      if (status)
799				/* No previous SPLOOP instruction.  */
800				break;
801			      search_fp_header_based
802				= (tic6x_check_fetch_packet_header
803				   (search_fp, &search_fp_header, info));
804			      if (search_fp_header_based)
805				search_fp_offset
806				  = search_fp_header.word_compact[6] ? 26 : 24;
807			      else
808				search_fp_offset = 28;
809			    }
810
811			  /* Extract the previous instruction.  */
812			  if (search_fp_header_based)
813			    search_num_bits
814			      = (search_fp_header.word_compact[search_fp_offset
815							       >> 2]
816				 ? 16
817				 : 32);
818			  else
819			    search_num_bits = 32;
820			  if (search_num_bits == 16)
821			    {
822			      if (info->endian == BFD_ENDIAN_LITTLE)
823				search_opcode
824				  = (tic6x_extract_16
825				     (search_fp + search_fp_offset, info));
826			      else
827				search_opcode
828				  = (tic6x_extract_16
829				     (search_fp + (search_fp_offset ^ 2),
830				      info));
831			    }
832			  else
833			    search_opcode
834			      = tic6x_extract_32 (search_fp + search_fp_offset,
835						  info);
836
837			  /* Check whether it is an SPLOOP-family
838			     instruction.  */
839			  if (search_num_bits == 32
840			      && ((search_opcode & 0x003ffffe) == 0x00038000
841				  || (search_opcode & 0x003ffffe) == 0x0003a000
842				  || ((search_opcode & 0x003ffffe)
843				      == 0x0003e000)))
844			    {
845			      prev_sploop_found = TRUE;
846			      sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
847			    }
848			  else if (search_num_bits == 16
849				   && (search_opcode & 0x3c7e) == 0x0c66)
850			    {
851			      prev_sploop_found = TRUE;
852			      sploop_ii
853				= (((search_opcode >> 7) & 0x7)
854				   | ((search_opcode >> 11) & 0x8)) + 1;
855			    }
856			  if (prev_sploop_found)
857			    {
858			      if (sploop_ii <= 0)
859				abort ();
860			      else if (sploop_ii <= 1)
861				fcyc_bits = 0;
862			      else if (sploop_ii <= 2)
863				fcyc_bits = 1;
864			      else if (sploop_ii <= 4)
865				fcyc_bits = 2;
866			      else if (sploop_ii <= 8)
867				fcyc_bits = 3;
868			      else if (sploop_ii <= 14)
869				fcyc_bits = 4;
870			      else
871				prev_sploop_found = FALSE;
872			    }
873			  if (prev_sploop_found)
874			    break;
875			}
876		    }
877		  if (!prev_sploop_found)
878		    {
879		      operands_ok = FALSE;
880		      operands_text[op_num] = TRUE;
881		      break;
882		    }
883		  if (fcyc_bits > field->width)
884		    abort ();
885		  if (enc->coding_method == tic6x_coding_fstg)
886		    {
887		      int i, t;
888		      for (t = 0, i = fcyc_bits; i < 6; i++)
889			t = (t << 1) | ((fld_val >> i) & 1);
890		      operands_text[op_num] = TRUE;
891		      snprintf (operands[op_num], 24, "%u", t);
892		    }
893		  else
894		    {
895		      operands_text[op_num] = TRUE;
896		      snprintf (operands[op_num], 24, "%u",
897				fld_val & ((1 << fcyc_bits) - 1));
898		    }
899		  break;
900
901		case tic6x_coding_spmask:
902		  if (fld_val == 0)
903		    spmask_skip_operand = TRUE;
904		  else
905		    {
906		      char *p;
907		      unsigned int i;
908
909		      operands_text[op_num] = TRUE;
910		      p = operands[op_num];
911		      for (i = 0; i < 8; i++)
912			if (fld_val & (1 << i))
913			  {
914			    *p++ = "LSDM"[i/2];
915			    *p++ = '1' + (i & 1);
916			    *p++ = ',';
917			  }
918		      p[-1] = 0;
919		    }
920		  break;
921
922		case tic6x_coding_fu:
923		case tic6x_coding_data_fu:
924		case tic6x_coding_xpath:
925		  /* Don't relate to operands, so operand number is
926		     meaningless.  */
927		  break;
928
929		default:
930		  abort ();
931		}
932
933	      if (mem_base_reg_known_long && mem_offset_known_long)
934		{
935		  if (operands_text[op_num] || operands_pcrel[op_num])
936		    abort ();
937		  operands_text[op_num] = TRUE;
938		  snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
939			    mem_offset * opc->operand_info[op_num].size);
940		}
941
942	      if (mem_base_reg_known && mem_offset_known && mem_mode_known
943		  && (mem_scaled_known
944		      || (opc->operand_info[op_num].form
945			  != tic6x_operand_mem_ndw)))
946		{
947		  char side;
948		  char base[4];
949		  bfd_boolean offset_is_reg;
950		  bfd_boolean offset_scaled;
951		  char offset[4];
952		  char offsetp[6];
953
954		  if (operands_text[op_num] || operands_pcrel[op_num])
955		    abort ();
956
957		  side = func_unit_side == 2 ? 'b' : 'a';
958		  snprintf (base, 4, "%c%u", side, mem_base_reg);
959
960		  offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
961		  if (offset_is_reg)
962		    {
963		      snprintf (offset, 4, "%c%u", side, mem_offset);
964		      if (opc->operand_info[op_num].form
965			  == tic6x_operand_mem_ndw)
966			offset_scaled = mem_scaled ? TRUE : FALSE;
967		      else
968			offset_scaled = TRUE;
969		    }
970		  else
971		    {
972		      if (opc->operand_info[op_num].form
973			  == tic6x_operand_mem_ndw)
974			{
975			  offset_scaled = mem_scaled ? TRUE : FALSE;
976			  snprintf (offset, 4, "%u", mem_offset);
977			}
978		      else
979			{
980			  offset_scaled = FALSE;
981			  snprintf (offset, 4, "%u",
982				    (mem_offset
983				     * opc->operand_info[op_num].size));
984			}
985		    }
986
987		  if (offset_scaled)
988		    snprintf (offsetp, 6, "[%s]", offset);
989		  else
990		    snprintf (offsetp, 6, "(%s)", offset);
991
992		  operands_text[op_num] = TRUE;
993		  switch (mem_mode & ~4u)
994		    {
995		    case 0:
996		      snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
997		      break;
998
999		    case 1:
1000		      snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1001		      break;
1002
1003		    case 2:
1004		    case 3:
1005		      operands_ok = FALSE;
1006		      break;
1007
1008		    case 8:
1009		      snprintf (operands[op_num], 24, "*--%s%s", base,
1010				offsetp);
1011		      break;
1012
1013		    case 9:
1014		      snprintf (operands[op_num], 24, "*++%s%s", base,
1015				offsetp);
1016		      break;
1017
1018		    case 10:
1019		      snprintf (operands[op_num], 24, "*%s--%s", base,
1020				offsetp);
1021		      break;
1022
1023		    case 11:
1024		      snprintf (operands[op_num], 24, "*%s++%s", base,
1025				offsetp);
1026		      break;
1027
1028		    default:
1029		      abort ();
1030		    }
1031		}
1032
1033	      if (crlo_known && crhi_known)
1034		{
1035		  tic6x_rw rw;
1036		  tic6x_ctrl_id crid;
1037
1038		  if (operands_text[op_num] || operands_pcrel[op_num])
1039		    abort ();
1040
1041		  rw = opc->operand_info[op_num].rw;
1042		  if (rw != tic6x_rw_read
1043		      && rw != tic6x_rw_write)
1044		    abort ();
1045
1046		  for (crid = 0; crid < tic6x_ctrl_max; crid++)
1047		    {
1048		      if (crlo == tic6x_ctrl_table[crid].crlo
1049			  && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1050			  && (rw == tic6x_rw_read
1051			      ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1052				 || (tic6x_ctrl_table[crid].rw
1053				     == tic6x_rw_read_write))
1054			      : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1055				 || (tic6x_ctrl_table[crid].rw
1056				     == tic6x_rw_read_write))))
1057			break;
1058		    }
1059		  if (crid == tic6x_ctrl_max)
1060		    {
1061		      operands_text[op_num] = TRUE;
1062		      operands_ok = FALSE;
1063		    }
1064		  else
1065		    {
1066		      operands_text[op_num] = TRUE;
1067		      snprintf (operands[op_num], 24, "%s",
1068				tic6x_ctrl_table[crid].name);
1069		    }
1070		}
1071
1072	      if (operands_text[op_num] || operands_pcrel[op_num]
1073		  || spmask_skip_operand)
1074		break;
1075	    }
1076	  if (spmask_skip_operand)
1077	    {
1078	      /* SPMASK operands are only valid as the single operand
1079		 in the opcode table.  */
1080	      if (num_operands != 1)
1081		abort ();
1082	      num_operands = 0;
1083	      break;
1084	    }
1085	  /* The operand must by now have been decoded.  */
1086	  if (!operands_text[op_num] && !operands_pcrel[op_num])
1087	    abort ();
1088	}
1089
1090      if (!operands_ok)
1091	continue;
1092
1093      info->bytes_per_chunk = num_bits / 8;
1094      info->fprintf_func (info->stream, "%s%s%s%s", parallel, cond,
1095			  opc->name, func_unit);
1096      for (op_num = 0; op_num < num_operands; op_num++)
1097	{
1098	  info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1099	  if (operands_pcrel[op_num])
1100	    info->print_address_func (operands_addresses[op_num], info);
1101	  else
1102	    info->fprintf_func (info->stream, "%s", operands[op_num]);
1103	}
1104      if (fetch_packet_header_based && header.prot)
1105	info->fprintf_func (info->stream, " || nop 5");
1106
1107      return num_bits / 8;
1108    }
1109
1110  info->bytes_per_chunk = num_bits / 8;
1111  info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1112		      (int) num_bits / 4, opcode);
1113  return num_bits / 8;
1114}
1115