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