Coverage Report

Created: 2026-10-02 09:53

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