Coverage Report

Created: 2026-07-25 10:20

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