Coverage Report

Created: 2026-07-12 09:22

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
9.05M
{
116
9.05M
  unsigned int f;
117
118
32.4M
  for (f = 0; f < fmt->num_fields; f++)
119
32.3M
    if (fmt->fields[f].field_id == field)
120
8.99M
      return &fmt->fields[f];
121
122
59.4k
  return NULL;
123
9.05M
}
124
125
/* Extract the field width.  */
126
127
static unsigned int
128
tic6x_field_width (const tic6x_insn_field *field)
129
26.3k
{
130
26.3k
  unsigned int i;
131
26.3k
  unsigned int width = 0;
132
133
26.3k
  if (!field->num_bitfields)
134
0
    return field->bitfields[0].width;
135
136
53.6k
  for (i = 0 ; i < field->num_bitfields ; i++)
137
27.3k
    width += field->bitfields[i].width;
138
139
26.3k
  return width;
140
26.3k
}
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
8.99M
{
147
8.99M
  unsigned int i;
148
8.99M
  unsigned int val = 0;
149
150
8.99M
  if (!field->num_bitfields)
151
0
    return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1);
152
153
17.9M
  for (i = 0 ; i < field->num_bitfields ; i++)
154
9.00M
    val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1))
155
9.00M
      << field->bitfields[i].pos;
156
157
8.99M
  return val;
158
8.99M
}
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
458k
{
165
458k
  if (info->endian == BFD_ENDIAN_LITTLE)
166
8.27k
    return p[0] | (p[1] << 8) | (p[2] << 16) | ((unsigned) p[3] << 24);
167
449k
  else
168
449k
    return p[3] | (p[2] << 8) | (p[1] << 16) | ((unsigned) p[0] << 24);
169
458k
}
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
16.5k
{
177
16.5k
  unsigned int op16;
178
179
16.5k
  if (info->endian == BFD_ENDIAN_LITTLE)
180
111
    op16 = (p[0]) | (p[1] << 8);
181
16.4k
  else
182
16.4k
    op16 = (p[1]) | (p[0] << 8);
183
16.5k
  op16 |= (header->sat << TIC6X_COMPACT_SAT_POS);
184
16.5k
  op16 |= (header->br << TIC6X_COMPACT_BR_POS);
185
16.5k
  op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS);
186
16.5k
  return op16;
187
16.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
182k
{
197
182k
  int i;
198
199
182k
  header->header = tic6x_extract_32 (fp + 28, info);
200
201
182k
  if ((header->header & 0xf0000000) != 0xe0000000)
202
160k
    {
203
160k
      header->prot = 0;
204
160k
      header->rs = 0;
205
160k
      header->dsz = 0;
206
160k
      header->br = 0;
207
160k
      header->sat = 0;
208
1.28M
      for (i = 0; i < 7; i++)
209
1.12M
  header->word_compact[i] = false;
210
2.40M
      for (i = 0; i < 14; i++)
211
2.24M
  header->p_bits[i] = false;
212
160k
      return false;
213
160k
    }
214
215
177k
  for (i = 0; i < 7; i++)
216
155k
    header->word_compact[i]
217
155k
      = (header->header & (1u << (21 + i))) != 0;
218
219
22.1k
  header->prot = (header->header & (1u << 20)) != 0;
220
22.1k
  header->rs = (header->header & (1u << 19)) != 0;
221
22.1k
  header->dsz = (header->header >> 16) & 0x7;
222
22.1k
  header->br = (header->header & (1u << 15)) != 0;
223
22.1k
  header->sat = (header->header & (1u << 14)) != 0;
224
225
332k
  for (i = 0; i < 14; i++)
226
310k
    header->p_bits[i] = (header->header & (1u << i)) != 0;
227
228
22.1k
  return true;
229
182k
}
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
165k
{
238
165k
  int status;
239
165k
  bfd_vma fp_addr;
240
165k
  bfd_vma fp_offset;
241
165k
  unsigned char fp[32];
242
165k
  unsigned int opcode;
243
165k
  tic6x_opcode_id opcode_id;
244
165k
  bool fetch_packet_header_based;
245
165k
  tic6x_fetch_packet_header header;
246
165k
  unsigned int num_bits;
247
165k
  bool bad_offset = false;
248
249
165k
  fp_offset = addr & 0x1f;
250
165k
  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
165k
  info->stop_vma = 0;
254
165k
  status = info->read_memory_func (fp_addr, fp, 32, info);
255
165k
  if (status)
256
193
    {
257
193
      info->memory_error_func (status, addr, info);
258
193
      return -1;
259
193
    }
260
261
164k
  fetch_packet_header_based
262
164k
    = tic6x_check_fetch_packet_header (fp, &header, info);
263
164k
  if (fetch_packet_header_based)
264
20.9k
    {
265
20.9k
      if (fp_offset & 0x1)
266
2
  bad_offset = true;
267
20.9k
      else if ((fp_offset & 0x3) && (fp_offset >= 28
268
7.50k
             || !header.word_compact[fp_offset >> 2]))
269
2
  bad_offset = true;
270
20.9k
      else if (fp_offset == 28)
271
1.68k
  {
272
1.68k
    info->bytes_per_chunk = 4;
273
1.68k
    info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
274
1.68k
            header.header);
275
1.68k
    return 4;
276
1.68k
  }
277
20.9k
    }
278
144k
  else
279
144k
    {
280
144k
      if (fp_offset & 0x3)
281
1
  bad_offset = true;
282
144k
    }
283
284
163k
  if (bad_offset)
285
5
    {
286
5
      info->bytes_per_chunk = 1;
287
5
      info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
288
5
      return 1;
289
5
    }
290
291
163k
  num_bits = 32;
292
163k
  if (fetch_packet_header_based && header.word_compact[fp_offset >> 2])
293
15.0k
    num_bits = 16;
294
295
163k
  if (num_bits == 16)
296
15.0k
    {
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
15.0k
      if (info->endian == BFD_ENDIAN_LITTLE)
303
111
  opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
304
14.9k
      else
305
14.9k
  opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
306
15.0k
    }
307
148k
  else
308
148k
    opcode = tic6x_extract_32 (fp + fp_offset, info);
309
310
64.5M
  for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
311
64.4M
    {
312
64.4M
      const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
313
64.4M
      const tic6x_insn_format *const fmt
314
64.4M
  = &tic6x_insn_format_table[opc->format];
315
64.4M
      const tic6x_insn_field *creg_field;
316
64.4M
      bool p_bit;
317
64.4M
      const char *parallel;
318
64.4M
      const char *cond = "";
319
64.4M
      const char *func_unit;
320
64.4M
      char func_unit_buf[8];
321
64.4M
      unsigned int func_unit_side = 0;
322
64.4M
      unsigned int func_unit_data_side = 0;
323
64.4M
      unsigned int func_unit_cross = 0;
324
64.4M
      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
64.4M
      char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
329
64.4M
      bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
330
64.4M
      bool operands_text[TIC6X_MAX_OPERANDS] = { false };
331
64.4M
      bool operands_pcrel[TIC6X_MAX_OPERANDS] = { false };
332
64.4M
      unsigned int fix;
333
64.4M
      unsigned int num_operands;
334
64.4M
      unsigned int op_num;
335
64.4M
      bool fixed_ok;
336
64.4M
      bool operands_ok;
337
64.4M
      bool have_t = false;
338
339
64.4M
      if (opc->flags & TIC6X_FLAG_MACRO)
340
6.82M
  continue;
341
57.6M
      if (fmt->num_bits != num_bits)
342
19.4M
  continue;
343
38.1M
      if ((opcode & fmt->mask) != fmt->cst_bits)
344
35.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
2.87M
      creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
351
2.87M
      if (creg_field)
352
2.81M
  {
353
2.81M
    const tic6x_insn_field *z_field;
354
2.81M
    unsigned int creg_value, z_value;
355
2.81M
    static const char *const conds[8][2] =
356
2.81M
      {
357
2.81M
        { "", NULL },
358
2.81M
        { "[b0] ", "[!b0] " },
359
2.81M
        { "[b1] ", "[!b1] " },
360
2.81M
        { "[b2] ", "[!b2] " },
361
2.81M
        { "[a1] ", "[!a1] " },
362
2.81M
        { "[a2] ", "[!a2] " },
363
2.81M
        { "[a0] ", "[!a0] " },
364
2.81M
        { NULL, NULL }
365
2.81M
      };
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
2.81M
    z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
371
2.81M
    if (!z_field)
372
0
      {
373
0
        printf ("*** opcode %x: missing z field", opcode);
374
0
        abort ();
375
0
      }
376
377
2.81M
    creg_value = tic6x_field_bits (opcode, creg_field);
378
2.81M
    z_value = tic6x_field_bits (opcode, z_field);
379
2.81M
    cond = conds[creg_value][z_value];
380
2.81M
    if (cond == NULL)
381
538k
      continue;
382
2.81M
  }
383
384
2.33M
      if (opc->flags & TIC6X_FLAG_INSN16_SPRED)
385
5.98k
  {
386
5.98k
    const tic6x_insn_field *cc_field;
387
5.98k
          unsigned int s_value = 0;
388
5.98k
          unsigned int z_value = 0;
389
5.98k
          bool cond_known = false;
390
5.98k
          static const char *const conds[2][2] =
391
5.98k
            {
392
5.98k
              { "[a0] ", "[!a0] " },
393
5.98k
              { "[b0] ", "[!b0] " }
394
5.98k
            };
395
396
5.98k
          cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc);
397
398
5.98k
          if (cc_field)
399
199
      {
400
199
        unsigned int cc_value;
401
402
199
        cc_value = tic6x_field_bits (opcode, cc_field);
403
199
        s_value = (cc_value & 0x2) >> 1;
404
199
        z_value = (cc_value & 0x1);
405
199
        cond_known = true;
406
199
      }
407
5.78k
    else
408
5.78k
      {
409
5.78k
        const tic6x_insn_field *z_field;
410
5.78k
        const tic6x_insn_field *s_field;
411
412
5.78k
        s_field = tic6x_field_from_fmt (fmt, tic6x_field_s);
413
414
5.78k
        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
5.78k
        s_value = tic6x_field_bits (opcode, s_field);
421
5.78k
        z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
422
5.78k
        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
5.78k
        z_value = tic6x_field_bits (opcode, z_field);
429
5.78k
        cond_known = true;
430
5.78k
      }
431
432
5.98k
          if (!cond_known)
433
0
      {
434
0
        printf ("opcode %x: unspecified ompact insn predicate\n", opcode);
435
0
        abort ();
436
0
      }
437
5.98k
          cond = conds[s_value][z_value];
438
5.98k
  }
439
440
      /* All fixed fields must have matching values; all fields with
441
   restricted ranges must have values within those ranges.  */
442
2.33M
      fixed_ok = true;
443
2.50M
      for (fix = 0; fix < opc->num_fixed_fields; fix++)
444
2.39M
  {
445
2.39M
    unsigned int field_bits;
446
2.39M
    const tic6x_insn_field *const field
447
2.39M
      = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
448
449
2.39M
    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
2.39M
    field_bits = tic6x_field_bits (opcode, field);
457
2.39M
    if (field_bits < opc->fixed_fields[fix].min_val
458
851k
        || field_bits > opc->fixed_fields[fix].max_val)
459
2.22M
      {
460
2.22M
        fixed_ok = false;
461
2.22M
        break;
462
2.22M
      }
463
2.39M
  }
464
2.33M
      if (!fixed_ok)
465
2.22M
  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
113k
      if (num_bits == 16 && (fp_offset & 0x2) == 2)
475
6.94k
  {
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.94k
    p_bit = header.p_bits[(fp_offset >> 2) << 1];
481
6.94k
  }
482
106k
      else if (fp_offset >= 4)
483
91.7k
  {
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
91.7k
    if (fetch_packet_header_based
488
7.37k
        && header.word_compact[(fp_offset >> 2) - 1])
489
4.34k
      p_bit = header.p_bits[(fp_offset >> 1) - 1];
490
87.4k
    else
491
87.4k
      {
492
87.4k
        unsigned int prev_opcode
493
87.4k
    = tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
494
87.4k
        p_bit = (prev_opcode & 0x1) != 0;
495
87.4k
      }
496
91.7k
  }
497
14.3k
      else
498
14.3k
  {
499
    /* Find the last instruction of the previous fetch
500
       packet.  */
501
14.3k
    unsigned char fp_prev[32];
502
503
14.3k
    status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
504
14.3k
    if (status)
505
      /* No previous instruction to be parallel with.  */
506
384
      p_bit = false;
507
13.9k
    else
508
13.9k
      {
509
13.9k
        bool prev_header_based;
510
13.9k
        tic6x_fetch_packet_header prev_header;
511
512
13.9k
        prev_header_based
513
13.9k
    = tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
514
13.9k
        if (prev_header_based)
515
1.10k
    {
516
1.10k
      if (prev_header.word_compact[6])
517
841
        p_bit = prev_header.p_bits[13];
518
265
      else
519
265
        {
520
265
          unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 24,
521
265
                   info);
522
265
          p_bit = (prev_opcode & 0x1) != 0;
523
265
        }
524
1.10k
    }
525
12.8k
        else
526
12.8k
    {
527
12.8k
      unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
528
12.8k
                     info);
529
12.8k
      p_bit = (prev_opcode & 0x1) != 0;
530
12.8k
    }
531
13.9k
      }
532
14.3k
  }
533
113k
      parallel = p_bit ? "|| " : "";
534
535
113k
      if (opc->func_unit == tic6x_func_unit_nfu)
536
10.5k
  func_unit = "";
537
102k
      else
538
102k
  {
539
102k
    unsigned int fld_num;
540
102k
    char func_unit_char;
541
102k
    const char *data_str;
542
102k
    bool have_areg = false;
543
102k
    bool have_cross = false;
544
545
102k
    func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
546
102k
    func_unit_cross = 0;
547
102k
    func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
548
549
571k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
550
468k
      {
551
468k
        const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
552
468k
        const tic6x_insn_field *field;
553
468k
        unsigned int fld_val;
554
555
468k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
556
557
468k
        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
468k
        fld_val = tic6x_field_bits (opcode, field);
565
566
468k
        switch (enc->coding_method)
567
468k
    {
568
83.0k
    case tic6x_coding_fu:
569
      /* The side must be specified exactly once.  */
570
83.0k
      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
83.0k
      func_unit_side = (fld_val ? 2 : 1);
577
83.0k
      break;
578
579
38.0k
    case tic6x_coding_data_fu:
580
      /* The data side must be specified exactly once.  */
581
38.0k
      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
38.0k
      func_unit_data_side = (fld_val ? 2 : 1);
588
38.0k
      break;
589
590
37.3k
    case tic6x_coding_xpath:
591
      /* Cross path use must be specified exactly
592
         once.  */
593
37.3k
      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
37.3k
      have_cross = true;
600
37.3k
      func_unit_cross = fld_val;
601
37.3k
      break;
602
603
1.84k
                case tic6x_coding_rside:
604
                  /* If the format has a t field, use it for src/dst register side.  */
605
1.84k
                  have_t = true;
606
1.84k
                  t_val = fld_val;
607
1.84k
                  func_unit_data_side = (t_val ? 2 : 1);
608
1.84k
                  break;
609
610
18.9k
    case tic6x_coding_areg:
611
18.9k
      have_areg = true;
612
18.9k
      break;
613
614
289k
    default:
615
      /* Don't relate to functional units.  */
616
289k
      break;
617
468k
    }
618
468k
      }
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
102k
    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
102k
    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
102k
    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
102k
    if (have_areg && !func_unit_data_side)
652
320
      {
653
320
        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
320
        func_unit_cross = func_unit_side == 1;
659
320
      }
660
661
102k
    switch (opc->func_unit)
662
102k
      {
663
42.0k
      case tic6x_func_unit_d:
664
42.0k
        func_unit_char = 'D';
665
42.0k
        break;
666
667
8.14k
      case tic6x_func_unit_l:
668
8.14k
        func_unit_char = 'L';
669
8.14k
        break;
670
671
23.0k
      case tic6x_func_unit_m:
672
23.0k
        func_unit_char = 'M';
673
23.0k
        break;
674
675
29.2k
      case tic6x_func_unit_s:
676
29.2k
        func_unit_char = 'S';
677
29.2k
        break;
678
679
0
      default:
680
0
              printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
681
0
        abort ();
682
102k
      }
683
684
102k
    switch (func_unit_data_side)
685
102k
      {
686
62.6k
      case 0:
687
62.6k
        data_str = "";
688
62.6k
        break;
689
690
20.0k
      case 1:
691
20.0k
        data_str = "T1";
692
20.0k
        break;
693
694
19.8k
      case 2:
695
19.8k
        data_str = "T2";
696
19.8k
        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
102k
      }
703
704
102k
    if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
705
79
        func_unit_cross = 1;
706
707
102k
    snprintf (func_unit_buf, sizeof func_unit_buf, " .%c%u%s%s",
708
102k
        func_unit_char, func_unit_side,
709
102k
        (func_unit_cross ? "X" : ""), data_str);
710
102k
    func_unit = func_unit_buf;
711
102k
  }
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
113k
      operands_ok = true;
717
113k
      num_operands = opc->num_operands;
718
378k
      for (op_num = 0; op_num < num_operands; op_num++)
719
265k
  {
720
265k
    unsigned int fld_num;
721
265k
    unsigned int mem_base_reg = 0;
722
265k
    bool mem_base_reg_known = false;
723
265k
    bool mem_base_reg_known_long = false;
724
265k
    unsigned int mem_offset = 0;
725
265k
    bool mem_offset_known = false;
726
265k
    bool mem_offset_known_long = false;
727
265k
    unsigned int mem_mode = 0;
728
265k
    bool mem_mode_known = false;
729
265k
    unsigned int mem_scaled = 0;
730
265k
    bool mem_scaled_known = false;
731
265k
    unsigned int crlo = 0;
732
265k
    bool crlo_known = false;
733
265k
    unsigned int crhi = 0;
734
265k
    bool crhi_known = false;
735
265k
    bool spmask_skip_operand = false;
736
265k
    unsigned int fcyc_bits = 0;
737
265k
    bool prev_sploop_found = false;
738
739
265k
    switch (opc->operand_info[op_num].form)
740
265k
      {
741
108
      case tic6x_operand_b15reg:
742
        /* Fully determined by the functional unit.  */
743
108
        operands_text[op_num] = true;
744
108
        snprintf (operands[op_num], 24, "b15");
745
108
        continue;
746
747
63
      case tic6x_operand_zreg:
748
        /* Fully determined by the functional unit.  */
749
63
        operands_text[op_num] = true;
750
63
        snprintf (operands[op_num], 24, "%c0",
751
63
      (func_unit_side == 2 ? 'b' : 'a'));
752
63
        continue;
753
754
365
      case tic6x_operand_retreg:
755
        /* Fully determined by the functional unit.  */
756
365
        operands_text[op_num] = true;
757
365
        snprintf (operands[op_num], 24, "%c3",
758
365
      (func_unit_side == 2 ? 'b' : 'a'));
759
365
        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
2
      case tic6x_operand_ilc:
772
2
        operands_text[op_num] = true;
773
2
        snprintf (operands[op_num], 24, "ilc");
774
2
        continue;
775
776
3
      case tic6x_operand_hw_const_minus_1:
777
3
        operands_text[op_num] = true;
778
3
        snprintf (operands[op_num], 24, "-1");
779
3
        continue;
780
781
6
      case tic6x_operand_hw_const_0:
782
6
        operands_text[op_num] = true;
783
6
        snprintf (operands[op_num], 24, "0");
784
6
        continue;
785
786
12
      case tic6x_operand_hw_const_1:
787
12
        operands_text[op_num] = true;
788
12
        snprintf (operands[op_num], 24, "1");
789
12
        continue;
790
791
5.55k
      case tic6x_operand_hw_const_5:
792
5.55k
        operands_text[op_num] = true;
793
5.55k
        snprintf (operands[op_num], 24, "5");
794
5.55k
        continue;
795
796
2.27k
      case tic6x_operand_hw_const_16:
797
2.27k
        operands_text[op_num] = true;
798
2.27k
        snprintf (operands[op_num], 24, "16");
799
2.27k
        continue;
800
801
22
      case tic6x_operand_hw_const_24:
802
22
        operands_text[op_num] = true;
803
22
        snprintf (operands[op_num], 24, "24");
804
22
        continue;
805
806
63
      case tic6x_operand_hw_const_31:
807
63
        operands_text[op_num] = true;
808
63
        snprintf (operands[op_num], 24, "31");
809
63
        continue;
810
811
257k
      default:
812
257k
        break;
813
265k
      }
814
815
976k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
816
976k
      {
817
976k
        const tic6x_coding_field *const enc
818
976k
    = &opc->variable_fields[fld_num];
819
976k
        const tic6x_insn_field *field;
820
976k
        unsigned int fld_val;
821
976k
        unsigned int reg_base = 0;
822
976k
        signed int signed_fld_val;
823
976k
              char reg_side = '?';
824
825
976k
        if (enc->operand_num != op_num)
826
498k
    continue;
827
478k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
828
478k
        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
478k
              fld_val = tic6x_field_bits (opcode, field);
834
478k
        switch (enc->coding_method)
835
478k
    {
836
155
                case tic6x_coding_cst_s3i:
837
155
                  (fld_val == 0x00) && (fld_val = 0x10);
838
155
                  (fld_val == 0x07) && (fld_val = 0x08);
839
                  /* Fall through.  */
840
14.0k
    case tic6x_coding_ucst:
841
19.3k
    case tic6x_coding_ulcst_dpr_byte:
842
24.9k
    case tic6x_coding_ulcst_dpr_half:
843
33.0k
    case tic6x_coding_ulcst_dpr_word:
844
33.0k
    case tic6x_coding_lcst_low16:
845
33.0k
      switch (opc->operand_info[op_num].form)
846
33.0k
        {
847
13.8k
        case tic6x_operand_asm_const:
848
14.3k
        case tic6x_operand_link_const:
849
14.3k
          operands_text[op_num] = true;
850
14.3k
          snprintf (operands[op_num], 24, "%u", fld_val);
851
14.3k
          break;
852
853
18.6k
        case tic6x_operand_mem_long:
854
18.6k
          mem_offset = fld_val;
855
18.6k
          mem_offset_known_long = true;
856
18.6k
          break;
857
858
0
        default:
859
0
                      printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
860
0
          abort ();
861
33.0k
        }
862
33.0k
      break;
863
864
33.0k
    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
519
                case tic6x_coding_scst_l3i:
870
519
      operands_text[op_num] = true;
871
519
                  if (fld_val == 0)
872
72
        {
873
72
          signed_fld_val = 8;
874
72
        }
875
447
      else
876
447
        {
877
447
          signed_fld_val = (signed int) fld_val;
878
447
          signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
879
447
          signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
880
447
        }
881
519
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
882
519
      break;
883
884
8.63k
    case tic6x_coding_scst:
885
8.63k
      operands_text[op_num] = true;
886
8.63k
      signed_fld_val = (signed int) fld_val;
887
8.63k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
888
8.63k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
889
8.63k
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
890
8.63k
      break;
891
892
9.48k
    case tic6x_coding_ucst_minus_one:
893
9.48k
      operands_text[op_num] = true;
894
9.48k
      snprintf (operands[op_num], 24, "%u", fld_val + 1);
895
9.48k
      break;
896
897
3.75k
    case tic6x_coding_pcrel:
898
4.09k
    case tic6x_coding_pcrel_half:
899
4.09k
      signed_fld_val = (signed int) fld_val;
900
4.09k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
901
4.09k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
902
4.09k
      if (fetch_packet_header_based
903
429
          && enc->coding_method == tic6x_coding_pcrel_half)
904
329
        signed_fld_val *= 2;
905
3.77k
      else
906
3.77k
        signed_fld_val *= 4;
907
4.09k
      operands_pcrel[op_num] = true;
908
4.09k
      operands_addresses[op_num] = fp_addr + signed_fld_val;
909
4.09k
      break;
910
911
141
    case tic6x_coding_regpair_msb:
912
141
      if (opc->operand_info[op_num].form != tic6x_operand_regpair)
913
0
        abort ();
914
141
      operands_text[op_num] = true;
915
141
      snprintf (operands[op_num], 24, "%c%u:%c%u",
916
141
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
917
141
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
918
141
      break;
919
920
5.55k
    case tic6x_coding_pcrel_half_unsigned:
921
5.55k
      operands_pcrel[op_num] = true;
922
5.55k
      operands_addresses[op_num] = fp_addr + 2 * fld_val;
923
5.55k
      break;
924
925
3.05k
    case tic6x_coding_reg_shift:
926
3.05k
      fld_val <<= 1;
927
      /* Fall through.  */
928
189k
    case tic6x_coding_reg:
929
189k
                  if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
930
8.16k
                    {
931
8.16k
          reg_base = 16;
932
8.16k
                    }
933
189k
      switch (opc->operand_info[op_num].form)
934
189k
        {
935
1.63k
        case tic6x_operand_treg:
936
1.63k
                      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.63k
          operands_text[op_num] = true;
942
1.63k
                      reg_side = t_val ? 'b' : 'a';
943
1.63k
          snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
944
1.63k
          break;
945
946
77.6k
        case tic6x_operand_reg:
947
77.6k
          operands_text[op_num] = true;
948
77.6k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
949
77.6k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
950
77.6k
          break;
951
952
212
        case tic6x_operand_reg_nors:
953
212
          operands_text[op_num] = true;
954
212
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
955
212
          snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
956
212
          break;
957
958
2
        case tic6x_operand_reg_bside:
959
2
          operands_text[op_num] = true;
960
2
          snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
961
2
          break;
962
963
186
        case tic6x_operand_reg_bside_nors:
964
186
          operands_text[op_num] = true;
965
186
          snprintf (operands[op_num], 24, "b%u", fld_val);
966
186
          break;
967
968
36.1k
        case tic6x_operand_xreg:
969
36.1k
          operands_text[op_num] = true;
970
36.1k
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
971
36.1k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
972
36.1k
          break;
973
974
33.5k
        case tic6x_operand_dreg:
975
33.5k
          operands_text[op_num] = true;
976
33.5k
                      reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
977
33.5k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
978
33.5k
          break;
979
980
14.7k
        case tic6x_operand_regpair:
981
14.7k
          operands_text[op_num] = true;
982
14.7k
          if (fld_val & 1)
983
3.00k
      operands_ok = false;
984
14.7k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
985
14.7k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
986
14.7k
                                reg_side, reg_base + fld_val + 1,
987
14.7k
        reg_side, reg_base + fld_val);
988
14.7k
          break;
989
990
1.16k
        case tic6x_operand_xregpair:
991
1.16k
          operands_text[op_num] = true;
992
1.16k
          if (fld_val & 1)
993
545
      operands_ok = false;
994
1.16k
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
995
1.16k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
996
1.16k
        reg_side, reg_base + fld_val + 1,
997
1.16k
        reg_side, reg_base + fld_val);
998
1.16k
          break;
999
1000
215
        case tic6x_operand_tregpair:
1001
215
                      if (!have_t)
1002
0
      {
1003
0
        printf ("opcode %x: operand tregpair but missing t field\n", opcode);
1004
0
        abort ();
1005
0
      }
1006
215
          operands_text[op_num] = true;
1007
215
          if (fld_val & 1)
1008
3
      operands_ok = false;
1009
215
                      reg_side = t_val ? 'b' : 'a';
1010
215
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1011
215
        reg_side, reg_base + fld_val + 1,
1012
215
        reg_side, reg_base + fld_val);
1013
215
          break;
1014
1015
4.52k
        case tic6x_operand_dregpair:
1016
4.52k
          operands_text[op_num] = true;
1017
4.52k
          if (fld_val & 1)
1018
761
      operands_ok = false;
1019
4.52k
                      reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1020
4.52k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1021
4.52k
        reg_side, reg_base + fld_val + 1,
1022
4.52k
        reg_side, reg_base + fld_val);
1023
4.52k
          break;
1024
1025
3
        case tic6x_operand_mem_deref:
1026
3
          operands_text[op_num] = true;
1027
3
                      reg_side = func_unit_side == 2 ? 'b' : 'a';
1028
3
          snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1029
3
          break;
1030
1031
17.3k
        case tic6x_operand_mem_short:
1032
19.4k
        case tic6x_operand_mem_ndw:
1033
19.4k
          mem_base_reg = fld_val;
1034
19.4k
          mem_base_reg_known = true;
1035
19.4k
          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
189k
        }
1042
189k
      break;
1043
1044
189k
                case tic6x_coding_reg_ptr:
1045
1.51k
      switch (opc->operand_info[op_num].form)
1046
1.51k
        {
1047
1.40k
        case tic6x_operand_mem_short:
1048
1.51k
        case tic6x_operand_mem_ndw:
1049
1.51k
                      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
1.51k
          mem_base_reg = 0x4 | fld_val;
1056
1.51k
          mem_base_reg_known = true;
1057
1.51k
          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
1.51k
        }
1064
1.51k
      break;
1065
1066
18.9k
    case tic6x_coding_areg:
1067
18.9k
      switch (opc->operand_info[op_num].form)
1068
18.9k
        {
1069
320
        case tic6x_operand_areg:
1070
320
          operands_text[op_num] = true;
1071
320
          snprintf (operands[op_num], 24, "b%u",
1072
320
        fld_val ? 15u : 14u);
1073
320
          break;
1074
1075
18.6k
        case tic6x_operand_mem_long:
1076
18.6k
          mem_base_reg = fld_val ? 15u : 14u;
1077
18.6k
          mem_base_reg_known_long = true;
1078
18.6k
          break;
1079
1080
0
        default:
1081
0
                      printf ("opcode %x: bad operand form\n", opcode);
1082
0
          abort ();
1083
18.9k
        }
1084
18.9k
      break;
1085
1086
18.9k
    case tic6x_coding_mem_offset_minus_one_noscale:
1087
413
    case tic6x_coding_mem_offset_minus_one:
1088
413
      fld_val += 1;
1089
      /* Fall through.  */
1090
2.53k
    case tic6x_coding_mem_offset_noscale:
1091
21.2k
    case tic6x_coding_mem_offset:
1092
21.2k
      mem_offset = fld_val;
1093
21.2k
      mem_offset_known = true;
1094
21.2k
      if (num_bits == 16)
1095
1.84k
        {
1096
1.84k
          mem_mode_known = true;
1097
1.84k
          mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1098
1.84k
          mem_scaled_known = true;
1099
1.84k
          mem_scaled = true;
1100
1.84k
          if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1101
337
      {
1102
337
        mem_base_reg_known = true;
1103
337
        mem_base_reg = 15;
1104
337
      }
1105
1.84k
          if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1106
1.76k
         || enc->coding_method == tic6x_coding_mem_offset_noscale )
1107
87
      mem_scaled = false;
1108
1.84k
        }
1109
21.2k
      break;
1110
1111
19.4k
    case tic6x_coding_mem_mode:
1112
19.4k
      mem_mode = fld_val;
1113
19.4k
      mem_mode_known = true;
1114
19.4k
      break;
1115
1116
2.03k
    case tic6x_coding_scaled:
1117
2.03k
      mem_scaled = fld_val;
1118
2.03k
      mem_scaled_known = true;
1119
2.03k
      break;
1120
1121
788
    case tic6x_coding_crlo:
1122
788
      crlo = fld_val;
1123
788
      crlo_known = true;
1124
788
      break;
1125
1126
788
    case tic6x_coding_crhi:
1127
788
      crhi = fld_val;
1128
788
      crhi_known = true;
1129
788
      break;
1130
1131
54
    case tic6x_coding_fstg:
1132
108
    case tic6x_coding_fcyc:
1133
108
      if (!prev_sploop_found)
1134
108
        {
1135
108
          bfd_vma search_fp_addr = fp_addr;
1136
108
          bfd_vma search_fp_offset = fp_offset;
1137
108
          bool search_fp_header_based
1138
108
      = fetch_packet_header_based;
1139
108
          tic6x_fetch_packet_header search_fp_header = header;
1140
108
          unsigned char search_fp[32];
1141
108
          unsigned int search_num_bits;
1142
108
          unsigned int search_opcode;
1143
108
          unsigned int sploop_ii = 0;
1144
108
          int i;
1145
1146
108
          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
28.4k
          for (i = 0; i < 48 * 8; i++)
1153
28.4k
      {
1154
        /* Find the previous instruction.  */
1155
28.4k
        if (search_fp_offset & 2)
1156
782
          search_fp_offset -= 2;
1157
27.6k
        else if (search_fp_offset >= 4)
1158
24.1k
          {
1159
24.1k
            if (search_fp_header_based
1160
1.11k
          && (search_fp_header.word_compact
1161
1.11k
              [(search_fp_offset >> 2) - 1]))
1162
644
        search_fp_offset -= 2;
1163
23.4k
            else
1164
23.4k
        search_fp_offset -= 4;
1165
24.1k
          }
1166
3.53k
        else
1167
3.53k
          {
1168
3.53k
            search_fp_addr -= 32;
1169
3.53k
            status = info->read_memory_func (search_fp_addr,
1170
3.53k
                     search_fp,
1171
3.53k
                     32, info);
1172
3.53k
            if (status)
1173
        /* No previous SPLOOP instruction.  */
1174
76
        break;
1175
3.45k
            search_fp_header_based
1176
3.45k
        = (tic6x_check_fetch_packet_header
1177
3.45k
           (search_fp, &search_fp_header, info));
1178
3.45k
            if (search_fp_header_based)
1179
158
        search_fp_offset
1180
158
          = search_fp_header.word_compact[6] ? 26 : 24;
1181
3.30k
            else
1182
3.30k
        search_fp_offset = 28;
1183
3.45k
          }
1184
1185
        /* Extract the previous instruction.  */
1186
28.3k
        if (search_fp_header_based)
1187
2.05k
          search_num_bits
1188
2.05k
            = (search_fp_header.word_compact[search_fp_offset
1189
2.05k
                     >> 2]
1190
2.05k
         ? 16
1191
2.05k
         : 32);
1192
26.3k
        else
1193
26.3k
          search_num_bits = 32;
1194
28.3k
        if (search_num_bits == 16)
1195
1.52k
          {
1196
1.52k
            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
1.52k
            else
1201
1.52k
        search_opcode
1202
1.52k
          = (tic6x_extract_16
1203
1.52k
             (search_fp + (search_fp_offset ^ 2), &header,
1204
1.52k
              info));
1205
1.52k
          }
1206
26.8k
        else
1207
26.8k
          search_opcode
1208
26.8k
            = tic6x_extract_32 (search_fp + search_fp_offset,
1209
26.8k
              info);
1210
1211
        /* Check whether it is an SPLOOP-family
1212
           instruction.  */
1213
28.3k
        if (search_num_bits == 32
1214
26.8k
            && ((search_opcode & 0x003ffffe) == 0x00038000
1215
26.8k
          || (search_opcode & 0x003ffffe) == 0x0003a000
1216
26.8k
          || ((search_opcode & 0x003ffffe)
1217
26.8k
              == 0x0003e000)))
1218
0
          {
1219
0
            prev_sploop_found = true;
1220
0
            sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1221
0
          }
1222
28.3k
        else if (search_num_bits == 16
1223
1.52k
           && (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
28.3k
        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
28.3k
        if (prev_sploop_found)
1251
2
          break;
1252
28.3k
      }
1253
108
        }
1254
108
      if (!prev_sploop_found)
1255
106
        {
1256
106
          operands_ok = false;
1257
106
          operands_text[op_num] = true;
1258
106
          break;
1259
106
        }
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
769
    case tic6x_coding_spmask:
1282
769
      if (fld_val == 0)
1283
24
        spmask_skip_operand = true;
1284
745
      else
1285
745
        {
1286
745
          char *p;
1287
745
          unsigned int i;
1288
1289
745
          operands_text[op_num] = true;
1290
745
          p = operands[op_num];
1291
6.70k
          for (i = 0; i < 8; i++)
1292
5.96k
      if (fld_val & (1 << i))
1293
2.32k
        {
1294
2.32k
          *p++ = "LSDM"[i/2];
1295
2.32k
          *p++ = '1' + (i & 1);
1296
2.32k
          *p++ = ',';
1297
2.32k
        }
1298
745
          p[-1] = 0;
1299
745
        }
1300
769
      break;
1301
1302
82.8k
    case tic6x_coding_fu:
1303
120k
    case tic6x_coding_data_fu:
1304
157k
    case tic6x_coding_xpath:
1305
159k
    case tic6x_coding_rside:
1306
      /* Don't relate to operands, so operand number is
1307
         meaningless.  */
1308
159k
      break;
1309
1310
0
    default:
1311
0
                  printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1312
0
      abort ();
1313
478k
    }
1314
1315
478k
        if (mem_base_reg_known_long && mem_offset_known_long)
1316
18.6k
    {
1317
18.6k
      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
18.6k
      operands_text[op_num] = true;
1323
18.6k
      snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1324
18.6k
          mem_offset * opc->operand_info[op_num].size);
1325
18.6k
    }
1326
1327
478k
        if (mem_base_reg_known && mem_offset_known && mem_mode_known
1328
23.2k
      && (mem_scaled_known
1329
19.4k
          || (opc->operand_info[op_num].form
1330
19.4k
        != tic6x_operand_mem_ndw)))
1331
21.2k
    {
1332
21.2k
      char side;
1333
21.2k
      char base[4];
1334
21.2k
      bool offset_is_reg;
1335
21.2k
      bool offset_scaled;
1336
21.2k
      char offset[4];
1337
21.2k
      char offsetp[6];
1338
1339
21.2k
      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
21.2k
      side = func_unit_side == 2 ? 'b' : 'a';
1346
21.2k
      snprintf (base, 4, "%c%u", side, mem_base_reg);
1347
1348
21.2k
      offset_is_reg = (mem_mode & 4) != 0;
1349
21.2k
      if (offset_is_reg)
1350
6.28k
        {
1351
1352
6.28k
          if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1353
328
      {
1354
328
        reg_base = 16;
1355
328
      }
1356
6.28k
          snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1357
6.28k
          if (opc->operand_info[op_num].form
1358
6.28k
        == tic6x_operand_mem_ndw)
1359
894
      offset_scaled = mem_scaled != 0;
1360
5.38k
          else
1361
5.38k
      offset_scaled = true;
1362
6.28k
        }
1363
14.9k
      else
1364
14.9k
        {
1365
14.9k
          if (opc->operand_info[op_num].form
1366
14.9k
        == tic6x_operand_mem_ndw)
1367
1.24k
      {
1368
1.24k
        offset_scaled = mem_scaled != 0;
1369
1.24k
        snprintf (offset, 4, "%u", mem_offset);
1370
1.24k
      }
1371
13.7k
          else
1372
13.7k
      {
1373
13.7k
        offset_scaled = false;
1374
13.7k
        snprintf (offset, 4, "%u",
1375
13.7k
            (mem_offset
1376
13.7k
             * opc->operand_info[op_num].size));
1377
13.7k
      }
1378
14.9k
        }
1379
1380
21.2k
      if (offset_scaled)
1381
5.92k
        snprintf (offsetp, 6, "[%s]", offset);
1382
15.3k
      else
1383
15.3k
        snprintf (offsetp, 6, "(%s)", offset);
1384
1385
21.2k
      operands_text[op_num] = true;
1386
21.2k
      switch (mem_mode & ~4u)
1387
21.2k
        {
1388
4.69k
        case 0:
1389
4.69k
          snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1390
4.69k
          break;
1391
1392
3.22k
        case 1:
1393
3.22k
          snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1394
3.22k
          break;
1395
1396
2.72k
        case 2:
1397
4.61k
        case 3:
1398
4.61k
          operands_ok = false;
1399
4.61k
          break;
1400
1401
2.05k
        case 8:
1402
2.05k
          snprintf (operands[op_num], 24, "*--%s%s", base,
1403
2.05k
        offsetp);
1404
2.05k
          break;
1405
1406
1.51k
        case 9:
1407
1.51k
          snprintf (operands[op_num], 24, "*++%s%s", base,
1408
1.51k
        offsetp);
1409
1.51k
          break;
1410
1411
2.12k
        case 10:
1412
2.12k
          snprintf (operands[op_num], 24, "*%s--%s", base,
1413
2.12k
        offsetp);
1414
2.12k
          break;
1415
1416
3.04k
        case 11:
1417
3.04k
          snprintf (operands[op_num], 24, "*%s++%s", base,
1418
3.04k
        offsetp);
1419
3.04k
          break;
1420
1421
0
        default:
1422
0
                      printf ("*** unknown mem_mode : %d \n", mem_mode);
1423
0
          abort ();
1424
21.2k
        }
1425
21.2k
    }
1426
1427
478k
        if (crlo_known && crhi_known)
1428
788
    {
1429
788
      tic6x_rw rw;
1430
788
      tic6x_ctrl_id crid;
1431
1432
788
      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
788
      rw = opc->operand_info[op_num].rw;
1439
788
      if (rw != tic6x_rw_read
1440
687
          && rw != tic6x_rw_write)
1441
0
        {
1442
0
          printf ("*** abort rw : %d\n", rw);
1443
0
          abort ();
1444
0
        }
1445
1446
22.3k
      for (crid = 0; crid < tic6x_ctrl_max; crid++)
1447
21.6k
        {
1448
21.6k
          if (crlo == tic6x_ctrl_table[crid].crlo
1449
782
        && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1450
70
        && (rw == tic6x_rw_read
1451
70
            ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1452
42
         || (tic6x_ctrl_table[crid].rw
1453
42
             == tic6x_rw_read_write))
1454
70
            : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1455
27
         || (tic6x_ctrl_table[crid].rw
1456
27
             == tic6x_rw_read_write))))
1457
66
      break;
1458
21.6k
        }
1459
788
      if (crid == tic6x_ctrl_max)
1460
722
        {
1461
722
          operands_text[op_num] = true;
1462
722
          operands_ok = false;
1463
722
        }
1464
66
      else
1465
66
        {
1466
66
          operands_text[op_num] = true;
1467
66
          snprintf (operands[op_num], 24, "%s",
1468
66
        tic6x_ctrl_table[crid].name);
1469
66
        }
1470
788
    }
1471
1472
478k
        if (operands_text[op_num] || operands_pcrel[op_num]
1473
221k
      || spmask_skip_operand)
1474
257k
    break;
1475
478k
      }
1476
          /* end for fld_num */
1477
1478
257k
    if (spmask_skip_operand)
1479
24
      {
1480
        /* SPMASK operands are only valid as the single operand
1481
     in the opcode table.  */
1482
24
        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
24
        num_operands = 0;
1488
24
        break;
1489
24
      }
1490
1491
    /* The operand must by now have been decoded.  */
1492
257k
    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
257k
        }
1498
      /* end for op_num */
1499
1500
113k
      if (!operands_ok)
1501
8.68k
  continue;
1502
1503
104k
      info->bytes_per_chunk = num_bits / 8;
1504
104k
      info->fprintf_func (info->stream, "%s", parallel);
1505
104k
      info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1506
104k
                          func_unit);
1507
349k
      for (op_num = 0; op_num < num_operands; op_num++)
1508
245k
  {
1509
245k
    info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1510
245k
    if (operands_pcrel[op_num])
1511
9.65k
      info->print_address_func (operands_addresses[op_num], info);
1512
235k
    else
1513
235k
      info->fprintf_func (info->stream, "%s", operands[op_num]);
1514
245k
  }
1515
104k
      if (fetch_packet_header_based && header.prot)
1516
2.54k
  info->fprintf_func (info->stream, " || nop 5");
1517
1518
104k
      return num_bits / 8;
1519
113k
    }
1520
1521
58.9k
  info->bytes_per_chunk = num_bits / 8;
1522
58.9k
  info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1523
58.9k
          (int) num_bits / 4, opcode);
1524
58.9k
  return num_bits / 8;
1525
163k
}