Update year range in copyright notice of all files.
[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 && prev_header.word_compact[6])
514                 p_bit = prev_header.p_bits[13];
515               else
516                 {
517                   unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
518                                                                info);
519                   p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
520                 }
521             }
522         }
523       parallel = p_bit ? "|| " : "";
524
525       if (opc->func_unit == tic6x_func_unit_nfu)
526         func_unit = "";
527       else
528         {
529           unsigned int fld_num;
530           char func_unit_char;
531           const char *data_str;
532           bfd_boolean have_areg = FALSE;
533           bfd_boolean have_cross = FALSE;
534
535           func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
536           func_unit_cross = 0;
537           func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
538
539           for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
540             {
541               const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
542               const tic6x_insn_field *field;
543               unsigned int fld_val;
544
545               field = tic6x_field_from_fmt (fmt, enc->field_id);
546
547               if (!field)
548                 {
549                   printf ("opcode %x: could not retrieve field (field_id:%d)\n",
550                           opcode, fld_num);
551                   abort ();
552                 }
553
554               fld_val = tic6x_field_bits (opcode, field);
555
556               switch (enc->coding_method)
557                 {
558                 case tic6x_coding_fu:
559                   /* The side must be specified exactly once.  */
560                   if (func_unit_side)
561                     {
562                       printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
563                               opcode, fld_num);
564                       abort ();
565                     }
566                   func_unit_side = (fld_val ? 2 : 1);
567                   break;
568
569                 case tic6x_coding_data_fu:
570                   /* The data side must be specified exactly once.  */
571                   if (func_unit_data_side)
572                     {
573                       printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
574                               opcode, fld_num);
575                       abort ();
576                     }
577                   func_unit_data_side = (fld_val ? 2 : 1);
578                   break;
579
580                 case tic6x_coding_xpath:
581                   /* Cross path use must be specified exactly
582                      once.  */
583                   if (have_cross)
584                     {
585                       printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
586                               opcode, fld_num);
587                       abort ();
588                     }
589                   have_cross = TRUE;
590                   func_unit_cross = fld_val;
591                   break;
592
593                 case tic6x_coding_rside:
594                   /* If the format has a t field, use it for src/dst register side.  */
595                   have_t = TRUE;
596                   t_val = fld_val;
597                   func_unit_data_side = (t_val ? 2 : 1);
598                   break;
599
600                 case tic6x_coding_areg:
601                   have_areg = TRUE;
602                   break;
603
604                 default:
605                   /* Don't relate to functional units.  */
606                   break;
607                 }
608             }
609
610           /* The side of the functional unit used must now have been
611              determined either from the flags or from an instruction
612              field.  */
613           if (func_unit_side != 1 && func_unit_side != 2)
614             {
615               printf ("opcode %x: func_unit_side is not encoded!\n", opcode);
616               abort ();
617             }
618
619           /* Cross paths are not applicable when sides are specified
620              for both address and data paths.  */
621           if (func_unit_data_side && have_cross)
622             {
623               printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n",
624                       opcode);
625               abort ();
626             }
627
628           /* Separate address and data paths are only applicable for
629              the D unit.  */
630           if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
631             {
632               printf ("opcode %x: separate address and data paths only applicable for D unit!\n",
633                       opcode);
634               abort ();
635           }
636
637           /* If an address register is being used but in ADDA rather
638              than a load or store, it uses a cross path for side-A
639              instructions, and the cross path use is not specified by
640              an instruction field.  */
641           if (have_areg && !func_unit_data_side)
642             {
643               if (have_cross)
644                 {
645                   printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode);
646                   abort ();
647                 }
648               func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
649             }
650
651           switch (opc->func_unit)
652             {
653             case tic6x_func_unit_d:
654               func_unit_char = 'D';
655               break;
656
657             case tic6x_func_unit_l:
658               func_unit_char = 'L';
659               break;
660
661             case tic6x_func_unit_m:
662               func_unit_char = 'M';
663               break;
664
665             case tic6x_func_unit_s:
666               func_unit_char = 'S';
667               break;
668
669             default:
670               printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
671               abort ();
672             }
673
674           switch (func_unit_data_side)
675             {
676             case 0:
677               data_str = "";
678               break;
679
680             case 1:
681               data_str = "T1";
682               break;
683
684             case 2:
685               data_str = "T2";
686               break;
687
688             default:
689               printf ("opcode %x: illegal data func_unit specifier %d\n",
690                       opcode, func_unit_data_side);
691               abort ();
692             }
693
694           if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
695               func_unit_cross = 1;
696
697           snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
698                     func_unit_side, (func_unit_cross ? "X" : ""), data_str);
699           func_unit = func_unit_buf;
700         }
701
702       /* For each operand there must be one or more fields set based
703          on that operand, that can together be used to derive the
704          operand value.  */
705       operands_ok = TRUE;
706       num_operands = opc->num_operands;
707       for (op_num = 0; op_num < num_operands; op_num++)
708         {
709           unsigned int fld_num;
710           unsigned int mem_base_reg = 0;
711           bfd_boolean mem_base_reg_known = FALSE;
712           bfd_boolean mem_base_reg_known_long = FALSE;
713           unsigned int mem_offset = 0;
714           bfd_boolean mem_offset_known = FALSE;
715           bfd_boolean mem_offset_known_long = FALSE;
716           unsigned int mem_mode = 0;
717           bfd_boolean mem_mode_known = FALSE;
718           unsigned int mem_scaled = 0;
719           bfd_boolean mem_scaled_known = FALSE;
720           unsigned int crlo = 0;
721           bfd_boolean crlo_known = FALSE;
722           unsigned int crhi = 0;
723           bfd_boolean crhi_known = FALSE;
724           bfd_boolean spmask_skip_operand = FALSE;
725           unsigned int fcyc_bits = 0;
726           bfd_boolean prev_sploop_found = FALSE;
727
728           switch (opc->operand_info[op_num].form)
729             {
730             case tic6x_operand_b15reg:
731               /* Fully determined by the functional unit.  */
732               operands_text[op_num] = TRUE;
733               snprintf (operands[op_num], 24, "b15");
734               continue;
735
736             case tic6x_operand_zreg:
737               /* Fully determined by the functional unit.  */
738               operands_text[op_num] = TRUE;
739               snprintf (operands[op_num], 24, "%c0",
740                         (func_unit_side == 2 ? 'b' : 'a'));
741               continue;
742
743             case tic6x_operand_retreg:
744               /* Fully determined by the functional unit.  */
745               operands_text[op_num] = TRUE;
746               snprintf (operands[op_num], 24, "%c3",
747                         (func_unit_side == 2 ? 'b' : 'a'));
748               continue;
749
750             case tic6x_operand_irp:
751               operands_text[op_num] = TRUE;
752               snprintf (operands[op_num], 24, "irp");
753               continue;
754
755             case tic6x_operand_nrp:
756               operands_text[op_num] = TRUE;
757               snprintf (operands[op_num], 24, "nrp");
758               continue;
759
760             case tic6x_operand_ilc:
761               operands_text[op_num] = TRUE;
762               snprintf (operands[op_num], 24, "ilc");
763               continue;
764
765             case tic6x_operand_hw_const_minus_1:
766               operands_text[op_num] = TRUE;
767               snprintf (operands[op_num], 24, "-1");
768               continue;
769
770             case tic6x_operand_hw_const_0:
771               operands_text[op_num] = TRUE;
772               snprintf (operands[op_num], 24, "0");
773               continue;
774
775             case tic6x_operand_hw_const_1:
776               operands_text[op_num] = TRUE;
777               snprintf (operands[op_num], 24, "1");
778               continue;
779
780             case tic6x_operand_hw_const_5:
781               operands_text[op_num] = TRUE;
782               snprintf (operands[op_num], 24, "5");
783               continue;
784
785             case tic6x_operand_hw_const_16:
786               operands_text[op_num] = TRUE;
787               snprintf (operands[op_num], 24, "16");
788               continue;
789
790             case tic6x_operand_hw_const_24:
791               operands_text[op_num] = TRUE;
792               snprintf (operands[op_num], 24, "24");
793               continue;
794
795             case tic6x_operand_hw_const_31:
796               operands_text[op_num] = TRUE;
797               snprintf (operands[op_num], 24, "31");
798               continue;
799
800             default:
801               break;
802             }
803
804           for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
805             {
806               const tic6x_coding_field *const enc
807                 = &opc->variable_fields[fld_num];
808               const tic6x_insn_field *field;
809               unsigned int fld_val;
810               unsigned int reg_base = 0;
811               signed int signed_fld_val;
812               char reg_side = '?';
813
814               if (enc->operand_num != op_num)
815                 continue;
816               field = tic6x_field_from_fmt (fmt, enc->field_id);
817               if (!field)
818                 {
819                   printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
820                   abort ();
821                 }
822               fld_val = tic6x_field_bits (opcode, field);
823               switch (enc->coding_method)
824                 {
825                 case tic6x_coding_cst_s3i:
826                   (fld_val == 0x00) && (fld_val = 0x10);
827                   (fld_val == 0x07) && (fld_val = 0x08);
828                   /* Fall through.  */
829                 case tic6x_coding_ucst:
830                 case tic6x_coding_ulcst_dpr_byte:
831                 case tic6x_coding_ulcst_dpr_half:
832                 case tic6x_coding_ulcst_dpr_word:
833                 case tic6x_coding_lcst_low16:
834                   switch (opc->operand_info[op_num].form)
835                     {
836                     case tic6x_operand_asm_const:
837                     case tic6x_operand_link_const:
838                       operands_text[op_num] = TRUE;
839                       snprintf (operands[op_num], 24, "%u", fld_val);
840                       break;
841
842                     case tic6x_operand_mem_long:
843                       mem_offset = fld_val;
844                       mem_offset_known_long = TRUE;
845                       break;
846
847                     default:
848                       printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
849                       abort ();
850                     }
851                   break;
852
853                 case tic6x_coding_lcst_high16:
854                   operands_text[op_num] = TRUE;
855                   snprintf (operands[op_num], 24, "%u", fld_val << 16);
856                   break;
857
858                 case tic6x_coding_scst_l3i:
859                   operands_text[op_num] = TRUE;
860                   if (fld_val == 0)
861                     {
862                       signed_fld_val = 8;
863                     }
864                   else
865                     {
866                       signed_fld_val = (signed int) fld_val;
867                       signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
868                       signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
869                     }
870                   snprintf (operands[op_num], 24, "%d", signed_fld_val);
871                   break;
872
873                 case tic6x_coding_scst:
874                   operands_text[op_num] = TRUE;
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                   snprintf (operands[op_num], 24, "%d", signed_fld_val);
879                   break;
880
881                 case tic6x_coding_ucst_minus_one:
882                   operands_text[op_num] = TRUE;
883                   snprintf (operands[op_num], 24, "%u", fld_val + 1);
884                   break;
885
886                 case tic6x_coding_pcrel:
887                 case tic6x_coding_pcrel_half:
888                   signed_fld_val = (signed int) fld_val;
889                   signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
890                   signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
891                   if (fetch_packet_header_based
892                       && enc->coding_method == tic6x_coding_pcrel_half)
893                     signed_fld_val *= 2;
894                   else
895                     signed_fld_val *= 4;
896                   operands_pcrel[op_num] = TRUE;
897                   operands_addresses[op_num] = fp_addr + signed_fld_val;
898                   break;
899
900                 case tic6x_coding_regpair_msb:
901                   if (opc->operand_info[op_num].form != tic6x_operand_regpair)
902                     abort ();
903                   operands_text[op_num] = TRUE;
904                   snprintf (operands[op_num], 24, "%c%u:%c%u",
905                             (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
906                             (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
907                   break;
908
909                 case tic6x_coding_pcrel_half_unsigned:
910                   operands_pcrel[op_num] = TRUE;
911                   operands_addresses[op_num] = fp_addr + 2 * fld_val;
912                   break;
913
914                 case tic6x_coding_reg_shift:
915                   fld_val <<= 1;
916                   /* Fall through.  */
917                 case tic6x_coding_reg:
918                   if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
919                     {
920                       reg_base = 16;
921                     }
922                   switch (opc->operand_info[op_num].form)
923                     {
924                     case tic6x_operand_treg:
925                       if (!have_t)
926                         {
927                           printf ("opcode %x: operand treg but missing t field\n", opcode);
928                           abort ();
929                         }
930                       operands_text[op_num] = TRUE;
931                       reg_side = t_val ? 'b' : 'a';
932                       snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
933                       break;
934
935                     case tic6x_operand_reg:
936                       operands_text[op_num] = TRUE;
937                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
938                       snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
939                       break;
940
941                     case tic6x_operand_reg_nors:
942                       operands_text[op_num] = TRUE;
943                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
944                       snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
945                       break;
946
947                     case tic6x_operand_reg_bside:
948                       operands_text[op_num] = TRUE;
949                       snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
950                       break;
951
952                     case tic6x_operand_reg_bside_nors:
953                       operands_text[op_num] = TRUE;
954                       snprintf (operands[op_num], 24, "b%u", fld_val);
955                       break;
956
957                     case tic6x_operand_xreg:
958                       operands_text[op_num] = TRUE;
959                       reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
960                       snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
961                       break;
962
963                     case tic6x_operand_dreg:
964                       operands_text[op_num] = TRUE;
965                       reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
966                       snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
967                       break;
968
969                     case tic6x_operand_regpair:
970                       operands_text[op_num] = TRUE;
971                       if (fld_val & 1)
972                         operands_ok = FALSE;
973                       reg_side = (func_unit_side == 2) ? 'b' : 'a';
974                       snprintf (operands[op_num], 24, "%c%u:%c%u",
975                                 reg_side, reg_base + fld_val + 1,
976                                 reg_side, reg_base + fld_val);
977                       break;
978
979                     case tic6x_operand_xregpair:
980                       operands_text[op_num] = TRUE;
981                       if (fld_val & 1)
982                         operands_ok = FALSE;
983                       reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
984                       snprintf (operands[op_num], 24, "%c%u:%c%u",
985                                 reg_side, reg_base + fld_val + 1,
986                                 reg_side, reg_base + fld_val);
987                       break;
988
989                     case tic6x_operand_tregpair:
990                       if (!have_t)
991                         {
992                           printf ("opcode %x: operand tregpair but missing t field\n", opcode);
993                           abort ();
994                         }
995                       operands_text[op_num] = TRUE;
996                       if (fld_val & 1)
997                         operands_ok = FALSE;
998                       reg_side = t_val ? 'b' : 'a';
999                       snprintf (operands[op_num], 24, "%c%u:%c%u",
1000                                 reg_side, reg_base + fld_val + 1,
1001                                 reg_side, reg_base + fld_val);
1002                       break;
1003
1004                     case tic6x_operand_dregpair:
1005                       operands_text[op_num] = TRUE;
1006                       if (fld_val & 1)
1007                         operands_ok = FALSE;
1008                       reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1009                       snprintf (operands[op_num], 24, "%c%u:%c%u",
1010                                 reg_side, reg_base + fld_val + 1,
1011                                 reg_side, reg_base + fld_val);
1012                       break;
1013
1014                     case tic6x_operand_mem_deref:
1015                       operands_text[op_num] = TRUE;
1016                       reg_side = func_unit_side == 2 ? 'b' : 'a';
1017                       snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1018                       break;
1019
1020                     case tic6x_operand_mem_short:
1021                     case tic6x_operand_mem_ndw:
1022                       mem_base_reg = fld_val;
1023                       mem_base_reg_known = TRUE;
1024                       break;
1025
1026                     default:
1027                       printf ("opcode %x: unexpected operand form %d for operand #%d",
1028                               opcode, opc->operand_info[op_num].form, op_num);
1029                       abort ();
1030                     }
1031                   break;
1032
1033                 case tic6x_coding_reg_ptr:
1034                   switch (opc->operand_info[op_num].form)
1035                     {
1036                     case tic6x_operand_mem_short:
1037                     case tic6x_operand_mem_ndw:
1038                       if (fld_val > 0x3u)
1039                         {
1040                           printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
1041                                  opcode, op_num, fld_val);
1042                           abort ();
1043                         }
1044                       mem_base_reg = 0x4 | fld_val;
1045                       mem_base_reg_known = TRUE;
1046                       break;
1047
1048                     default:
1049                       printf ("opcode %x: unexpected operand form %d for operand #%d",
1050                               opcode, opc->operand_info[op_num].form, op_num);
1051                       abort ();
1052                     }
1053                   break;
1054
1055                 case tic6x_coding_areg:
1056                   switch (opc->operand_info[op_num].form)
1057                     {
1058                     case tic6x_operand_areg:
1059                       operands_text[op_num] = TRUE;
1060                       snprintf (operands[op_num], 24, "b%u",
1061                                 fld_val ? 15u : 14u);
1062                       break;
1063
1064                     case tic6x_operand_mem_long:
1065                       mem_base_reg = fld_val ? 15u : 14u;
1066                       mem_base_reg_known_long = TRUE;
1067                       break;
1068
1069                     default:
1070                       printf ("opcode %x: bad operand form\n", opcode);
1071                       abort ();
1072                     }
1073                   break;
1074
1075                 case tic6x_coding_mem_offset_minus_one_noscale:
1076                 case tic6x_coding_mem_offset_minus_one:
1077                   fld_val += 1;
1078                   /* Fall through.  */
1079                 case tic6x_coding_mem_offset_noscale:
1080                 case tic6x_coding_mem_offset:
1081                   mem_offset = fld_val;
1082                   mem_offset_known = TRUE;
1083                   if (num_bits == 16)
1084                     {
1085                       mem_mode_known = TRUE;
1086                       mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1087                       mem_scaled_known = TRUE;
1088                       mem_scaled = TRUE;
1089                       if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1090                         {
1091                           mem_base_reg_known = TRUE;
1092                           mem_base_reg = 15;
1093                         }
1094                       if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1095                            || enc->coding_method == tic6x_coding_mem_offset_noscale )
1096                         mem_scaled = FALSE;
1097                     }
1098                   break;
1099
1100                 case tic6x_coding_mem_mode:
1101                   mem_mode = fld_val;
1102                   mem_mode_known = TRUE;
1103                   break;
1104
1105                 case tic6x_coding_scaled:
1106                   mem_scaled = fld_val;
1107                   mem_scaled_known = TRUE;
1108                   break;
1109
1110                 case tic6x_coding_crlo:
1111                   crlo = fld_val;
1112                   crlo_known = TRUE;
1113                   break;
1114
1115                 case tic6x_coding_crhi:
1116                   crhi = fld_val;
1117                   crhi_known = TRUE;
1118                   break;
1119
1120                 case tic6x_coding_fstg:
1121                 case tic6x_coding_fcyc:
1122                   if (!prev_sploop_found)
1123                     {
1124                       bfd_vma search_fp_addr = fp_addr;
1125                       bfd_vma search_fp_offset = fp_offset;
1126                       bfd_boolean search_fp_header_based
1127                         = fetch_packet_header_based;
1128                       tic6x_fetch_packet_header search_fp_header = header;
1129                       unsigned char search_fp[32];
1130                       unsigned int search_num_bits;
1131                       unsigned int search_opcode;
1132                       unsigned int sploop_ii = 0;
1133                       int i;
1134
1135                       memcpy (search_fp, fp, 32);
1136
1137                       /* To interpret these bits in an SPKERNEL
1138                          instruction, we must find the previous
1139                          SPLOOP-family instruction.  It may come up to
1140                          48 execute packets earlier.  */
1141                       for (i = 0; i < 48 * 8; i++)
1142                         {
1143                           /* Find the previous instruction.  */
1144                           if (search_fp_offset & 2)
1145                             search_fp_offset -= 2;
1146                           else if (search_fp_offset >= 4)
1147                             {
1148                               if (search_fp_header_based
1149                                   && (search_fp_header.word_compact
1150                                       [(search_fp_offset >> 2) - 1]))
1151                                 search_fp_offset -= 2;
1152                               else
1153                                 search_fp_offset -= 4;
1154                             }
1155                           else
1156                             {
1157                               search_fp_addr -= 32;
1158                               status = info->read_memory_func (search_fp_addr,
1159                                                                search_fp,
1160                                                                32, info);
1161                               if (status)
1162                                 /* No previous SPLOOP instruction.  */
1163                                 break;
1164                               search_fp_header_based
1165                                 = (tic6x_check_fetch_packet_header
1166                                    (search_fp, &search_fp_header, info));
1167                               if (search_fp_header_based)
1168                                 search_fp_offset
1169                                   = search_fp_header.word_compact[6] ? 26 : 24;
1170                               else
1171                                 search_fp_offset = 28;
1172                             }
1173
1174                           /* Extract the previous instruction.  */
1175                           if (search_fp_header_based)
1176                             search_num_bits
1177                               = (search_fp_header.word_compact[search_fp_offset
1178                                                                >> 2]
1179                                  ? 16
1180                                  : 32);
1181                           else
1182                             search_num_bits = 32;
1183                           if (search_num_bits == 16)
1184                             {
1185                               if (info->endian == BFD_ENDIAN_LITTLE)
1186                                 search_opcode
1187                                   = (tic6x_extract_16
1188                                      (search_fp + search_fp_offset, &header, info));
1189                               else
1190                                 search_opcode
1191                                   = (tic6x_extract_16
1192                                      (search_fp + (search_fp_offset ^ 2), &header,
1193                                       info));
1194                             }
1195                           else
1196                             search_opcode
1197                               = tic6x_extract_32 (search_fp + search_fp_offset,
1198                                                   info);
1199
1200                           /* Check whether it is an SPLOOP-family
1201                              instruction.  */
1202                           if (search_num_bits == 32
1203                               && ((search_opcode & 0x003ffffe) == 0x00038000
1204                                   || (search_opcode & 0x003ffffe) == 0x0003a000
1205                                   || ((search_opcode & 0x003ffffe)
1206                                       == 0x0003e000)))
1207                             {
1208                               prev_sploop_found = TRUE;
1209                               sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1210                             }
1211                           else if (search_num_bits == 16
1212                                    && (search_opcode & 0x3c7e) == 0x0c66)
1213                             {
1214                               prev_sploop_found = TRUE;
1215                               sploop_ii
1216                                 = (((search_opcode >> 7) & 0x7)
1217                                    | ((search_opcode >> 11) & 0x8)) + 1;
1218                             }
1219                           if (prev_sploop_found)
1220                             {
1221                               if (sploop_ii <= 0)
1222                                 {
1223                                   printf ("opcode %x:  sloop index not found (%d)\n", opcode, sploop_ii);
1224                                   abort ();
1225                                 }
1226                               else if (sploop_ii <= 1)
1227                                 fcyc_bits = 0;
1228                               else if (sploop_ii <= 2)
1229                                 fcyc_bits = 1;
1230                               else if (sploop_ii <= 4)
1231                                 fcyc_bits = 2;
1232                               else if (sploop_ii <= 8)
1233                                 fcyc_bits = 3;
1234                               else if (sploop_ii <= 14)
1235                                 fcyc_bits = 4;
1236                               else
1237                                 prev_sploop_found = FALSE;
1238                             }
1239                           if (prev_sploop_found)
1240                             break;
1241                         }
1242                     }
1243                   if (!prev_sploop_found)
1244                     {
1245                       operands_ok = FALSE;
1246                       operands_text[op_num] = TRUE;
1247                       break;
1248                     }
1249                   if (fcyc_bits > tic6x_field_width(field))
1250                     {
1251                       printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1252                       abort ();
1253                     }
1254                   if (enc->coding_method == tic6x_coding_fstg)
1255                     {
1256                       int i, t;
1257                       for (t = 0, i = fcyc_bits; i < 6; i++)
1258                         t = (t << 1) | ((fld_val >> i) & 1);
1259                       operands_text[op_num] = TRUE;
1260                       snprintf (operands[op_num], 24, "%u", t);
1261                     }
1262                   else
1263                     {
1264                       operands_text[op_num] = TRUE;
1265                       snprintf (operands[op_num], 24, "%u",
1266                                 fld_val & ((1 << fcyc_bits) - 1));
1267                     }
1268                   break;
1269
1270                 case tic6x_coding_spmask:
1271                   if (fld_val == 0)
1272                     spmask_skip_operand = TRUE;
1273                   else
1274                     {
1275                       char *p;
1276                       unsigned int i;
1277
1278                       operands_text[op_num] = TRUE;
1279                       p = operands[op_num];
1280                       for (i = 0; i < 8; i++)
1281                         if (fld_val & (1 << i))
1282                           {
1283                             *p++ = "LSDM"[i/2];
1284                             *p++ = '1' + (i & 1);
1285                             *p++ = ',';
1286                           }
1287                       p[-1] = 0;
1288                     }
1289                   break;
1290
1291                 case tic6x_coding_fu:
1292                 case tic6x_coding_data_fu:
1293                 case tic6x_coding_xpath:
1294                 case tic6x_coding_rside:
1295                   /* Don't relate to operands, so operand number is
1296                      meaningless.  */
1297                   break;
1298
1299                 default:
1300                   printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1301                   abort ();
1302                 }
1303
1304               if (mem_base_reg_known_long && mem_offset_known_long)
1305                 {
1306                   if (operands_text[op_num] || operands_pcrel[op_num])
1307                     {
1308                       printf ("opcode %x: long access but operands already known ?\n", opcode);
1309                       abort ();
1310                     }
1311                   operands_text[op_num] = TRUE;
1312                   snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1313                             mem_offset * opc->operand_info[op_num].size);
1314                 }
1315
1316               if (mem_base_reg_known && mem_offset_known && mem_mode_known
1317                   && (mem_scaled_known
1318                       || (opc->operand_info[op_num].form
1319                           != tic6x_operand_mem_ndw)))
1320                 {
1321                   char side;
1322                   char base[4];
1323                   bfd_boolean offset_is_reg;
1324                   bfd_boolean offset_scaled;
1325                   char offset[4];
1326                   char offsetp[6];
1327
1328                   if (operands_text[op_num] || operands_pcrel[op_num])
1329                     {
1330                       printf ("opcode %x: mem access operands already known ?\n", opcode);
1331                       abort ();
1332                     }
1333
1334                   side = func_unit_side == 2 ? 'b' : 'a';
1335                   snprintf (base, 4, "%c%u", side, mem_base_reg);
1336
1337                   offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
1338                   if (offset_is_reg)
1339                     {
1340
1341                       if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1342                         {
1343                           reg_base = 16;
1344                         }
1345                       snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1346                       if (opc->operand_info[op_num].form
1347                           == tic6x_operand_mem_ndw)
1348                         offset_scaled = mem_scaled ? TRUE : FALSE;
1349                       else
1350                         offset_scaled = TRUE;
1351                     }
1352                   else
1353                     {
1354                       if (opc->operand_info[op_num].form
1355                           == tic6x_operand_mem_ndw)
1356                         {
1357                           offset_scaled = mem_scaled ? TRUE : FALSE;
1358                           snprintf (offset, 4, "%u", mem_offset);
1359                         }
1360                       else
1361                         {
1362                           offset_scaled = FALSE;
1363                           snprintf (offset, 4, "%u",
1364                                     (mem_offset
1365                                      * opc->operand_info[op_num].size));
1366                         }
1367                     }
1368
1369                   if (offset_scaled)
1370                     snprintf (offsetp, 6, "[%s]", offset);
1371                   else
1372                     snprintf (offsetp, 6, "(%s)", offset);
1373
1374                   operands_text[op_num] = TRUE;
1375                   switch (mem_mode & ~4u)
1376                     {
1377                     case 0:
1378                       snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1379                       break;
1380
1381                     case 1:
1382                       snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1383                       break;
1384
1385                     case 2:
1386                     case 3:
1387                       operands_ok = FALSE;
1388                       break;
1389
1390                     case 8:
1391                       snprintf (operands[op_num], 24, "*--%s%s", base,
1392                                 offsetp);
1393                       break;
1394
1395                     case 9:
1396                       snprintf (operands[op_num], 24, "*++%s%s", base,
1397                                 offsetp);
1398                       break;
1399
1400                     case 10:
1401                       snprintf (operands[op_num], 24, "*%s--%s", base,
1402                                 offsetp);
1403                       break;
1404
1405                     case 11:
1406                       snprintf (operands[op_num], 24, "*%s++%s", base,
1407                                 offsetp);
1408                       break;
1409
1410                     default:
1411                       printf ("*** unknown mem_mode : %d \n", mem_mode);
1412                       abort ();
1413                     }
1414                 }
1415
1416               if (crlo_known && crhi_known)
1417                 {
1418                   tic6x_rw rw;
1419                   tic6x_ctrl_id crid;
1420
1421                   if (operands_text[op_num] || operands_pcrel[op_num])
1422                     {
1423                       printf ("*** abort crlo crli\n");
1424                       abort ();
1425                     }
1426
1427                   rw = opc->operand_info[op_num].rw;
1428                   if (rw != tic6x_rw_read
1429                       && rw != tic6x_rw_write)
1430                     {
1431                       printf ("*** abort rw : %d\n", rw);
1432                       abort ();
1433                     }
1434
1435                   for (crid = 0; crid < tic6x_ctrl_max; crid++)
1436                     {
1437                       if (crlo == tic6x_ctrl_table[crid].crlo
1438                           && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1439                           && (rw == tic6x_rw_read
1440                               ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1441                                  || (tic6x_ctrl_table[crid].rw
1442                                      == tic6x_rw_read_write))
1443                               : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1444                                  || (tic6x_ctrl_table[crid].rw
1445                                      == tic6x_rw_read_write))))
1446                         break;
1447                     }
1448                   if (crid == tic6x_ctrl_max)
1449                     {
1450                       operands_text[op_num] = TRUE;
1451                       operands_ok = FALSE;
1452                     }
1453                   else
1454                     {
1455                       operands_text[op_num] = TRUE;
1456                       snprintf (operands[op_num], 24, "%s",
1457                                 tic6x_ctrl_table[crid].name);
1458                     }
1459                 }
1460
1461               if (operands_text[op_num] || operands_pcrel[op_num]
1462                   || spmask_skip_operand)
1463                 break;
1464             }
1465           /* end for fld_num */
1466
1467           if (spmask_skip_operand)
1468             {
1469               /* SPMASK operands are only valid as the single operand
1470                  in the opcode table.  */
1471               if (num_operands != 1)
1472                 {
1473                   printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
1474                   abort ();
1475                 }
1476               num_operands = 0;
1477               break;
1478             }
1479
1480           /* The operand must by now have been decoded.  */
1481           if (!operands_text[op_num] && !operands_pcrel[op_num])
1482             {
1483               printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
1484               abort ();
1485             }
1486         }
1487       /* end for op_num */
1488
1489       if (!operands_ok)
1490         continue;
1491
1492       info->bytes_per_chunk = num_bits / 8;
1493       info->fprintf_func (info->stream, "%s", parallel);
1494       info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1495                           func_unit);
1496       for (op_num = 0; op_num < num_operands; op_num++)
1497         {
1498           info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1499           if (operands_pcrel[op_num])
1500             info->print_address_func (operands_addresses[op_num], info);
1501           else
1502             info->fprintf_func (info->stream, "%s", operands[op_num]);
1503         }
1504       if (fetch_packet_header_based && header.prot)
1505         info->fprintf_func (info->stream, " || nop 5");
1506
1507       return num_bits / 8;
1508     }
1509
1510   info->bytes_per_chunk = num_bits / 8;
1511   info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1512                       (int) num_bits / 4, opcode);
1513   return num_bits / 8;
1514 }