Coverage Report

Created: 2025-07-08 11:15

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