OSDN Git Service

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