Coverage Report

Created: 2026-09-14 08:07

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