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