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