Coverage Report

Created: 2026-03-10 08:46

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