Coverage Report

Created: 2026-04-04 08:16

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
6.10M
{
116
6.10M
  unsigned int f;
117
118
21.7M
  for (f = 0; f < fmt->num_fields; f++)
119
21.6M
    if (fmt->fields[f].field_id == field)
120
6.07M
      return &fmt->fields[f];
121
122
33.2k
  return NULL;
123
6.10M
}
124
125
/* Extract the field width.  */
126
127
static unsigned int
128
tic6x_field_width (const tic6x_insn_field *field)
129
19.6k
{
130
19.6k
  unsigned int i;
131
19.6k
  unsigned int width = 0;
132
133
19.6k
  if (!field->num_bitfields)
134
0
    return field->bitfields[0].width;
135
136
39.7k
  for (i = 0 ; i < field->num_bitfields ; i++)
137
20.0k
    width += field->bitfields[i].width;
138
139
19.6k
  return width;
140
19.6k
}
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
6.07M
{
147
6.07M
  unsigned int i;
148
6.07M
  unsigned int val = 0;
149
150
6.07M
  if (!field->num_bitfields)
151
0
    return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1);
152
153
12.1M
  for (i = 0 ; i < field->num_bitfields ; i++)
154
6.07M
    val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1))
155
6.07M
      << field->bitfields[i].pos;
156
157
6.07M
  return val;
158
6.07M
}
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
296k
{
165
296k
  if (info->endian == BFD_ENDIAN_LITTLE)
166
90
    return p[0] | (p[1] << 8) | (p[2] << 16) | ((unsigned) p[3] << 24);
167
296k
  else
168
296k
    return p[3] | (p[2] << 8) | (p[1] << 16) | ((unsigned) p[0] << 24);
169
296k
}
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
6.23k
{
177
6.23k
  unsigned int op16;
178
179
6.23k
  if (info->endian == BFD_ENDIAN_LITTLE)
180
30
    op16 = (p[0]) | (p[1] << 8);
181
6.20k
  else
182
6.20k
    op16 = (p[1]) | (p[0] << 8);
183
6.23k
  op16 |= (header->sat << TIC6X_COMPACT_SAT_POS);
184
6.23k
  op16 |= (header->br << TIC6X_COMPACT_BR_POS);
185
6.23k
  op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS);
186
6.23k
  return op16;
187
6.23k
}
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
115k
{
197
115k
  int i;
198
199
115k
  header->header = tic6x_extract_32 (fp + 28, info);
200
201
115k
  if ((header->header & 0xf0000000) != 0xe0000000)
202
106k
    {
203
106k
      header->prot = 0;
204
106k
      header->rs = 0;
205
106k
      header->dsz = 0;
206
106k
      header->br = 0;
207
106k
      header->sat = 0;
208
850k
      for (i = 0; i < 7; i++)
209
744k
  header->word_compact[i] = false;
210
1.59M
      for (i = 0; i < 14; i++)
211
1.48M
  header->p_bits[i] = false;
212
106k
      return false;
213
106k
    }
214
215
70.2k
  for (i = 0; i < 7; i++)
216
61.4k
    header->word_compact[i]
217
61.4k
      = (header->header & (1u << (21 + i))) != 0;
218
219
8.78k
  header->prot = (header->header & (1u << 20)) != 0;
220
8.78k
  header->rs = (header->header & (1u << 19)) != 0;
221
8.78k
  header->dsz = (header->header >> 16) & 0x7;
222
8.78k
  header->br = (header->header & (1u << 15)) != 0;
223
8.78k
  header->sat = (header->header & (1u << 14)) != 0;
224
225
131k
  for (i = 0; i < 14; i++)
226
122k
    header->p_bits[i] = (header->header & (1u << i)) != 0;
227
228
8.78k
  return true;
229
115k
}
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
104k
{
238
104k
  int status;
239
104k
  bfd_vma fp_addr;
240
104k
  bfd_vma fp_offset;
241
104k
  unsigned char fp[32];
242
104k
  unsigned int opcode;
243
104k
  tic6x_opcode_id opcode_id;
244
104k
  bool fetch_packet_header_based;
245
104k
  tic6x_fetch_packet_header header;
246
104k
  unsigned int num_bits;
247
104k
  bool bad_offset = false;
248
249
104k
  fp_offset = addr & 0x1f;
250
104k
  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
104k
  info->stop_vma = 0;
254
104k
  status = info->read_memory_func (fp_addr, fp, 32, info);
255
104k
  if (status)
256
217
    {
257
217
      info->memory_error_func (status, addr, info);
258
217
      return -1;
259
217
    }
260
261
103k
  fetch_packet_header_based
262
103k
    = tic6x_check_fetch_packet_header (fp, &header, info);
263
103k
  if (fetch_packet_header_based)
264
8.38k
    {
265
8.38k
      if (fp_offset & 0x1)
266
1
  bad_offset = true;
267
8.38k
      if ((fp_offset & 0x3) && (fp_offset >= 28
268
2.86k
        || !header.word_compact[fp_offset >> 2]))
269
2
  bad_offset = true;
270
8.38k
      if (fp_offset == 28)
271
705
  {
272
705
    info->bytes_per_chunk = 4;
273
705
    info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
274
705
            header.header);
275
705
    return 4;
276
705
  }
277
7.67k
      num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
278
7.67k
    }
279
95.4k
  else
280
95.4k
    {
281
95.4k
      num_bits = 32;
282
95.4k
      if (fp_offset & 0x3)
283
3
  bad_offset = true;
284
95.4k
    }
285
286
103k
  if (bad_offset)
287
5
    {
288
5
      info->bytes_per_chunk = 1;
289
5
      info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
290
5
      return 1;
291
5
    }
292
293
103k
  if (num_bits == 16)
294
5.76k
    {
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
5.76k
      if (info->endian == BFD_ENDIAN_LITTLE)
301
30
  opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
302
5.73k
      else
303
5.73k
  opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
304
5.76k
    }
305
97.3k
  else
306
97.3k
    opcode = tic6x_extract_32 (fp + fp_offset, info);
307
308
41.6M
  for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
309
41.6M
    {
310
41.6M
      const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
311
41.6M
      const tic6x_insn_format *const fmt
312
41.6M
  = &tic6x_insn_format_table[opc->format];
313
41.6M
      const tic6x_insn_field *creg_field;
314
41.6M
      bool p_bit;
315
41.6M
      const char *parallel;
316
41.6M
      const char *cond = "";
317
41.6M
      const char *func_unit;
318
41.6M
      char func_unit_buf[8];
319
41.6M
      unsigned int func_unit_side = 0;
320
41.6M
      unsigned int func_unit_data_side = 0;
321
41.6M
      unsigned int func_unit_cross = 0;
322
41.6M
      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
41.6M
      char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
327
41.6M
      bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
328
41.6M
      bool operands_text[TIC6X_MAX_OPERANDS] = { false };
329
41.6M
      bool operands_pcrel[TIC6X_MAX_OPERANDS] = { false };
330
41.6M
      unsigned int fix;
331
41.6M
      unsigned int num_operands;
332
41.6M
      unsigned int op_num;
333
41.6M
      bool fixed_ok;
334
41.6M
      bool operands_ok;
335
41.6M
      bool have_t = false;
336
337
41.6M
      if (opc->flags & TIC6X_FLAG_MACRO)
338
4.42M
  continue;
339
37.1M
      if (fmt->num_bits != num_bits)
340
12.3M
  continue;
341
24.8M
      if ((opcode & fmt->mask) != fmt->cst_bits)
342
22.8M
  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
1.95M
      creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
349
1.95M
      if (creg_field)
350
1.92M
  {
351
1.92M
    const tic6x_insn_field *z_field;
352
1.92M
    unsigned int creg_value, z_value;
353
1.92M
    static const char *const conds[8][2] =
354
1.92M
      {
355
1.92M
        { "", NULL },
356
1.92M
        { "[b0] ", "[!b0] " },
357
1.92M
        { "[b1] ", "[!b1] " },
358
1.92M
        { "[b2] ", "[!b2] " },
359
1.92M
        { "[a1] ", "[!a1] " },
360
1.92M
        { "[a2] ", "[!a2] " },
361
1.92M
        { "[a0] ", "[!a0] " },
362
1.92M
        { NULL, NULL }
363
1.92M
      };
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
1.92M
    z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
369
1.92M
    if (!z_field)
370
0
      {
371
0
        printf ("*** opcode %x: missing z field", opcode);
372
0
        abort ();
373
0
      }
374
375
1.92M
    creg_value = tic6x_field_bits (opcode, creg_field);
376
1.92M
    z_value = tic6x_field_bits (opcode, z_field);
377
1.92M
    cond = conds[creg_value][z_value];
378
1.92M
    if (cond == NULL)
379
363k
      continue;
380
1.92M
  }
381
382
1.59M
      if (opc->flags & TIC6X_FLAG_INSN16_SPRED)
383
791
  {
384
791
    const tic6x_insn_field *cc_field;
385
791
          unsigned int s_value = 0;
386
791
          unsigned int z_value = 0;
387
791
          bool cond_known = false;
388
791
          static const char *const conds[2][2] =
389
791
            {
390
791
              { "[a0] ", "[!a0] " },
391
791
              { "[b0] ", "[!b0] " }
392
791
            };
393
394
791
          cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc);
395
396
791
          if (cc_field)
397
49
      {
398
49
        unsigned int cc_value;
399
400
49
        cc_value = tic6x_field_bits (opcode, cc_field);
401
49
        s_value = (cc_value & 0x2) >> 1;
402
49
        z_value = (cc_value & 0x1);
403
49
        cond_known = true;
404
49
      }
405
742
    else
406
742
      {
407
742
        const tic6x_insn_field *z_field;
408
742
        const tic6x_insn_field *s_field;
409
410
742
        s_field = tic6x_field_from_fmt (fmt, tic6x_field_s);
411
412
742
        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
742
        s_value = tic6x_field_bits (opcode, s_field);
419
742
        z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
420
742
        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
742
        z_value = tic6x_field_bits (opcode, z_field);
427
742
        cond_known = true;
428
742
      }
429
430
791
          if (!cond_known)
431
0
      {
432
0
        printf ("opcode %x: unspecified ompact insn predicate\n", opcode);
433
0
        abort ();
434
0
      }
435
791
          cond = conds[s_value][z_value];
436
791
  }
437
438
      /* All fixed fields must have matching values; all fields with
439
   restricted ranges must have values within those ranges.  */
440
1.59M
      fixed_ok = true;
441
1.70M
      for (fix = 0; fix < opc->num_fixed_fields; fix++)
442
1.63M
  {
443
1.63M
    unsigned int field_bits;
444
1.63M
    const tic6x_insn_field *const field
445
1.63M
      = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
446
447
1.63M
    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
1.63M
    field_bits = tic6x_field_bits (opcode, field);
455
1.63M
    if (field_bits < opc->fixed_fields[fix].min_val
456
527k
        || field_bits > opc->fixed_fields[fix].max_val)
457
1.52M
      {
458
1.52M
        fixed_ok = false;
459
1.52M
        break;
460
1.52M
      }
461
1.63M
  }
462
1.59M
      if (!fixed_ok)
463
1.52M
  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
70.1k
      if (num_bits == 16 && (fp_offset & 0x2) == 2)
473
2.41k
  {
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.41k
    p_bit = header.p_bits[(fp_offset >> 2) << 1];
479
2.41k
  }
480
67.7k
      else if (fp_offset >= 4)
481
58.5k
  {
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
58.5k
    if (fetch_packet_header_based
486
2.84k
        && header.word_compact[(fp_offset >> 2) - 1])
487
1.75k
      p_bit = header.p_bits[(fp_offset >> 1) - 1];
488
56.8k
    else
489
56.8k
      {
490
56.8k
        unsigned int prev_opcode
491
56.8k
    = tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
492
56.8k
        p_bit = (prev_opcode & 0x1) != 0;
493
56.8k
      }
494
58.5k
  }
495
9.14k
      else
496
9.14k
  {
497
    /* Find the last instruction of the previous fetch
498
       packet.  */
499
9.14k
    unsigned char fp_prev[32];
500
501
9.14k
    status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
502
9.14k
    if (status)
503
      /* No previous instruction to be parallel with.  */
504
258
      p_bit = false;
505
8.88k
    else
506
8.88k
      {
507
8.88k
        bool prev_header_based;
508
8.88k
        tic6x_fetch_packet_header prev_header;
509
510
8.88k
        prev_header_based
511
8.88k
    = tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
512
8.88k
        if (prev_header_based)
513
354
    {
514
354
      if (prev_header.word_compact[6])
515
179
        p_bit = prev_header.p_bits[13];
516
175
      else
517
175
        {
518
175
          unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 24,
519
175
                   info);
520
175
          p_bit = (prev_opcode & 0x1) != 0;
521
175
        }
522
354
    }
523
8.52k
        else
524
8.52k
    {
525
8.52k
      unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
526
8.52k
                     info);
527
8.52k
      p_bit = (prev_opcode & 0x1) != 0;
528
8.52k
    }
529
8.88k
      }
530
9.14k
  }
531
70.1k
      parallel = p_bit ? "|| " : "";
532
533
70.1k
      if (opc->func_unit == tic6x_func_unit_nfu)
534
7.95k
  func_unit = "";
535
62.1k
      else
536
62.1k
  {
537
62.1k
    unsigned int fld_num;
538
62.1k
    char func_unit_char;
539
62.1k
    const char *data_str;
540
62.1k
    bool have_areg = false;
541
62.1k
    bool have_cross = false;
542
543
62.1k
    func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
544
62.1k
    func_unit_cross = 0;
545
62.1k
    func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
546
547
348k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
548
286k
      {
549
286k
        const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
550
286k
        const tic6x_insn_field *field;
551
286k
        unsigned int fld_val;
552
553
286k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
554
555
286k
        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
286k
        fld_val = tic6x_field_bits (opcode, field);
563
564
286k
        switch (enc->coding_method)
565
286k
    {
566
49.4k
    case tic6x_coding_fu:
567
      /* The side must be specified exactly once.  */
568
49.4k
      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
49.4k
      func_unit_side = (fld_val ? 2 : 1);
575
49.4k
      break;
576
577
22.9k
    case tic6x_coding_data_fu:
578
      /* The data side must be specified exactly once.  */
579
22.9k
      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
22.9k
      func_unit_data_side = (fld_val ? 2 : 1);
586
22.9k
      break;
587
588
24.5k
    case tic6x_coding_xpath:
589
      /* Cross path use must be specified exactly
590
         once.  */
591
24.5k
      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
24.5k
      have_cross = true;
598
24.5k
      func_unit_cross = fld_val;
599
24.5k
      break;
600
601
770
                case tic6x_coding_rside:
602
                  /* If the format has a t field, use it for src/dst register side.  */
603
770
                  have_t = true;
604
770
                  t_val = fld_val;
605
770
                  func_unit_data_side = (t_val ? 2 : 1);
606
770
                  break;
607
608
11.8k
    case tic6x_coding_areg:
609
11.8k
      have_areg = true;
610
11.8k
      break;
611
612
176k
    default:
613
      /* Don't relate to functional units.  */
614
176k
      break;
615
286k
    }
616
286k
      }
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
62.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
62.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
62.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
62.1k
    if (have_areg && !func_unit_data_side)
650
249
      {
651
249
        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
249
        func_unit_cross = func_unit_side == 1;
657
249
      }
658
659
62.1k
    switch (opc->func_unit)
660
62.1k
      {
661
25.0k
      case tic6x_func_unit_d:
662
25.0k
        func_unit_char = 'D';
663
25.0k
        break;
664
665
4.76k
      case tic6x_func_unit_l:
666
4.76k
        func_unit_char = 'L';
667
4.76k
        break;
668
669
15.6k
      case tic6x_func_unit_m:
670
15.6k
        func_unit_char = 'M';
671
15.6k
        break;
672
673
16.6k
      case tic6x_func_unit_s:
674
16.6k
        func_unit_char = 'S';
675
16.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
62.1k
      }
681
682
62.1k
    switch (func_unit_data_side)
683
62.1k
      {
684
38.4k
      case 0:
685
38.4k
        data_str = "";
686
38.4k
        break;
687
688
12.0k
      case 1:
689
12.0k
        data_str = "T1";
690
12.0k
        break;
691
692
11.7k
      case 2:
693
11.7k
        data_str = "T2";
694
11.7k
        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
62.1k
      }
701
702
62.1k
    if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
703
12
        func_unit_cross = 1;
704
705
62.1k
    snprintf (func_unit_buf, sizeof func_unit_buf, " .%c%u%s%s",
706
62.1k
        func_unit_char, func_unit_side,
707
62.1k
        (func_unit_cross ? "X" : ""), data_str);
708
62.1k
    func_unit = func_unit_buf;
709
62.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
70.1k
      operands_ok = true;
715
70.1k
      num_operands = opc->num_operands;
716
233k
      for (op_num = 0; op_num < num_operands; op_num++)
717
163k
  {
718
163k
    unsigned int fld_num;
719
163k
    unsigned int mem_base_reg = 0;
720
163k
    bool mem_base_reg_known = false;
721
163k
    bool mem_base_reg_known_long = false;
722
163k
    unsigned int mem_offset = 0;
723
163k
    bool mem_offset_known = false;
724
163k
    bool mem_offset_known_long = false;
725
163k
    unsigned int mem_mode = 0;
726
163k
    bool mem_mode_known = false;
727
163k
    unsigned int mem_scaled = 0;
728
163k
    bool mem_scaled_known = false;
729
163k
    unsigned int crlo = 0;
730
163k
    bool crlo_known = false;
731
163k
    unsigned int crhi = 0;
732
163k
    bool crhi_known = false;
733
163k
    bool spmask_skip_operand = false;
734
163k
    unsigned int fcyc_bits = 0;
735
163k
    bool prev_sploop_found = false;
736
737
163k
    switch (opc->operand_info[op_num].form)
738
163k
      {
739
21
      case tic6x_operand_b15reg:
740
        /* Fully determined by the functional unit.  */
741
21
        operands_text[op_num] = true;
742
21
        snprintf (operands[op_num], 24, "b15");
743
21
        continue;
744
745
31
      case tic6x_operand_zreg:
746
        /* Fully determined by the functional unit.  */
747
31
        operands_text[op_num] = true;
748
31
        snprintf (operands[op_num], 24, "%c0",
749
31
      (func_unit_side == 2 ? 'b' : 'a'));
750
31
        continue;
751
752
915
      case tic6x_operand_retreg:
753
        /* Fully determined by the functional unit.  */
754
915
        operands_text[op_num] = true;
755
915
        snprintf (operands[op_num], 24, "%c3",
756
915
      (func_unit_side == 2 ? 'b' : 'a'));
757
915
        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
1
      case tic6x_operand_hw_const_0:
780
1
        operands_text[op_num] = true;
781
1
        snprintf (operands[op_num], 24, "0");
782
1
        continue;
783
784
5
      case tic6x_operand_hw_const_1:
785
5
        operands_text[op_num] = true;
786
5
        snprintf (operands[op_num], 24, "1");
787
5
        continue;
788
789
595
      case tic6x_operand_hw_const_5:
790
595
        operands_text[op_num] = true;
791
595
        snprintf (operands[op_num], 24, "5");
792
595
        continue;
793
794
2.48k
      case tic6x_operand_hw_const_16:
795
2.48k
        operands_text[op_num] = true;
796
2.48k
        snprintf (operands[op_num], 24, "16");
797
2.48k
        continue;
798
799
2
      case tic6x_operand_hw_const_24:
800
2
        operands_text[op_num] = true;
801
2
        snprintf (operands[op_num], 24, "24");
802
2
        continue;
803
804
31
      case tic6x_operand_hw_const_31:
805
31
        operands_text[op_num] = true;
806
31
        snprintf (operands[op_num], 24, "31");
807
31
        continue;
808
809
158k
      default:
810
158k
        break;
811
163k
      }
812
813
600k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
814
600k
      {
815
600k
        const tic6x_coding_field *const enc
816
600k
    = &opc->variable_fields[fld_num];
817
600k
        const tic6x_insn_field *field;
818
600k
        unsigned int fld_val;
819
600k
        unsigned int reg_base = 0;
820
600k
        signed int signed_fld_val;
821
600k
              char reg_side = '?';
822
823
600k
        if (enc->operand_num != op_num)
824
306k
    continue;
825
293k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
826
293k
        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
293k
              fld_val = tic6x_field_bits (opcode, field);
832
293k
        switch (enc->coding_method)
833
293k
    {
834
58
                case tic6x_coding_cst_s3i:
835
58
                  (fld_val == 0x00) && (fld_val = 0x10);
836
58
                  (fld_val == 0x07) && (fld_val = 0x08);
837
                  /* Fall through.  */
838
7.07k
    case tic6x_coding_ucst:
839
9.69k
    case tic6x_coding_ulcst_dpr_byte:
840
13.7k
    case tic6x_coding_ulcst_dpr_half:
841
18.9k
    case tic6x_coding_ulcst_dpr_word:
842
18.9k
    case tic6x_coding_lcst_low16:
843
18.9k
      switch (opc->operand_info[op_num].form)
844
18.9k
        {
845
6.92k
        case tic6x_operand_asm_const:
846
7.32k
        case tic6x_operand_link_const:
847
7.32k
          operands_text[op_num] = true;
848
7.32k
          snprintf (operands[op_num], 24, "%u", fld_val);
849
7.32k
          break;
850
851
11.6k
        case tic6x_operand_mem_long:
852
11.6k
          mem_offset = fld_val;
853
11.6k
          mem_offset_known_long = true;
854
11.6k
          break;
855
856
0
        default:
857
0
                      printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
858
0
          abort ();
859
18.9k
        }
860
18.9k
      break;
861
862
18.9k
    case tic6x_coding_lcst_high16:
863
1.54k
      operands_text[op_num] = true;
864
1.54k
      snprintf (operands[op_num], 24, "%u", fld_val << 16);
865
1.54k
      break;
866
867
217
                case tic6x_coding_scst_l3i:
868
217
      operands_text[op_num] = true;
869
217
                  if (fld_val == 0)
870
39
        {
871
39
          signed_fld_val = 8;
872
39
        }
873
178
      else
874
178
        {
875
178
          signed_fld_val = (signed int) fld_val;
876
178
          signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
877
178
          signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
878
178
        }
879
217
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
880
217
      break;
881
882
5.71k
    case tic6x_coding_scst:
883
5.71k
      operands_text[op_num] = true;
884
5.71k
      signed_fld_val = (signed int) fld_val;
885
5.71k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
886
5.71k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
887
5.71k
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
888
5.71k
      break;
889
890
7.14k
    case tic6x_coding_ucst_minus_one:
891
7.14k
      operands_text[op_num] = true;
892
7.14k
      snprintf (operands[op_num], 24, "%u", fld_val + 1);
893
7.14k
      break;
894
895
3.72k
    case tic6x_coding_pcrel:
896
3.94k
    case tic6x_coding_pcrel_half:
897
3.94k
      signed_fld_val = (signed int) fld_val;
898
3.94k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
899
3.94k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
900
3.94k
      if (fetch_packet_header_based
901
234
          && enc->coding_method == tic6x_coding_pcrel_half)
902
193
        signed_fld_val *= 2;
903
3.75k
      else
904
3.75k
        signed_fld_val *= 4;
905
3.94k
      operands_pcrel[op_num] = true;
906
3.94k
      operands_addresses[op_num] = fp_addr + signed_fld_val;
907
3.94k
      break;
908
909
125
    case tic6x_coding_regpair_msb:
910
125
      if (opc->operand_info[op_num].form != tic6x_operand_regpair)
911
0
        abort ();
912
125
      operands_text[op_num] = true;
913
125
      snprintf (operands[op_num], 24, "%c%u:%c%u",
914
125
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
915
125
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
916
125
      break;
917
918
595
    case tic6x_coding_pcrel_half_unsigned:
919
595
      operands_pcrel[op_num] = true;
920
595
      operands_addresses[op_num] = fp_addr + 2 * fld_val;
921
595
      break;
922
923
1.88k
    case tic6x_coding_reg_shift:
924
1.88k
      fld_val <<= 1;
925
      /* Fall through.  */
926
117k
    case tic6x_coding_reg:
927
117k
                  if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
928
2.99k
                    {
929
2.99k
          reg_base = 16;
930
2.99k
                    }
931
117k
      switch (opc->operand_info[op_num].form)
932
117k
        {
933
490
        case tic6x_operand_treg:
934
490
                      if (!have_t)
935
0
      {
936
0
        printf ("opcode %x: operand treg but missing t field\n", opcode);
937
0
        abort ();
938
0
      }
939
490
          operands_text[op_num] = true;
940
490
                      reg_side = t_val ? 'b' : 'a';
941
490
          snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
942
490
          break;
943
944
49.1k
        case tic6x_operand_reg:
945
49.1k
          operands_text[op_num] = true;
946
49.1k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
947
49.1k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
948
49.1k
          break;
949
950
62
        case tic6x_operand_reg_nors:
951
62
          operands_text[op_num] = true;
952
62
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
953
62
          snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
954
62
          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
53
        case tic6x_operand_reg_bside_nors:
962
53
          operands_text[op_num] = true;
963
53
          snprintf (operands[op_num], 24, "b%u", fld_val);
964
53
          break;
965
966
23.8k
        case tic6x_operand_xreg:
967
23.8k
          operands_text[op_num] = true;
968
23.8k
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
969
23.8k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
970
23.8k
          break;
971
972
20.5k
        case tic6x_operand_dreg:
973
20.5k
          operands_text[op_num] = true;
974
20.5k
                      reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
975
20.5k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
976
20.5k
          break;
977
978
9.10k
        case tic6x_operand_regpair:
979
9.10k
          operands_text[op_num] = true;
980
9.10k
          if (fld_val & 1)
981
1.46k
      operands_ok = false;
982
9.10k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
983
9.10k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
984
9.10k
                                reg_side, reg_base + fld_val + 1,
985
9.10k
        reg_side, reg_base + fld_val);
986
9.10k
          break;
987
988
642
        case tic6x_operand_xregpair:
989
642
          operands_text[op_num] = true;
990
642
          if (fld_val & 1)
991
201
      operands_ok = false;
992
642
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
993
642
          snprintf (operands[op_num], 24, "%c%u:%c%u",
994
642
        reg_side, reg_base + fld_val + 1,
995
642
        reg_side, reg_base + fld_val);
996
642
          break;
997
998
280
        case tic6x_operand_tregpair:
999
280
                      if (!have_t)
1000
0
      {
1001
0
        printf ("opcode %x: operand tregpair but missing t field\n", opcode);
1002
0
        abort ();
1003
0
      }
1004
280
          operands_text[op_num] = true;
1005
280
          if (fld_val & 1)
1006
7
      operands_ok = false;
1007
280
                      reg_side = t_val ? 'b' : 'a';
1008
280
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1009
280
        reg_side, reg_base + fld_val + 1,
1010
280
        reg_side, reg_base + fld_val);
1011
280
          break;
1012
1013
2.48k
        case tic6x_operand_dregpair:
1014
2.48k
          operands_text[op_num] = true;
1015
2.48k
          if (fld_val & 1)
1016
276
      operands_ok = false;
1017
2.48k
                      reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1018
2.48k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1019
2.48k
        reg_side, reg_base + fld_val + 1,
1020
2.48k
        reg_side, reg_base + fld_val);
1021
2.48k
          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
9.93k
        case tic6x_operand_mem_short:
1030
11.3k
        case tic6x_operand_mem_ndw:
1031
11.3k
          mem_base_reg = fld_val;
1032
11.3k
          mem_base_reg_known = true;
1033
11.3k
          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
117k
        }
1040
117k
      break;
1041
1042
117k
                case tic6x_coding_reg_ptr:
1043
715
      switch (opc->operand_info[op_num].form)
1044
715
        {
1045
618
        case tic6x_operand_mem_short:
1046
715
        case tic6x_operand_mem_ndw:
1047
715
                      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
715
          mem_base_reg = 0x4 | fld_val;
1054
715
          mem_base_reg_known = true;
1055
715
          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
715
        }
1062
715
      break;
1063
1064
11.8k
    case tic6x_coding_areg:
1065
11.8k
      switch (opc->operand_info[op_num].form)
1066
11.8k
        {
1067
249
        case tic6x_operand_areg:
1068
249
          operands_text[op_num] = true;
1069
249
          snprintf (operands[op_num], 24, "b%u",
1070
249
        fld_val ? 15u : 14u);
1071
249
          break;
1072
1073
11.6k
        case tic6x_operand_mem_long:
1074
11.6k
          mem_base_reg = fld_val ? 15u : 14u;
1075
11.6k
          mem_base_reg_known_long = true;
1076
11.6k
          break;
1077
1078
0
        default:
1079
0
                      printf ("opcode %x: bad operand form\n", opcode);
1080
0
          abort ();
1081
11.8k
        }
1082
11.8k
      break;
1083
1084
11.8k
    case tic6x_coding_mem_offset_minus_one_noscale:
1085
188
    case tic6x_coding_mem_offset_minus_one:
1086
188
      fld_val += 1;
1087
      /* Fall through.  */
1088
1.65k
    case tic6x_coding_mem_offset_noscale:
1089
12.0k
    case tic6x_coding_mem_offset:
1090
12.0k
      mem_offset = fld_val;
1091
12.0k
      mem_offset_known = true;
1092
12.0k
      if (num_bits == 16)
1093
770
        {
1094
770
          mem_mode_known = true;
1095
770
          mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1096
770
          mem_scaled_known = true;
1097
770
          mem_scaled = true;
1098
770
          if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1099
55
      {
1100
55
        mem_base_reg_known = true;
1101
55
        mem_base_reg = 15;
1102
55
      }
1103
770
          if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1104
692
         || enc->coding_method == tic6x_coding_mem_offset_noscale )
1105
78
      mem_scaled = false;
1106
770
        }
1107
12.0k
      break;
1108
1109
11.3k
    case tic6x_coding_mem_mode:
1110
11.3k
      mem_mode = fld_val;
1111
11.3k
      mem_mode_known = true;
1112
11.3k
      break;
1113
1114
1.39k
    case tic6x_coding_scaled:
1115
1.39k
      mem_scaled = fld_val;
1116
1.39k
      mem_scaled_known = true;
1117
1.39k
      break;
1118
1119
1.04k
    case tic6x_coding_crlo:
1120
1.04k
      crlo = fld_val;
1121
1.04k
      crlo_known = true;
1122
1.04k
      break;
1123
1124
1.04k
    case tic6x_coding_crhi:
1125
1.04k
      crhi = fld_val;
1126
1.04k
      crhi_known = true;
1127
1.04k
      break;
1128
1129
39
    case tic6x_coding_fstg:
1130
78
    case tic6x_coding_fcyc:
1131
78
      if (!prev_sploop_found)
1132
78
        {
1133
78
          bfd_vma search_fp_addr = fp_addr;
1134
78
          bfd_vma search_fp_offset = fp_offset;
1135
78
          bool search_fp_header_based
1136
78
      = fetch_packet_header_based;
1137
78
          tic6x_fetch_packet_header search_fp_header = header;
1138
78
          unsigned char search_fp[32];
1139
78
          unsigned int search_num_bits;
1140
78
          unsigned int search_opcode;
1141
78
          unsigned int sploop_ii = 0;
1142
78
          int i;
1143
1144
78
          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
19.5k
          for (i = 0; i < 48 * 8; i++)
1151
19.5k
      {
1152
        /* Find the previous instruction.  */
1153
19.5k
        if (search_fp_offset & 2)
1154
254
          search_fp_offset -= 2;
1155
19.3k
        else if (search_fp_offset >= 4)
1156
16.8k
          {
1157
16.8k
            if (search_fp_header_based
1158
410
          && (search_fp_header.word_compact
1159
410
              [(search_fp_offset >> 2) - 1]))
1160
192
        search_fp_offset -= 2;
1161
16.6k
            else
1162
16.6k
        search_fp_offset -= 4;
1163
16.8k
          }
1164
2.46k
        else
1165
2.46k
          {
1166
2.46k
            search_fp_addr -= 32;
1167
2.46k
            status = info->read_memory_func (search_fp_addr,
1168
2.46k
                     search_fp,
1169
2.46k
                     32, info);
1170
2.46k
            if (status)
1171
        /* No previous SPLOOP instruction.  */
1172
58
        break;
1173
2.40k
            search_fp_header_based
1174
2.40k
        = (tic6x_check_fetch_packet_header
1175
2.40k
           (search_fp, &search_fp_header, info));
1176
2.40k
            if (search_fp_header_based)
1177
50
        search_fp_offset
1178
50
          = search_fp_header.word_compact[6] ? 26 : 24;
1179
2.35k
            else
1180
2.35k
        search_fp_offset = 28;
1181
2.40k
          }
1182
1183
        /* Extract the previous instruction.  */
1184
19.5k
        if (search_fp_header_based)
1185
714
          search_num_bits
1186
714
            = (search_fp_header.word_compact[search_fp_offset
1187
714
                     >> 2]
1188
714
         ? 16
1189
714
         : 32);
1190
18.8k
        else
1191
18.8k
          search_num_bits = 32;
1192
19.5k
        if (search_num_bits == 16)
1193
470
          {
1194
470
            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
470
            else
1199
470
        search_opcode
1200
470
          = (tic6x_extract_16
1201
470
             (search_fp + (search_fp_offset ^ 2), &header,
1202
470
              info));
1203
470
          }
1204
19.0k
        else
1205
19.0k
          search_opcode
1206
19.0k
            = tic6x_extract_32 (search_fp + search_fp_offset,
1207
19.0k
              info);
1208
1209
        /* Check whether it is an SPLOOP-family
1210
           instruction.  */
1211
19.5k
        if (search_num_bits == 32
1212
19.0k
            && ((search_opcode & 0x003ffffe) == 0x00038000
1213
19.0k
          || (search_opcode & 0x003ffffe) == 0x0003a000
1214
19.0k
          || ((search_opcode & 0x003ffffe)
1215
19.0k
              == 0x0003e000)))
1216
0
          {
1217
0
            prev_sploop_found = true;
1218
0
            sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1219
0
          }
1220
19.5k
        else if (search_num_bits == 16
1221
470
           && (search_opcode & 0x3c7e) == 0x0c66)
1222
2
          {
1223
2
            prev_sploop_found = true;
1224
2
            sploop_ii
1225
2
        = (((search_opcode >> 7) & 0x7)
1226
2
           | ((search_opcode >> 11) & 0x8)) + 1;
1227
2
          }
1228
19.5k
        if (prev_sploop_found)
1229
2
          {
1230
2
            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
2
            else if (sploop_ii <= 1)
1236
0
        fcyc_bits = 0;
1237
2
            else if (sploop_ii <= 2)
1238
0
        fcyc_bits = 1;
1239
2
            else if (sploop_ii <= 4)
1240
0
        fcyc_bits = 2;
1241
2
            else if (sploop_ii <= 8)
1242
0
        fcyc_bits = 3;
1243
2
            else if (sploop_ii <= 14)
1244
2
        fcyc_bits = 4;
1245
0
            else
1246
0
        prev_sploop_found = false;
1247
2
          }
1248
19.5k
        if (prev_sploop_found)
1249
2
          break;
1250
19.5k
      }
1251
78
        }
1252
78
      if (!prev_sploop_found)
1253
76
        {
1254
76
          operands_ok = false;
1255
76
          operands_text[op_num] = true;
1256
76
          break;
1257
76
        }
1258
2
      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
2
      if (enc->coding_method == tic6x_coding_fstg)
1264
1
        {
1265
1
          int i, t;
1266
3
          for (t = 0, i = fcyc_bits; i < 6; i++)
1267
2
      t = (t << 1) | ((fld_val >> i) & 1);
1268
1
          operands_text[op_num] = true;
1269
1
          snprintf (operands[op_num], 24, "%u", t);
1270
1
        }
1271
1
      else
1272
1
        {
1273
1
          operands_text[op_num] = true;
1274
1
          snprintf (operands[op_num], 24, "%u",
1275
1
        fld_val & ((1 << fcyc_bits) - 1));
1276
1
        }
1277
2
      break;
1278
1279
595
    case tic6x_coding_spmask:
1280
595
      if (fld_val == 0)
1281
47
        spmask_skip_operand = true;
1282
548
      else
1283
548
        {
1284
548
          char *p;
1285
548
          unsigned int i;
1286
1287
548
          operands_text[op_num] = true;
1288
548
          p = operands[op_num];
1289
4.93k
          for (i = 0; i < 8; i++)
1290
4.38k
      if (fld_val & (1 << i))
1291
1.68k
        {
1292
1.68k
          *p++ = "LSDM"[i/2];
1293
1.68k
          *p++ = '1' + (i & 1);
1294
1.68k
          *p++ = ',';
1295
1.68k
        }
1296
548
          p[-1] = 0;
1297
548
        }
1298
595
      break;
1299
1300
49.3k
    case tic6x_coding_fu:
1301
72.3k
    case tic6x_coding_data_fu:
1302
96.7k
    case tic6x_coding_xpath:
1303
97.4k
    case tic6x_coding_rside:
1304
      /* Don't relate to operands, so operand number is
1305
         meaningless.  */
1306
97.4k
      break;
1307
1308
0
    default:
1309
0
                  printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1310
0
      abort ();
1311
293k
    }
1312
1313
293k
        if (mem_base_reg_known_long && mem_offset_known_long)
1314
11.6k
    {
1315
11.6k
      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
11.6k
      operands_text[op_num] = true;
1321
11.6k
      snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1322
11.6k
          mem_offset * opc->operand_info[op_num].size);
1323
11.6k
    }
1324
1325
293k
        if (mem_base_reg_known && mem_offset_known && mem_mode_known
1326
13.4k
      && (mem_scaled_known
1327
11.3k
          || (opc->operand_info[op_num].form
1328
11.3k
        != tic6x_operand_mem_ndw)))
1329
12.0k
    {
1330
12.0k
      char side;
1331
12.0k
      char base[4];
1332
12.0k
      bool offset_is_reg;
1333
12.0k
      bool offset_scaled;
1334
12.0k
      char offset[4];
1335
12.0k
      char offsetp[6];
1336
1337
12.0k
      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
12.0k
      side = func_unit_side == 2 ? 'b' : 'a';
1344
12.0k
      snprintf (base, 4, "%c%u", side, mem_base_reg);
1345
1346
12.0k
      offset_is_reg = (mem_mode & 4) != 0;
1347
12.0k
      if (offset_is_reg)
1348
3.57k
        {
1349
1350
3.57k
          if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1351
97
      {
1352
97
        reg_base = 16;
1353
97
      }
1354
3.57k
          snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1355
3.57k
          if (opc->operand_info[op_num].form
1356
3.57k
        == tic6x_operand_mem_ndw)
1357
572
      offset_scaled = mem_scaled != 0;
1358
3.00k
          else
1359
3.00k
      offset_scaled = true;
1360
3.57k
        }
1361
8.52k
      else
1362
8.52k
        {
1363
8.52k
          if (opc->operand_info[op_num].form
1364
8.52k
        == tic6x_operand_mem_ndw)
1365
918
      {
1366
918
        offset_scaled = mem_scaled != 0;
1367
918
        snprintf (offset, 4, "%u", mem_offset);
1368
918
      }
1369
7.60k
          else
1370
7.60k
      {
1371
7.60k
        offset_scaled = false;
1372
7.60k
        snprintf (offset, 4, "%u",
1373
7.60k
            (mem_offset
1374
7.60k
             * opc->operand_info[op_num].size));
1375
7.60k
      }
1376
8.52k
        }
1377
1378
12.0k
      if (offset_scaled)
1379
3.41k
        snprintf (offsetp, 6, "[%s]", offset);
1380
8.68k
      else
1381
8.68k
        snprintf (offsetp, 6, "(%s)", offset);
1382
1383
12.0k
      operands_text[op_num] = true;
1384
12.0k
      switch (mem_mode & ~4u)
1385
12.0k
        {
1386
3.45k
        case 0:
1387
3.45k
          snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1388
3.45k
          break;
1389
1390
1.40k
        case 1:
1391
1.40k
          snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1392
1.40k
          break;
1393
1394
1.53k
        case 2:
1395
2.69k
        case 3:
1396
2.69k
          operands_ok = false;
1397
2.69k
          break;
1398
1399
1.20k
        case 8:
1400
1.20k
          snprintf (operands[op_num], 24, "*--%s%s", base,
1401
1.20k
        offsetp);
1402
1.20k
          break;
1403
1404
925
        case 9:
1405
925
          snprintf (operands[op_num], 24, "*++%s%s", base,
1406
925
        offsetp);
1407
925
          break;
1408
1409
976
        case 10:
1410
976
          snprintf (operands[op_num], 24, "*%s--%s", base,
1411
976
        offsetp);
1412
976
          break;
1413
1414
1.43k
        case 11:
1415
1.43k
          snprintf (operands[op_num], 24, "*%s++%s", base,
1416
1.43k
        offsetp);
1417
1.43k
          break;
1418
1419
0
        default:
1420
0
                      printf ("*** unknown mem_mode : %d \n", mem_mode);
1421
0
          abort ();
1422
12.0k
        }
1423
12.0k
    }
1424
1425
293k
        if (crlo_known && crhi_known)
1426
1.04k
    {
1427
1.04k
      tic6x_rw rw;
1428
1.04k
      tic6x_ctrl_id crid;
1429
1430
1.04k
      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
1.04k
      rw = opc->operand_info[op_num].rw;
1437
1.04k
      if (rw != tic6x_rw_read
1438
1.00k
          && rw != tic6x_rw_write)
1439
0
        {
1440
0
          printf ("*** abort rw : %d\n", rw);
1441
0
          abort ();
1442
0
        }
1443
1444
30.1k
      for (crid = 0; crid < tic6x_ctrl_max; crid++)
1445
29.1k
        {
1446
29.1k
          if (crlo == tic6x_ctrl_table[crid].crlo
1447
1.03k
        && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1448
54
        && (rw == tic6x_rw_read
1449
54
            ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1450
18
         || (tic6x_ctrl_table[crid].rw
1451
18
             == tic6x_rw_read_write))
1452
54
            : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1453
33
         || (tic6x_ctrl_table[crid].rw
1454
33
             == tic6x_rw_read_write))))
1455
53
      break;
1456
29.1k
        }
1457
1.04k
      if (crid == tic6x_ctrl_max)
1458
990
        {
1459
990
          operands_text[op_num] = true;
1460
990
          operands_ok = false;
1461
990
        }
1462
53
      else
1463
53
        {
1464
53
          operands_text[op_num] = true;
1465
53
          snprintf (operands[op_num], 24, "%s",
1466
53
        tic6x_ctrl_table[crid].name);
1467
53
        }
1468
1.04k
    }
1469
1470
293k
        if (operands_text[op_num] || operands_pcrel[op_num]
1471
134k
      || spmask_skip_operand)
1472
158k
    break;
1473
293k
      }
1474
          /* end for fld_num */
1475
1476
158k
    if (spmask_skip_operand)
1477
47
      {
1478
        /* SPMASK operands are only valid as the single operand
1479
     in the opcode table.  */
1480
47
        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
47
        num_operands = 0;
1486
47
        break;
1487
47
      }
1488
1489
    /* The operand must by now have been decoded.  */
1490
158k
    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
158k
        }
1496
      /* end for op_num */
1497
1498
70.1k
      if (!operands_ok)
1499
5.36k
  continue;
1500
1501
64.7k
      info->bytes_per_chunk = num_bits / 8;
1502
64.7k
      info->fprintf_func (info->stream, "%s", parallel);
1503
64.7k
      info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1504
64.7k
                          func_unit);
1505
215k
      for (op_num = 0; op_num < num_operands; op_num++)
1506
150k
  {
1507
150k
    info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1508
150k
    if (operands_pcrel[op_num])
1509
4.54k
      info->print_address_func (operands_addresses[op_num], info);
1510
146k
    else
1511
146k
      info->fprintf_func (info->stream, "%s", operands[op_num]);
1512
150k
  }
1513
64.7k
      if (fetch_packet_header_based && header.prot)
1514
1.40k
  info->fprintf_func (info->stream, " || nop 5");
1515
1516
64.7k
      return num_bits / 8;
1517
70.1k
    }
1518
1519
38.3k
  info->bytes_per_chunk = num_bits / 8;
1520
38.3k
  info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1521
38.3k
          (int) num_bits / 4, opcode);
1522
38.3k
  return num_bits / 8;
1523
103k
}