Coverage Report

Created: 2023-06-29 07:13

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