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