Coverage Report

Created: 2024-05-21 06:29

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