Coverage Report

Created: 2026-05-11 07:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/tic6x-dis.c
Line
Count
Source
1
/* TI C6X disassembler.
2
   Copyright (C) 2010-2026 Free Software Foundation, Inc.
3
   Contributed by Joseph Myers <joseph@codesourcery.com>
4
        Bernd Schmidt  <bernds@codesourcery.com>
5
6
   This file is part of libopcodes.
7
8
   This library is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   It is distributed in the hope that it will be useful, but WITHOUT
14
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
   License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
23
#include "sysdep.h"
24
#include "disassemble.h"
25
#include "opcode/tic6x.h"
26
#include "libiberty.h"
27
28
/* Define the instruction format table.  */
29
const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max] =
30
  {
31
#define FMT(name, num_bits, cst_bits, mask, fields) \
32
    { num_bits, cst_bits, mask, fields },
33
#include "opcode/tic6x-insn-formats.h"
34
#undef FMT
35
  };
36
37
/* Define the control register table.  */
38
const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max] =
39
  {
40
#define CTRL(name, isa, rw, crlo, crhi_mask)  \
41
    {           \
42
      STRINGX(name),        \
43
      CONCAT2(TIC6X_INSN_,isa),     \
44
      CONCAT2(tic6x_rw_,rw),      \
45
      crlo,         \
46
      crhi_mask         \
47
    },
48
#include "opcode/tic6x-control-registers.h"
49
#undef CTRL
50
  };
51
52
/* Define the opcode table.  */
53
const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max] =
54
  {
55
#define INSNU(name, func_unit, format, type, isa, flags, fixed, ops, var) \
56
    {                 \
57
      STRINGX(name),              \
58
      CONCAT2(tic6x_func_unit_,func_unit),        \
59
      CONCAT3(tic6x_insn_format,_,format),              \
60
      CONCAT2(tic6x_pipeline_,type),          \
61
      CONCAT2(TIC6X_INSN_,isa),           \
62
      flags,                \
63
      fixed,                \
64
      ops,                \
65
      var               \
66
    },
67
#define INSNUE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
68
    {                 \
69
      STRINGX(name),              \
70
      CONCAT2(tic6x_func_unit_,func_unit),        \
71
      CONCAT3(tic6x_insn_format,_,format),              \
72
      CONCAT2(tic6x_pipeline_,type),          \
73
      CONCAT2(TIC6X_INSN_,isa),           \
74
      flags,                \
75
      fixed,                \
76
      ops,                \
77
      var               \
78
    },
79
#define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
80
    {                 \
81
      STRINGX(name),              \
82
      CONCAT2(tic6x_func_unit_,func_unit),        \
83
      CONCAT4(tic6x_insn_format_,func_unit,_,format),     \
84
      CONCAT2(tic6x_pipeline_,type),          \
85
      CONCAT2(TIC6X_INSN_,isa),           \
86
      flags,                \
87
      fixed,                \
88
      ops,                \
89
      var               \
90
    },
91
#define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
92
    {                 \
93
      STRINGX(name),              \
94
      CONCAT2(tic6x_func_unit_,func_unit),        \
95
      CONCAT4(tic6x_insn_format_,func_unit,_,format),     \
96
      CONCAT2(tic6x_pipeline_,type),          \
97
      CONCAT2(TIC6X_INSN_,isa),           \
98
      flags,                \
99
      fixed,                \
100
      ops,                \
101
      var               \
102
    },
103
#include "opcode/tic6x-opcode-table.h"
104
#undef INSN
105
#undef INSNE
106
#undef INSNU
107
#undef INSNUE
108
  };
109
110
/* If instruction format FMT has a field FIELD, return a pointer to
111
   the description of that field; otherwise return NULL.  */
112
113
const tic6x_insn_field *
114
tic6x_field_from_fmt (const tic6x_insn_format *fmt, tic6x_insn_field_id field)
115
6.27M
{
116
6.27M
  unsigned int f;
117
118
22.3M
  for (f = 0; f < fmt->num_fields; f++)
119
22.3M
    if (fmt->fields[f].field_id == field)
120
6.24M
      return &fmt->fields[f];
121
122
33.6k
  return NULL;
123
6.27M
}
124
125
/* Extract the field width.  */
126
127
static unsigned int
128
tic6x_field_width (const tic6x_insn_field *field)
129
19.0k
{
130
19.0k
  unsigned int i;
131
19.0k
  unsigned int width = 0;
132
133
19.0k
  if (!field->num_bitfields)
134
0
    return field->bitfields[0].width;
135
136
38.4k
  for (i = 0 ; i < field->num_bitfields ; i++)
137
19.4k
    width += field->bitfields[i].width;
138
139
19.0k
  return width;
140
19.0k
}
141
142
/* Extract the bits corresponding to FIELD from OPCODE.  */
143
144
static unsigned int
145
tic6x_field_bits (unsigned int opcode, const tic6x_insn_field *field)
146
6.24M
{
147
6.24M
  unsigned int i;
148
6.24M
  unsigned int val = 0;
149
150
6.24M
  if (!field->num_bitfields)
151
0
    return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1);
152
153
12.4M
  for (i = 0 ; i < field->num_bitfields ; i++)
154
6.24M
    val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1))
155
6.24M
      << field->bitfields[i].pos;
156
157
6.24M
  return val;
158
6.24M
}
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
307k
{
165
307k
  if (info->endian == BFD_ENDIAN_LITTLE)
166
89
    return p[0] | (p[1] << 8) | (p[2] << 16) | ((unsigned) p[3] << 24);
167
307k
  else
168
307k
    return p[3] | (p[2] << 8) | (p[1] << 16) | ((unsigned) p[0] << 24);
169
307k
}
170
171
/* Extract a 16-bit value read from the instruction stream.  */
172
173
static unsigned int
174
tic6x_extract_16 (unsigned char *p, tic6x_fetch_packet_header *header,
175
                  struct disassemble_info *info)
176
6.14k
{
177
6.14k
  unsigned int op16;
178
179
6.14k
  if (info->endian == BFD_ENDIAN_LITTLE)
180
25
    op16 = (p[0]) | (p[1] << 8);
181
6.11k
  else
182
6.11k
    op16 = (p[1]) | (p[0] << 8);
183
6.14k
  op16 |= (header->sat << TIC6X_COMPACT_SAT_POS);
184
6.14k
  op16 |= (header->br << TIC6X_COMPACT_BR_POS);
185
6.14k
  op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS);
186
6.14k
  return op16;
187
6.14k
}
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
118k
{
197
118k
  int i;
198
199
118k
  header->header = tic6x_extract_32 (fp + 28, info);
200
201
118k
  if ((header->header & 0xf0000000) != 0xe0000000)
202
109k
    {
203
109k
      header->prot = 0;
204
109k
      header->rs = 0;
205
109k
      header->dsz = 0;
206
109k
      header->br = 0;
207
109k
      header->sat = 0;
208
879k
      for (i = 0; i < 7; i++)
209
769k
  header->word_compact[i] = false;
210
1.64M
      for (i = 0; i < 14; i++)
211
1.53M
  header->p_bits[i] = false;
212
109k
      return false;
213
109k
    }
214
215
70.7k
  for (i = 0; i < 7; i++)
216
61.8k
    header->word_compact[i]
217
61.8k
      = (header->header & (1u << (21 + i))) != 0;
218
219
8.84k
  header->prot = (header->header & (1u << 20)) != 0;
220
8.84k
  header->rs = (header->header & (1u << 19)) != 0;
221
8.84k
  header->dsz = (header->header >> 16) & 0x7;
222
8.84k
  header->br = (header->header & (1u << 15)) != 0;
223
8.84k
  header->sat = (header->header & (1u << 14)) != 0;
224
225
132k
  for (i = 0; i < 14; i++)
226
123k
    header->p_bits[i] = (header->header & (1u << i)) != 0;
227
228
8.84k
  return true;
229
118k
}
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
107k
{
238
107k
  int status;
239
107k
  bfd_vma fp_addr;
240
107k
  bfd_vma fp_offset;
241
107k
  unsigned char fp[32];
242
107k
  unsigned int opcode;
243
107k
  tic6x_opcode_id opcode_id;
244
107k
  bool fetch_packet_header_based;
245
107k
  tic6x_fetch_packet_header header;
246
107k
  unsigned int num_bits;
247
107k
  bool bad_offset = false;
248
249
107k
  fp_offset = addr & 0x1f;
250
107k
  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
107k
  info->stop_vma = 0;
254
107k
  status = info->read_memory_func (fp_addr, fp, 32, info);
255
107k
  if (status)
256
171
    {
257
171
      info->memory_error_func (status, addr, info);
258
171
      return -1;
259
171
    }
260
261
107k
  fetch_packet_header_based
262
107k
    = tic6x_check_fetch_packet_header (fp, &header, info);
263
107k
  if (fetch_packet_header_based)
264
8.41k
    {
265
8.41k
      if (fp_offset & 0x1)
266
1
  bad_offset = true;
267
8.41k
      if ((fp_offset & 0x3) && (fp_offset >= 28
268
2.82k
        || !header.word_compact[fp_offset >> 2]))
269
2
  bad_offset = true;
270
8.41k
      if (fp_offset == 28)
271
710
  {
272
710
    info->bytes_per_chunk = 4;
273
710
    info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
274
710
            header.header);
275
710
    return 4;
276
710
  }
277
7.70k
      num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
278
7.70k
    }
279
98.7k
  else
280
98.7k
    {
281
98.7k
      num_bits = 32;
282
98.7k
      if (fp_offset & 0x3)
283
3
  bad_offset = true;
284
98.7k
    }
285
286
106k
  if (bad_offset)
287
5
    {
288
5
      info->bytes_per_chunk = 1;
289
5
      info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
290
5
      return 1;
291
5
    }
292
293
106k
  if (num_bits == 16)
294
5.67k
    {
295
      /* The least-significant part of a 32-bit word comes logically
296
   before the most-significant part.  For big-endian, follow the
297
   TI assembler in showing instructions in logical order by
298
   pretending that the two halves of the word are in opposite
299
   locations to where they actually are.  */
300
5.67k
      if (info->endian == BFD_ENDIAN_LITTLE)
301
25
  opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
302
5.65k
      else
303
5.65k
  opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
304
5.67k
    }
305
100k
  else
306
100k
    opcode = tic6x_extract_32 (fp + fp_offset, info);
307
308
43.0M
  for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
309
43.0M
    {
310
43.0M
      const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
311
43.0M
      const tic6x_insn_format *const fmt
312
43.0M
  = &tic6x_insn_format_table[opc->format];
313
43.0M
      const tic6x_insn_field *creg_field;
314
43.0M
      bool p_bit;
315
43.0M
      const char *parallel;
316
43.0M
      const char *cond = "";
317
43.0M
      const char *func_unit;
318
43.0M
      char func_unit_buf[8];
319
43.0M
      unsigned int func_unit_side = 0;
320
43.0M
      unsigned int func_unit_data_side = 0;
321
43.0M
      unsigned int func_unit_cross = 0;
322
43.0M
      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
43.0M
      char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
327
43.0M
      bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
328
43.0M
      bool operands_text[TIC6X_MAX_OPERANDS] = { false };
329
43.0M
      bool operands_pcrel[TIC6X_MAX_OPERANDS] = { false };
330
43.0M
      unsigned int fix;
331
43.0M
      unsigned int num_operands;
332
43.0M
      unsigned int op_num;
333
43.0M
      bool fixed_ok;
334
43.0M
      bool operands_ok;
335
43.0M
      bool have_t = false;
336
337
43.0M
      if (opc->flags & TIC6X_FLAG_MACRO)
338
4.57M
  continue;
339
38.4M
      if (fmt->num_bits != num_bits)
340
12.7M
  continue;
341
25.6M
      if ((opcode & fmt->mask) != fmt->cst_bits)
342
23.6M
  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
2.00M
      creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
349
2.00M
      if (creg_field)
350
1.97M
  {
351
1.97M
    const tic6x_insn_field *z_field;
352
1.97M
    unsigned int creg_value, z_value;
353
1.97M
    static const char *const conds[8][2] =
354
1.97M
      {
355
1.97M
        { "", NULL },
356
1.97M
        { "[b0] ", "[!b0] " },
357
1.97M
        { "[b1] ", "[!b1] " },
358
1.97M
        { "[b2] ", "[!b2] " },
359
1.97M
        { "[a1] ", "[!a1] " },
360
1.97M
        { "[a2] ", "[!a2] " },
361
1.97M
        { "[a0] ", "[!a0] " },
362
1.97M
        { NULL, NULL }
363
1.97M
      };
364
365
    /* A creg field is not meaningful without a z field, so if
366
       the z field is not present this is an error in the format
367
       table.  */
368
1.97M
    z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
369
1.97M
    if (!z_field)
370
0
      {
371
0
        printf ("*** opcode %x: missing z field", opcode);
372
0
        abort ();
373
0
      }
374
375
1.97M
    creg_value = tic6x_field_bits (opcode, creg_field);
376
1.97M
    z_value = tic6x_field_bits (opcode, z_field);
377
1.97M
    cond = conds[creg_value][z_value];
378
1.97M
    if (cond == NULL)
379
373k
      continue;
380
1.97M
  }
381
382
1.63M
      if (opc->flags & TIC6X_FLAG_INSN16_SPRED)
383
906
  {
384
906
    const tic6x_insn_field *cc_field;
385
906
          unsigned int s_value = 0;
386
906
          unsigned int z_value = 0;
387
906
          bool cond_known = false;
388
906
          static const char *const conds[2][2] =
389
906
            {
390
906
              { "[a0] ", "[!a0] " },
391
906
              { "[b0] ", "[!b0] " }
392
906
            };
393
394
906
          cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc);
395
396
906
          if (cc_field)
397
12
      {
398
12
        unsigned int cc_value;
399
400
12
        cc_value = tic6x_field_bits (opcode, cc_field);
401
12
        s_value = (cc_value & 0x2) >> 1;
402
12
        z_value = (cc_value & 0x1);
403
12
        cond_known = true;
404
12
      }
405
894
    else
406
894
      {
407
894
        const tic6x_insn_field *z_field;
408
894
        const tic6x_insn_field *s_field;
409
410
894
        s_field = tic6x_field_from_fmt (fmt, tic6x_field_s);
411
412
894
        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
894
        s_value = tic6x_field_bits (opcode, s_field);
419
894
        z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
420
894
        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
894
        z_value = tic6x_field_bits (opcode, z_field);
427
894
        cond_known = true;
428
894
      }
429
430
906
          if (!cond_known)
431
0
      {
432
0
        printf ("opcode %x: unspecified ompact insn predicate\n", opcode);
433
0
        abort ();
434
0
      }
435
906
          cond = conds[s_value][z_value];
436
906
  }
437
438
      /* All fixed fields must have matching values; all fields with
439
   restricted ranges must have values within those ranges.  */
440
1.63M
      fixed_ok = true;
441
1.75M
      for (fix = 0; fix < opc->num_fixed_fields; fix++)
442
1.67M
  {
443
1.67M
    unsigned int field_bits;
444
1.67M
    const tic6x_insn_field *const field
445
1.67M
      = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
446
447
1.67M
    if (!field)
448
0
      {
449
0
        printf ("opcode %x: missing field #%d for FIX #%d\n",
450
0
          opcode, opc->fixed_fields[fix].field_id, fix);
451
0
        abort ();
452
0
      }
453
454
1.67M
    field_bits = tic6x_field_bits (opcode, field);
455
1.67M
    if (field_bits < opc->fixed_fields[fix].min_val
456
570k
        || field_bits > opc->fixed_fields[fix].max_val)
457
1.56M
      {
458
1.56M
        fixed_ok = false;
459
1.56M
        break;
460
1.56M
      }
461
1.67M
  }
462
1.63M
      if (!fixed_ok)
463
1.56M
  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
72.5k
      if (num_bits == 16 && (fp_offset & 0x2) == 2)
473
2.35k
  {
474
    /* This is the logically second (most significant; second in
475
       fp_offset terms because fp_offset relates to logical not
476
       physical addresses) instruction of a compact pair; find
477
       the p-bit for the first (least significant).  */
478
2.35k
    p_bit = header.p_bits[(fp_offset >> 2) << 1];
479
2.35k
  }
480
70.2k
      else if (fp_offset >= 4)
481
60.8k
  {
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
60.8k
    if (fetch_packet_header_based
486
2.93k
        && header.word_compact[(fp_offset >> 2) - 1])
487
1.67k
      p_bit = header.p_bits[(fp_offset >> 1) - 1];
488
59.1k
    else
489
59.1k
      {
490
59.1k
        unsigned int prev_opcode
491
59.1k
    = tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
492
59.1k
        p_bit = (prev_opcode & 0x1) != 0;
493
59.1k
      }
494
60.8k
  }
495
9.39k
      else
496
9.39k
  {
497
    /* Find the last instruction of the previous fetch
498
       packet.  */
499
9.39k
    unsigned char fp_prev[32];
500
501
9.39k
    status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
502
9.39k
    if (status)
503
      /* No previous instruction to be parallel with.  */
504
257
      p_bit = false;
505
9.13k
    else
506
9.13k
      {
507
9.13k
        bool prev_header_based;
508
9.13k
        tic6x_fetch_packet_header prev_header;
509
510
9.13k
        prev_header_based
511
9.13k
    = tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
512
9.13k
        if (prev_header_based)
513
378
    {
514
378
      if (prev_header.word_compact[6])
515
227
        p_bit = prev_header.p_bits[13];
516
151
      else
517
151
        {
518
151
          unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 24,
519
151
                   info);
520
151
          p_bit = (prev_opcode & 0x1) != 0;
521
151
        }
522
378
    }
523
8.75k
        else
524
8.75k
    {
525
8.75k
      unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
526
8.75k
                     info);
527
8.75k
      p_bit = (prev_opcode & 0x1) != 0;
528
8.75k
    }
529
9.13k
      }
530
9.39k
  }
531
72.5k
      parallel = p_bit ? "|| " : "";
532
533
72.5k
      if (opc->func_unit == tic6x_func_unit_nfu)
534
7.88k
  func_unit = "";
535
64.7k
      else
536
64.7k
  {
537
64.7k
    unsigned int fld_num;
538
64.7k
    char func_unit_char;
539
64.7k
    const char *data_str;
540
64.7k
    bool have_areg = false;
541
64.7k
    bool have_cross = false;
542
543
64.7k
    func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
544
64.7k
    func_unit_cross = 0;
545
64.7k
    func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
546
547
365k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
548
301k
      {
549
301k
        const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
550
301k
        const tic6x_insn_field *field;
551
301k
        unsigned int fld_val;
552
553
301k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
554
555
301k
        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
301k
        fld_val = tic6x_field_bits (opcode, field);
563
564
301k
        switch (enc->coding_method)
565
301k
    {
566
51.1k
    case tic6x_coding_fu:
567
      /* The side must be specified exactly once.  */
568
51.1k
      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
51.1k
      func_unit_side = (fld_val ? 2 : 1);
575
51.1k
      break;
576
577
25.1k
    case tic6x_coding_data_fu:
578
      /* The data side must be specified exactly once.  */
579
25.1k
      if (func_unit_data_side)
580
0
        {
581
0
          printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
582
0
            opcode, fld_num);
583
0
          abort ();
584
0
        }
585
25.1k
      func_unit_data_side = (fld_val ? 2 : 1);
586
25.1k
      break;
587
588
25.5k
    case tic6x_coding_xpath:
589
      /* Cross path use must be specified exactly
590
         once.  */
591
25.5k
      if (have_cross)
592
0
        {
593
0
          printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
594
0
            opcode, fld_num);
595
0
          abort ();
596
0
        }
597
25.5k
      have_cross = true;
598
25.5k
      func_unit_cross = fld_val;
599
25.5k
      break;
600
601
854
                case tic6x_coding_rside:
602
                  /* If the format has a t field, use it for src/dst register side.  */
603
854
                  have_t = true;
604
854
                  t_val = fld_val;
605
854
                  func_unit_data_side = (t_val ? 2 : 1);
606
854
                  break;
607
608
13.0k
    case tic6x_coding_areg:
609
13.0k
      have_areg = true;
610
13.0k
      break;
611
612
185k
    default:
613
      /* Don't relate to functional units.  */
614
185k
      break;
615
301k
    }
616
301k
      }
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
64.7k
    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
64.7k
    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
64.7k
    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
64.7k
    if (have_areg && !func_unit_data_side)
650
228
      {
651
228
        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
228
        func_unit_cross = func_unit_side == 1;
657
228
      }
658
659
64.7k
    switch (opc->func_unit)
660
64.7k
      {
661
27.4k
      case tic6x_func_unit_d:
662
27.4k
        func_unit_char = 'D';
663
27.4k
        break;
664
665
5.44k
      case tic6x_func_unit_l:
666
5.44k
        func_unit_char = 'L';
667
5.44k
        break;
668
669
16.0k
      case tic6x_func_unit_m:
670
16.0k
        func_unit_char = 'M';
671
16.0k
        break;
672
673
15.8k
      case tic6x_func_unit_s:
674
15.8k
        func_unit_char = 'S';
675
15.8k
        break;
676
677
0
      default:
678
0
              printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
679
0
        abort ();
680
64.7k
      }
681
682
64.7k
    switch (func_unit_data_side)
683
64.7k
      {
684
38.7k
      case 0:
685
38.7k
        data_str = "";
686
38.7k
        break;
687
688
13.2k
      case 1:
689
13.2k
        data_str = "T1";
690
13.2k
        break;
691
692
12.7k
      case 2:
693
12.7k
        data_str = "T2";
694
12.7k
        break;
695
696
0
      default:
697
0
              printf ("opcode %x: illegal data func_unit specifier %d\n",
698
0
          opcode, func_unit_data_side);
699
0
        abort ();
700
64.7k
      }
701
702
64.7k
    if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
703
9
        func_unit_cross = 1;
704
705
64.7k
    snprintf (func_unit_buf, sizeof func_unit_buf, " .%c%u%s%s",
706
64.7k
        func_unit_char, func_unit_side,
707
64.7k
        (func_unit_cross ? "X" : ""), data_str);
708
64.7k
    func_unit = func_unit_buf;
709
64.7k
  }
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
72.5k
      operands_ok = true;
715
72.5k
      num_operands = opc->num_operands;
716
241k
      for (op_num = 0; op_num < num_operands; op_num++)
717
168k
  {
718
168k
    unsigned int fld_num;
719
168k
    unsigned int mem_base_reg = 0;
720
168k
    bool mem_base_reg_known = false;
721
168k
    bool mem_base_reg_known_long = false;
722
168k
    unsigned int mem_offset = 0;
723
168k
    bool mem_offset_known = false;
724
168k
    bool mem_offset_known_long = false;
725
168k
    unsigned int mem_mode = 0;
726
168k
    bool mem_mode_known = false;
727
168k
    unsigned int mem_scaled = 0;
728
168k
    bool mem_scaled_known = false;
729
168k
    unsigned int crlo = 0;
730
168k
    bool crlo_known = false;
731
168k
    unsigned int crhi = 0;
732
168k
    bool crhi_known = false;
733
168k
    bool spmask_skip_operand = false;
734
168k
    unsigned int fcyc_bits = 0;
735
168k
    bool prev_sploop_found = false;
736
737
168k
    switch (opc->operand_info[op_num].form)
738
168k
      {
739
27
      case tic6x_operand_b15reg:
740
        /* Fully determined by the functional unit.  */
741
27
        operands_text[op_num] = true;
742
27
        snprintf (operands[op_num], 24, "b15");
743
27
        continue;
744
745
39
      case tic6x_operand_zreg:
746
        /* Fully determined by the functional unit.  */
747
39
        operands_text[op_num] = true;
748
39
        snprintf (operands[op_num], 24, "%c0",
749
39
      (func_unit_side == 2 ? 'b' : 'a'));
750
39
        continue;
751
752
675
      case tic6x_operand_retreg:
753
        /* Fully determined by the functional unit.  */
754
675
        operands_text[op_num] = true;
755
675
        snprintf (operands[op_num], 24, "%c3",
756
675
      (func_unit_side == 2 ? 'b' : 'a'));
757
675
        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
0
      case tic6x_operand_ilc:
770
0
        operands_text[op_num] = true;
771
0
        snprintf (operands[op_num], 24, "ilc");
772
0
        continue;
773
774
0
      case tic6x_operand_hw_const_minus_1:
775
0
        operands_text[op_num] = true;
776
0
        snprintf (operands[op_num], 24, "-1");
777
0
        continue;
778
779
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
6
      case tic6x_operand_hw_const_1:
785
6
        operands_text[op_num] = true;
786
6
        snprintf (operands[op_num], 24, "1");
787
6
        continue;
788
789
818
      case tic6x_operand_hw_const_5:
790
818
        operands_text[op_num] = true;
791
818
        snprintf (operands[op_num], 24, "5");
792
818
        continue;
793
794
1.09k
      case tic6x_operand_hw_const_16:
795
1.09k
        operands_text[op_num] = true;
796
1.09k
        snprintf (operands[op_num], 24, "16");
797
1.09k
        continue;
798
799
10
      case tic6x_operand_hw_const_24:
800
10
        operands_text[op_num] = true;
801
10
        snprintf (operands[op_num], 24, "24");
802
10
        continue;
803
804
39
      case tic6x_operand_hw_const_31:
805
39
        operands_text[op_num] = true;
806
39
        snprintf (operands[op_num], 24, "31");
807
39
        continue;
808
809
165k
      default:
810
165k
        break;
811
168k
      }
812
813
631k
    for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
814
631k
      {
815
631k
        const tic6x_coding_field *const enc
816
631k
    = &opc->variable_fields[fld_num];
817
631k
        const tic6x_insn_field *field;
818
631k
        unsigned int fld_val;
819
631k
        unsigned int reg_base = 0;
820
631k
        signed int signed_fld_val;
821
631k
              char reg_side = '?';
822
823
631k
        if (enc->operand_num != op_num)
824
323k
    continue;
825
308k
        field = tic6x_field_from_fmt (fmt, enc->field_id);
826
308k
        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
308k
              fld_val = tic6x_field_bits (opcode, field);
832
308k
        switch (enc->coding_method)
833
308k
    {
834
60
                case tic6x_coding_cst_s3i:
835
60
                  (fld_val == 0x00) && (fld_val = 0x10);
836
60
                  (fld_val == 0x07) && (fld_val = 0x08);
837
                  /* Fall through.  */
838
7.45k
    case tic6x_coding_ucst:
839
10.4k
    case tic6x_coding_ulcst_dpr_byte:
840
14.8k
    case tic6x_coding_ulcst_dpr_half:
841
20.5k
    case tic6x_coding_ulcst_dpr_word:
842
20.5k
    case tic6x_coding_lcst_low16:
843
20.5k
      switch (opc->operand_info[op_num].form)
844
20.5k
        {
845
7.29k
        case tic6x_operand_asm_const:
846
7.68k
        case tic6x_operand_link_const:
847
7.68k
          operands_text[op_num] = true;
848
7.68k
          snprintf (operands[op_num], 24, "%u", fld_val);
849
7.68k
          break;
850
851
12.8k
        case tic6x_operand_mem_long:
852
12.8k
          mem_offset = fld_val;
853
12.8k
          mem_offset_known_long = true;
854
12.8k
          break;
855
856
0
        default:
857
0
                      printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
858
0
          abort ();
859
20.5k
        }
860
20.5k
      break;
861
862
20.5k
    case tic6x_coding_lcst_high16:
863
1.59k
      operands_text[op_num] = true;
864
1.59k
      snprintf (operands[op_num], 24, "%u", fld_val << 16);
865
1.59k
      break;
866
867
243
                case tic6x_coding_scst_l3i:
868
243
      operands_text[op_num] = true;
869
243
                  if (fld_val == 0)
870
51
        {
871
51
          signed_fld_val = 8;
872
51
        }
873
192
      else
874
192
        {
875
192
          signed_fld_val = (signed int) fld_val;
876
192
          signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
877
192
          signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
878
192
        }
879
243
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
880
243
      break;
881
882
6.02k
    case tic6x_coding_scst:
883
6.02k
      operands_text[op_num] = true;
884
6.02k
      signed_fld_val = (signed int) fld_val;
885
6.02k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
886
6.02k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
887
6.02k
      snprintf (operands[op_num], 24, "%d", signed_fld_val);
888
6.02k
      break;
889
890
7.08k
    case tic6x_coding_ucst_minus_one:
891
7.08k
      operands_text[op_num] = true;
892
7.08k
      snprintf (operands[op_num], 24, "%u", fld_val + 1);
893
7.08k
      break;
894
895
3.13k
    case tic6x_coding_pcrel:
896
3.27k
    case tic6x_coding_pcrel_half:
897
3.27k
      signed_fld_val = (signed int) fld_val;
898
3.27k
      signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
899
3.27k
      signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
900
3.27k
      if (fetch_packet_header_based
901
172
          && enc->coding_method == tic6x_coding_pcrel_half)
902
127
        signed_fld_val *= 2;
903
3.15k
      else
904
3.15k
        signed_fld_val *= 4;
905
3.27k
      operands_pcrel[op_num] = true;
906
3.27k
      operands_addresses[op_num] = fp_addr + signed_fld_val;
907
3.27k
      break;
908
909
108
    case tic6x_coding_regpair_msb:
910
108
      if (opc->operand_info[op_num].form != tic6x_operand_regpair)
911
0
        abort ();
912
108
      operands_text[op_num] = true;
913
108
      snprintf (operands[op_num], 24, "%c%u:%c%u",
914
108
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
915
108
          (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
916
108
      break;
917
918
818
    case tic6x_coding_pcrel_half_unsigned:
919
818
      operands_pcrel[op_num] = true;
920
818
      operands_addresses[op_num] = fp_addr + 2 * fld_val;
921
818
      break;
922
923
2.08k
    case tic6x_coding_reg_shift:
924
2.08k
      fld_val <<= 1;
925
      /* Fall through.  */
926
123k
    case tic6x_coding_reg:
927
123k
                  if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
928
3.67k
                    {
929
3.67k
          reg_base = 16;
930
3.67k
                    }
931
123k
      switch (opc->operand_info[op_num].form)
932
123k
        {
933
605
        case tic6x_operand_treg:
934
605
                      if (!have_t)
935
0
      {
936
0
        printf ("opcode %x: operand treg but missing t field\n", opcode);
937
0
        abort ();
938
0
      }
939
605
          operands_text[op_num] = true;
940
605
                      reg_side = t_val ? 'b' : 'a';
941
605
          snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
942
605
          break;
943
944
50.2k
        case tic6x_operand_reg:
945
50.2k
          operands_text[op_num] = true;
946
50.2k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
947
50.2k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
948
50.2k
          break;
949
950
92
        case tic6x_operand_reg_nors:
951
92
          operands_text[op_num] = true;
952
92
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
953
92
          snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
954
92
          break;
955
956
0
        case tic6x_operand_reg_bside:
957
0
          operands_text[op_num] = true;
958
0
          snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
959
0
          break;
960
961
58
        case tic6x_operand_reg_bside_nors:
962
58
          operands_text[op_num] = true;
963
58
          snprintf (operands[op_num], 24, "b%u", fld_val);
964
58
          break;
965
966
24.7k
        case tic6x_operand_xreg:
967
24.7k
          operands_text[op_num] = true;
968
24.7k
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
969
24.7k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
970
24.7k
          break;
971
972
22.0k
        case tic6x_operand_dreg:
973
22.0k
          operands_text[op_num] = true;
974
22.0k
                      reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
975
22.0k
          snprintf (operands[op_num], 24, "%c%u", reg_side,  reg_base + fld_val);
976
22.0k
          break;
977
978
9.55k
        case tic6x_operand_regpair:
979
9.55k
          operands_text[op_num] = true;
980
9.55k
          if (fld_val & 1)
981
1.67k
      operands_ok = false;
982
9.55k
                      reg_side = (func_unit_side == 2) ? 'b' : 'a';
983
9.55k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
984
9.55k
                                reg_side, reg_base + fld_val + 1,
985
9.55k
        reg_side, reg_base + fld_val);
986
9.55k
          break;
987
988
686
        case tic6x_operand_xregpair:
989
686
          operands_text[op_num] = true;
990
686
          if (fld_val & 1)
991
218
      operands_ok = false;
992
686
                      reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
993
686
          snprintf (operands[op_num], 24, "%c%u:%c%u",
994
686
        reg_side, reg_base + fld_val + 1,
995
686
        reg_side, reg_base + fld_val);
996
686
          break;
997
998
249
        case tic6x_operand_tregpair:
999
249
                      if (!have_t)
1000
0
      {
1001
0
        printf ("opcode %x: operand tregpair but missing t field\n", opcode);
1002
0
        abort ();
1003
0
      }
1004
249
          operands_text[op_num] = true;
1005
249
          if (fld_val & 1)
1006
5
      operands_ok = false;
1007
249
                      reg_side = t_val ? 'b' : 'a';
1008
249
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1009
249
        reg_side, reg_base + fld_val + 1,
1010
249
        reg_side, reg_base + fld_val);
1011
249
          break;
1012
1013
3.04k
        case tic6x_operand_dregpair:
1014
3.04k
          operands_text[op_num] = true;
1015
3.04k
          if (fld_val & 1)
1016
497
      operands_ok = false;
1017
3.04k
                      reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1018
3.04k
          snprintf (operands[op_num], 24, "%c%u:%c%u",
1019
3.04k
        reg_side, reg_base + fld_val + 1,
1020
3.04k
        reg_side, reg_base + fld_val);
1021
3.04k
          break;
1022
1023
10
        case tic6x_operand_mem_deref:
1024
10
          operands_text[op_num] = true;
1025
10
                      reg_side = func_unit_side == 2 ? 'b' : 'a';
1026
10
          snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1027
10
          break;
1028
1029
10.7k
        case tic6x_operand_mem_short:
1030
12.2k
        case tic6x_operand_mem_ndw:
1031
12.2k
          mem_base_reg = fld_val;
1032
12.2k
          mem_base_reg_known = true;
1033
12.2k
          break;
1034
1035
0
        default:
1036
0
                      printf ("opcode %x: unexpected operand form %d for operand #%d",
1037
0
            opcode, opc->operand_info[op_num].form, op_num);
1038
0
          abort ();
1039
123k
        }
1040
123k
      break;
1041
1042
123k
                case tic6x_coding_reg_ptr:
1043
773
      switch (opc->operand_info[op_num].form)
1044
773
        {
1045
671
        case tic6x_operand_mem_short:
1046
773
        case tic6x_operand_mem_ndw:
1047
773
                      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
773
          mem_base_reg = 0x4 | fld_val;
1054
773
          mem_base_reg_known = true;
1055
773
          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
773
        }
1062
773
      break;
1063
1064
13.0k
    case tic6x_coding_areg:
1065
13.0k
      switch (opc->operand_info[op_num].form)
1066
13.0k
        {
1067
228
        case tic6x_operand_areg:
1068
228
          operands_text[op_num] = true;
1069
228
          snprintf (operands[op_num], 24, "b%u",
1070
228
        fld_val ? 15u : 14u);
1071
228
          break;
1072
1073
12.8k
        case tic6x_operand_mem_long:
1074
12.8k
          mem_base_reg = fld_val ? 15u : 14u;
1075
12.8k
          mem_base_reg_known_long = true;
1076
12.8k
          break;
1077
1078
0
        default:
1079
0
                      printf ("opcode %x: bad operand form\n", opcode);
1080
0
          abort ();
1081
13.0k
        }
1082
13.0k
      break;
1083
1084
13.0k
    case tic6x_coding_mem_offset_minus_one_noscale:
1085
175
    case tic6x_coding_mem_offset_minus_one:
1086
175
      fld_val += 1;
1087
      /* Fall through.  */
1088
1.80k
    case tic6x_coding_mem_offset_noscale:
1089
13.1k
    case tic6x_coding_mem_offset:
1090
13.1k
      mem_offset = fld_val;
1091
13.1k
      mem_offset_known = true;
1092
13.1k
      if (num_bits == 16)
1093
854
        {
1094
854
          mem_mode_known = true;
1095
854
          mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1096
854
          mem_scaled_known = true;
1097
854
          mem_scaled = true;
1098
854
          if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1099
81
      {
1100
81
        mem_base_reg_known = true;
1101
81
        mem_base_reg = 15;
1102
81
      }
1103
854
          if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1104
771
         || enc->coding_method == tic6x_coding_mem_offset_noscale )
1105
83
      mem_scaled = false;
1106
854
        }
1107
13.1k
      break;
1108
1109
12.2k
    case tic6x_coding_mem_mode:
1110
12.2k
      mem_mode = fld_val;
1111
12.2k
      mem_mode_known = true;
1112
12.2k
      break;
1113
1114
1.54k
    case tic6x_coding_scaled:
1115
1.54k
      mem_scaled = fld_val;
1116
1.54k
      mem_scaled_known = true;
1117
1.54k
      break;
1118
1119
709
    case tic6x_coding_crlo:
1120
709
      crlo = fld_val;
1121
709
      crlo_known = true;
1122
709
      break;
1123
1124
709
    case tic6x_coding_crhi:
1125
709
      crhi = fld_val;
1126
709
      crhi_known = true;
1127
709
      break;
1128
1129
42
    case tic6x_coding_fstg:
1130
84
    case tic6x_coding_fcyc:
1131
84
      if (!prev_sploop_found)
1132
84
        {
1133
84
          bfd_vma search_fp_addr = fp_addr;
1134
84
          bfd_vma search_fp_offset = fp_offset;
1135
84
          bool search_fp_header_based
1136
84
      = fetch_packet_header_based;
1137
84
          tic6x_fetch_packet_header search_fp_header = header;
1138
84
          unsigned char search_fp[32];
1139
84
          unsigned int search_num_bits;
1140
84
          unsigned int search_opcode;
1141
84
          unsigned int sploop_ii = 0;
1142
84
          int i;
1143
1144
84
          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
20.5k
          for (i = 0; i < 48 * 8; i++)
1151
20.5k
      {
1152
        /* Find the previous instruction.  */
1153
20.5k
        if (search_fp_offset & 2)
1154
248
          search_fp_offset -= 2;
1155
20.2k
        else if (search_fp_offset >= 4)
1156
17.6k
          {
1157
17.6k
            if (search_fp_header_based
1158
398
          && (search_fp_header.word_compact
1159
398
              [(search_fp_offset >> 2) - 1]))
1160
198
        search_fp_offset -= 2;
1161
17.4k
            else
1162
17.4k
        search_fp_offset -= 4;
1163
17.6k
          }
1164
2.58k
        else
1165
2.58k
          {
1166
2.58k
            search_fp_addr -= 32;
1167
2.58k
            status = info->read_memory_func (search_fp_addr,
1168
2.58k
                     search_fp,
1169
2.58k
                     32, info);
1170
2.58k
            if (status)
1171
        /* No previous SPLOOP instruction.  */
1172
66
        break;
1173
2.52k
            search_fp_header_based
1174
2.52k
        = (tic6x_check_fetch_packet_header
1175
2.52k
           (search_fp, &search_fp_header, info));
1176
2.52k
            if (search_fp_header_based)
1177
46
        search_fp_offset
1178
46
          = search_fp_header.word_compact[6] ? 26 : 24;
1179
2.47k
            else
1180
2.47k
        search_fp_offset = 28;
1181
2.52k
          }
1182
1183
        /* Extract the previous instruction.  */
1184
20.4k
        if (search_fp_header_based)
1185
692
          search_num_bits
1186
692
            = (search_fp_header.word_compact[search_fp_offset
1187
692
                     >> 2]
1188
692
         ? 16
1189
692
         : 32);
1190
19.7k
        else
1191
19.7k
          search_num_bits = 32;
1192
20.4k
        if (search_num_bits == 16)
1193
464
          {
1194
464
            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
464
            else
1199
464
        search_opcode
1200
464
          = (tic6x_extract_16
1201
464
             (search_fp + (search_fp_offset ^ 2), &header,
1202
464
              info));
1203
464
          }
1204
19.9k
        else
1205
19.9k
          search_opcode
1206
19.9k
            = tic6x_extract_32 (search_fp + search_fp_offset,
1207
19.9k
              info);
1208
1209
        /* Check whether it is an SPLOOP-family
1210
           instruction.  */
1211
20.4k
        if (search_num_bits == 32
1212
19.9k
            && ((search_opcode & 0x003ffffe) == 0x00038000
1213
19.9k
          || (search_opcode & 0x003ffffe) == 0x0003a000
1214
19.9k
          || ((search_opcode & 0x003ffffe)
1215
19.9k
              == 0x0003e000)))
1216
0
          {
1217
0
            prev_sploop_found = true;
1218
0
            sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1219
0
          }
1220
20.4k
        else if (search_num_bits == 16
1221
464
           && (search_opcode & 0x3c7e) == 0x0c66)
1222
2
          {
1223
2
            prev_sploop_found = true;
1224
2
            sploop_ii
1225
2
        = (((search_opcode >> 7) & 0x7)
1226
2
           | ((search_opcode >> 11) & 0x8)) + 1;
1227
2
          }
1228
20.4k
        if (prev_sploop_found)
1229
2
          {
1230
2
            if (sploop_ii <= 0)
1231
0
        {
1232
0
          printf ("opcode %x:  sloop index not found (%d)\n", opcode, sploop_ii);
1233
0
          abort ();
1234
0
        }
1235
2
            else if (sploop_ii <= 1)
1236
0
        fcyc_bits = 0;
1237
2
            else if (sploop_ii <= 2)
1238
0
        fcyc_bits = 1;
1239
2
            else if (sploop_ii <= 4)
1240
0
        fcyc_bits = 2;
1241
2
            else if (sploop_ii <= 8)
1242
0
        fcyc_bits = 3;
1243
2
            else if (sploop_ii <= 14)
1244
2
        fcyc_bits = 4;
1245
0
            else
1246
0
        prev_sploop_found = false;
1247
2
          }
1248
20.4k
        if (prev_sploop_found)
1249
2
          break;
1250
20.4k
      }
1251
84
        }
1252
84
      if (!prev_sploop_found)
1253
82
        {
1254
82
          operands_ok = false;
1255
82
          operands_text[op_num] = true;
1256
82
          break;
1257
82
        }
1258
2
      if (fcyc_bits > tic6x_field_width(field))
1259
0
        {
1260
0
          printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1261
0
          abort ();
1262
0
        }
1263
2
      if (enc->coding_method == tic6x_coding_fstg)
1264
1
        {
1265
1
          int i, t;
1266
3
          for (t = 0, i = fcyc_bits; i < 6; i++)
1267
2
      t = (t << 1) | ((fld_val >> i) & 1);
1268
1
          operands_text[op_num] = true;
1269
1
          snprintf (operands[op_num], 24, "%u", t);
1270
1
        }
1271
1
      else
1272
1
        {
1273
1
          operands_text[op_num] = true;
1274
1
          snprintf (operands[op_num], 24, "%u",
1275
1
        fld_val & ((1 << fcyc_bits) - 1));
1276
1
        }
1277
2
      break;
1278
1279
564
    case tic6x_coding_spmask:
1280
564
      if (fld_val == 0)
1281
46
        spmask_skip_operand = true;
1282
518
      else
1283
518
        {
1284
518
          char *p;
1285
518
          unsigned int i;
1286
1287
518
          operands_text[op_num] = true;
1288
518
          p = operands[op_num];
1289
4.66k
          for (i = 0; i < 8; i++)
1290
4.14k
      if (fld_val & (1 << i))
1291
1.64k
        {
1292
1.64k
          *p++ = "LSDM"[i/2];
1293
1.64k
          *p++ = '1' + (i & 1);
1294
1.64k
          *p++ = ',';
1295
1.64k
        }
1296
518
          p[-1] = 0;
1297
518
        }
1298
564
      break;
1299
1300
51.0k
    case tic6x_coding_fu:
1301
76.2k
    case tic6x_coding_data_fu:
1302
101k
    case tic6x_coding_xpath:
1303
102k
    case tic6x_coding_rside:
1304
      /* Don't relate to operands, so operand number is
1305
         meaningless.  */
1306
102k
      break;
1307
1308
0
    default:
1309
0
                  printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1310
0
      abort ();
1311
308k
    }
1312
1313
308k
        if (mem_base_reg_known_long && mem_offset_known_long)
1314
12.8k
    {
1315
12.8k
      if (operands_text[op_num] || operands_pcrel[op_num])
1316
0
        {
1317
0
          printf ("opcode %x: long access but operands already known ?\n", opcode);
1318
0
          abort ();
1319
0
        }
1320
12.8k
      operands_text[op_num] = true;
1321
12.8k
      snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1322
12.8k
          mem_offset * opc->operand_info[op_num].size);
1323
12.8k
    }
1324
1325
308k
        if (mem_base_reg_known && mem_offset_known && mem_mode_known
1326
14.6k
      && (mem_scaled_known
1327
12.2k
          || (opc->operand_info[op_num].form
1328
12.2k
        != tic6x_operand_mem_ndw)))
1329
13.1k
    {
1330
13.1k
      char side;
1331
13.1k
      char base[4];
1332
13.1k
      bool offset_is_reg;
1333
13.1k
      bool offset_scaled;
1334
13.1k
      char offset[4];
1335
13.1k
      char offsetp[6];
1336
1337
13.1k
      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
13.1k
      side = func_unit_side == 2 ? 'b' : 'a';
1344
13.1k
      snprintf (base, 4, "%c%u", side, mem_base_reg);
1345
1346
13.1k
      offset_is_reg = (mem_mode & 4) != 0;
1347
13.1k
      if (offset_is_reg)
1348
4.19k
        {
1349
1350
4.19k
          if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1351
120
      {
1352
120
        reg_base = 16;
1353
120
      }
1354
4.19k
          snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1355
4.19k
          if (opc->operand_info[op_num].form
1356
4.19k
        == tic6x_operand_mem_ndw)
1357
655
      offset_scaled = mem_scaled != 0;
1358
3.54k
          else
1359
3.54k
      offset_scaled = true;
1360
4.19k
        }
1361
8.94k
      else
1362
8.94k
        {
1363
8.94k
          if (opc->operand_info[op_num].form
1364
8.94k
        == tic6x_operand_mem_ndw)
1365
996
      {
1366
996
        offset_scaled = mem_scaled != 0;
1367
996
        snprintf (offset, 4, "%u", mem_offset);
1368
996
      }
1369
7.94k
          else
1370
7.94k
      {
1371
7.94k
        offset_scaled = false;
1372
7.94k
        snprintf (offset, 4, "%u",
1373
7.94k
            (mem_offset
1374
7.94k
             * opc->operand_info[op_num].size));
1375
7.94k
      }
1376
8.94k
        }
1377
1378
13.1k
      if (offset_scaled)
1379
3.97k
        snprintf (offsetp, 6, "[%s]", offset);
1380
9.16k
      else
1381
9.16k
        snprintf (offsetp, 6, "(%s)", offset);
1382
1383
13.1k
      operands_text[op_num] = true;
1384
13.1k
      switch (mem_mode & ~4u)
1385
13.1k
        {
1386
3.47k
        case 0:
1387
3.47k
          snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1388
3.47k
          break;
1389
1390
1.63k
        case 1:
1391
1.63k
          snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1392
1.63k
          break;
1393
1394
1.75k
        case 2:
1395
3.14k
        case 3:
1396
3.14k
          operands_ok = false;
1397
3.14k
          break;
1398
1399
1.35k
        case 8:
1400
1.35k
          snprintf (operands[op_num], 24, "*--%s%s", base,
1401
1.35k
        offsetp);
1402
1.35k
          break;
1403
1404
1.00k
        case 9:
1405
1.00k
          snprintf (operands[op_num], 24, "*++%s%s", base,
1406
1.00k
        offsetp);
1407
1.00k
          break;
1408
1409
1.09k
        case 10:
1410
1.09k
          snprintf (operands[op_num], 24, "*%s--%s", base,
1411
1.09k
        offsetp);
1412
1.09k
          break;
1413
1414
1.43k
        case 11:
1415
1.43k
          snprintf (operands[op_num], 24, "*%s++%s", base,
1416
1.43k
        offsetp);
1417
1.43k
          break;
1418
1419
0
        default:
1420
0
                      printf ("*** unknown mem_mode : %d \n", mem_mode);
1421
0
          abort ();
1422
13.1k
        }
1423
13.1k
    }
1424
1425
308k
        if (crlo_known && crhi_known)
1426
709
    {
1427
709
      tic6x_rw rw;
1428
709
      tic6x_ctrl_id crid;
1429
1430
709
      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
709
      rw = opc->operand_info[op_num].rw;
1437
709
      if (rw != tic6x_rw_read
1438
672
          && rw != tic6x_rw_write)
1439
0
        {
1440
0
          printf ("*** abort rw : %d\n", rw);
1441
0
          abort ();
1442
0
        }
1443
1444
20.4k
      for (crid = 0; crid < tic6x_ctrl_max; crid++)
1445
19.7k
        {
1446
19.7k
          if (crlo == tic6x_ctrl_table[crid].crlo
1447
704
        && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1448
45
        && (rw == tic6x_rw_read
1449
45
            ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1450
10
         || (tic6x_ctrl_table[crid].rw
1451
10
             == tic6x_rw_read_write))
1452
45
            : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1453
35
         || (tic6x_ctrl_table[crid].rw
1454
35
             == tic6x_rw_read_write))))
1455
43
      break;
1456
19.7k
        }
1457
709
      if (crid == tic6x_ctrl_max)
1458
666
        {
1459
666
          operands_text[op_num] = true;
1460
666
          operands_ok = false;
1461
666
        }
1462
43
      else
1463
43
        {
1464
43
          operands_text[op_num] = true;
1465
43
          snprintf (operands[op_num], 24, "%s",
1466
43
        tic6x_ctrl_table[crid].name);
1467
43
        }
1468
709
    }
1469
1470
308k
        if (operands_text[op_num] || operands_pcrel[op_num]
1471
142k
      || spmask_skip_operand)
1472
165k
    break;
1473
308k
      }
1474
          /* end for fld_num */
1475
1476
165k
    if (spmask_skip_operand)
1477
46
      {
1478
        /* SPMASK operands are only valid as the single operand
1479
     in the opcode table.  */
1480
46
        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
46
        num_operands = 0;
1486
46
        break;
1487
46
      }
1488
1489
    /* The operand must by now have been decoded.  */
1490
165k
    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
165k
        }
1496
      /* end for op_num */
1497
1498
72.5k
      if (!operands_ok)
1499
5.76k
  continue;
1500
1501
66.8k
      info->bytes_per_chunk = num_bits / 8;
1502
66.8k
      info->fprintf_func (info->stream, "%s", parallel);
1503
66.8k
      info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1504
66.8k
                          func_unit);
1505
222k
      for (op_num = 0; op_num < num_operands; op_num++)
1506
155k
  {
1507
155k
    info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1508
155k
    if (operands_pcrel[op_num])
1509
4.09k
      info->print_address_func (operands_addresses[op_num], info);
1510
151k
    else
1511
151k
      info->fprintf_func (info->stream, "%s", operands[op_num]);
1512
155k
  }
1513
66.8k
      if (fetch_packet_header_based && header.prot)
1514
1.76k
  info->fprintf_func (info->stream, " || nop 5");
1515
1516
66.8k
      return num_bits / 8;
1517
72.5k
    }
1518
1519
39.6k
  info->bytes_per_chunk = num_bits / 8;
1520
39.6k
  info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1521
39.6k
          (int) num_bits / 4, opcode);
1522
39.6k
  return num_bits / 8;
1523
106k
}