Coverage Report

Created: 2025-06-24 06:45

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