Coverage Report

Created: 2023-08-28 06:31

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