Coverage Report

Created: 2024-05-21 06:29

/src/binutils-gdb/opcodes/arc-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Instruction printing code for the ARC.
2
   Copyright (C) 1994-2024 Free Software Foundation, Inc.
3
4
   Contributed by Claudiu Zissulescu (claziss@synopsys.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, or (at your option)
11
   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 <stdio.h>
25
#include <assert.h>
26
#include "dis-asm.h"
27
#include "opcode/arc.h"
28
#include "elf/arc.h"
29
#include "arc-dis.h"
30
#include "arc-ext.h"
31
#include "elf-bfd.h"
32
#include "libiberty.h"
33
#include "opintl.h"
34
35
/* Structure used to iterate over, and extract the values for, operands of
36
   an opcode.  */
37
38
struct arc_operand_iterator
39
{
40
  /* The complete instruction value to extract operands from.  */
41
  unsigned long long insn;
42
43
  /* The LIMM if this is being tracked separately.  This field is only
44
     valid if we find the LIMM operand in the operand list.  */
45
  unsigned limm;
46
47
  /* The opcode this iterator is operating on.  */
48
  const struct arc_opcode *opcode;
49
50
  /* The index into the opcodes operand index list.  */
51
  const unsigned char *opidx;
52
};
53
54
/* A private data used by ARC decoder.  */
55
struct arc_disassemble_info
56
{
57
  /* The current disassembled arc opcode.  */
58
  const struct arc_opcode *opcode;
59
60
  /* Instruction length w/o limm field.  */
61
  unsigned insn_len;
62
63
  /* TRUE if we have limm.  */
64
  bool limm_p;
65
66
  /* LIMM value, if exists.  */
67
  unsigned limm;
68
69
  /* Condition code, if exists.  */
70
  unsigned condition_code;
71
72
  /* Writeback mode.  */
73
  unsigned writeback_mode;
74
75
  /* Number of operands.  */
76
  unsigned operands_count;
77
78
  struct arc_insn_operand operands[MAX_INSN_ARGS];
79
};
80
81
/* Globals variables.  */
82
83
static const char * const regnames[64] =
84
{
85
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
86
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
87
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
88
  "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
89
90
  "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
91
  "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
92
  "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
93
  "r56", "r57", "r58", "r59", "lp_count", "reserved", "LIMM", "pcl"
94
};
95
96
static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
97
{
98
  "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
99
  "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
100
};
101
102
static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
103
104
static const char * const addrtypeunknown = "unknown";
105
106
/* This structure keeps track which instruction class(es)
107
   should be ignored durring disassembling.  */
108
109
typedef struct skipclass
110
{
111
  insn_class_t     insn_class;
112
  insn_subclass_t  subclass;
113
  struct skipclass *nxt;
114
} skipclass_t, *linkclass;
115
116
/* Intial classes of instructions to be consider first when
117
   disassembling.  */
118
static linkclass decodelist = NULL;
119
120
/* ISA mask value enforced via disassembler info options.  ARC_OPCODE_NONE
121
   value means that no CPU is enforced.  */
122
123
static unsigned enforced_isa_mask = ARC_OPCODE_NONE;
124
125
/* True if we want to print using only hex numbers.  */
126
static bool print_hex = false;
127
128
/* Macros section.  */
129
130
#ifdef DEBUG
131
# define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
132
#else
133
# define pr_debug(fmt, args...)
134
#endif
135
136
#define ARRANGE_ENDIAN(info, buf)         \
137
224k
  (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))  \
138
224k
   : bfd_getb32 (buf))
139
140
522k
#define BITS(word,s,e)  (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1))
141
522k
#define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31))
142
143
/* Functions implementation.  */
144
145
/* Initialize private data.  */
146
static bool
147
init_arc_disasm_info (struct disassemble_info *info)
148
2.81k
{
149
2.81k
  struct arc_disassemble_info *arc_infop
150
2.81k
    = calloc (1, sizeof (*arc_infop));
151
152
2.81k
  if (arc_infop == NULL)
153
0
    return false;
154
155
2.81k
  info->private_data = arc_infop;
156
2.81k
  return true;
157
2.81k
}
158
159
/* Add a new element to the decode list.  */
160
161
static void
162
add_to_decodelist (insn_class_t     insn_class,
163
       insn_subclass_t  subclass)
164
43.7k
{
165
43.7k
  linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
166
167
43.7k
  t->insn_class = insn_class;
168
43.7k
  t->subclass = subclass;
169
43.7k
  t->nxt = decodelist;
170
43.7k
  decodelist = t;
171
43.7k
}
172
173
/* Return TRUE if we need to skip the opcode from being
174
   disassembled.  */
175
176
static bool
177
skip_this_opcode (const struct arc_opcode *opcode)
178
164k
{
179
164k
  linkclass t = decodelist;
180
181
  /* Check opcode for major 0x06, return if it is not in.  */
182
164k
  if (arc_opcode_len (opcode) == 4
183
164k
      && (OPCODE_32BIT_INSN (opcode->opcode) != 0x06
184
    /* Can be an APEX extensions.  */
185
164k
    && OPCODE_32BIT_INSN (opcode->opcode) != 0x07))
186
150k
    return false;
187
188
  /* or not a known truble class.  */
189
14.7k
  switch (opcode->insn_class)
190
14.7k
    {
191
8.67k
    case FLOAT:
192
10.7k
    case DSP:
193
12.0k
    case ARITH:
194
12.5k
    case MPY:
195
12.5k
      break;
196
2.19k
    default:
197
2.19k
      return false;
198
14.7k
    }
199
200
126M
  while (t != NULL)
201
126M
    {
202
126M
      if ((t->insn_class == opcode->insn_class)
203
126M
    && (t->subclass == opcode->subclass))
204
5.69k
  return false;
205
126M
      t = t->nxt;
206
126M
    }
207
208
6.90k
  return true;
209
12.5k
}
210
211
static bfd_vma
212
bfd_getm32 (unsigned int data)
213
223k
{
214
223k
  bfd_vma value = 0;
215
216
223k
  value = ((data & 0xff00) | (data & 0xff)) << 16;
217
223k
  value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
218
223k
  return value;
219
223k
}
220
221
static bool
222
special_flag_p (const char *opname,
223
    const char *flgname)
224
97.1k
{
225
97.1k
  const struct arc_flag_special *flg_spec;
226
97.1k
  unsigned i, j, flgidx;
227
228
840k
  for (i = 0; i < arc_num_flag_special; i++)
229
765k
    {
230
765k
      flg_spec = &arc_flag_special_cases[i];
231
232
765k
      if (strcmp (opname, flg_spec->name))
233
700k
  continue;
234
235
      /* Found potential special case instruction.  */
236
942k
      for (j=0;; ++j)
237
1.00M
  {
238
1.00M
    flgidx = flg_spec->flags[j];
239
1.00M
    if (flgidx == 0)
240
42.5k
      break; /* End of the array.  */
241
242
964k
    if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
243
22.3k
      return true;
244
964k
  }
245
64.8k
    }
246
74.8k
  return false;
247
97.1k
}
248
249
/* Find opcode from ARC_TABLE given the instruction described by INSN and
250
   INSNLEN.  The ISA_MASK restricts the possible matches in ARC_TABLE.  */
251
252
static const struct arc_opcode *
253
find_format_from_table (struct disassemble_info *info,
254
      const struct arc_opcode *arc_table,
255
                        unsigned long long insn,
256
      unsigned int insn_len,
257
                        unsigned isa_mask,
258
      bool *has_limm,
259
      bool overlaps)
260
517k
{
261
517k
  unsigned int i = 0;
262
517k
  const struct arc_opcode *opcode = NULL;
263
517k
  const struct arc_opcode *t_op = NULL;
264
517k
  const unsigned char *opidx;
265
517k
  const unsigned char *flgidx;
266
517k
  bool warn_p = false;
267
268
517k
  do
269
1.40G
    {
270
1.40G
      bool invalid = false;
271
272
1.40G
      opcode = &arc_table[i++];
273
274
1.40G
      if (!(opcode->cpu & isa_mask))
275
667M
  continue;
276
277
739M
      if (arc_opcode_len (opcode) != (int) insn_len)
278
440M
  continue;
279
280
299M
      if ((insn & opcode->mask) != opcode->opcode)
281
298M
  continue;
282
283
492k
      *has_limm = false;
284
285
      /* Possible candidate, check the operands.  */
286
1.91M
      for (opidx = opcode->operands; *opidx; opidx++)
287
1.44M
  {
288
1.44M
    int value, limmind;
289
1.44M
    const struct arc_operand *operand = &arc_operands[*opidx];
290
291
1.44M
    if (operand->flags & ARC_OPERAND_FAKE)
292
309k
      continue;
293
294
1.13M
    if (operand->extract)
295
967k
      value = (*operand->extract) (insn, &invalid);
296
165k
    else
297
165k
      value = (insn >> operand->shift) & ((1ull << operand->bits) - 1);
298
299
    /* Check for LIMM indicator.  If it is there, then make sure
300
       we pick the right format.  */
301
1.13M
    limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
302
1.13M
    if (operand->flags & ARC_OPERAND_IR
303
1.13M
        && !(operand->flags & ARC_OPERAND_LIMM))
304
615k
      {
305
615k
        if ((value == 0x3E && insn_len == 4)
306
615k
      || (value == limmind && insn_len == 2))
307
17.0k
    {
308
17.0k
      invalid = true;
309
17.0k
      break;
310
17.0k
    }
311
615k
      }
312
313
1.11M
    if (operand->flags & ARC_OPERAND_LIMM
314
1.11M
        && !(operand->flags & ARC_OPERAND_DUPLICATE))
315
10.8k
      *has_limm = true;
316
1.11M
  }
317
318
      /* Check the flags.  */
319
858k
      for (flgidx = opcode->flags; *flgidx; flgidx++)
320
373k
  {
321
    /* Get a valid flag class.  */
322
373k
    const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
323
373k
    const unsigned *flgopridx;
324
373k
    int foundA = 0, foundB = 0;
325
373k
    unsigned int value;
326
327
    /* Check first the extensions.  */
328
373k
    if (cl_flags->flag_class & F_CLASS_EXTEND)
329
74.4k
      {
330
74.4k
        value = (insn & 0x1F);
331
74.4k
        if (arcExtMap_condCodeName (value))
332
0
    continue;
333
74.4k
      }
334
335
    /* Check for the implicit flags.  */
336
373k
    if (cl_flags->flag_class & F_CLASS_IMPLICIT)
337
73.8k
      continue;
338
339
2.96M
    for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
340
2.66M
      {
341
2.66M
        const struct arc_flag_operand *flg_operand =
342
2.66M
    &arc_flag_operands[*flgopridx];
343
344
2.66M
        value = (insn >> flg_operand->shift)
345
2.66M
    & ((1 << flg_operand->bits) - 1);
346
2.66M
        if (value == flg_operand->code)
347
356k
    foundA = 1;
348
2.66M
        if (value)
349
1.14M
    foundB = 1;
350
2.66M
      }
351
352
299k
    if (!foundA && foundB)
353
8.21k
      {
354
8.21k
        invalid = true;
355
8.21k
        break;
356
8.21k
      }
357
299k
  }
358
359
492k
      if (invalid)
360
27.6k
  continue;
361
362
465k
      if (insn_len == 4
363
465k
    && overlaps)
364
164k
  {
365
164k
    warn_p = true;
366
164k
    t_op = opcode;
367
164k
    if (skip_this_opcode (opcode))
368
6.90k
      continue;
369
164k
  }
370
371
      /* The instruction is valid.  */
372
458k
      return opcode;
373
465k
    }
374
1.40G
  while (opcode->mask);
375
376
58.7k
  if (warn_p)
377
5.87k
    {
378
5.87k
      info->fprintf_styled_func
379
5.87k
  (info->stream, dis_style_text,
380
5.87k
   _("\nWarning: disassembly may be wrong due to "
381
5.87k
     "guessed opcode class choice.\n"
382
5.87k
     "Use -M<class[,class]> to select the correct "
383
5.87k
     "opcode class(es).\n\t\t\t\t"));
384
5.87k
      return t_op;
385
5.87k
    }
386
387
52.9k
  return NULL;
388
58.7k
}
389
390
/* Find opcode for INSN, trying various different sources.  The instruction
391
   length in INSN_LEN will be updated if the instruction requires a LIMM
392
   extension.
393
394
   A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
395
   initialised, ready to iterate over the operands of the found opcode.  If
396
   the found opcode requires a LIMM then the LIMM value will be loaded into a
397
   field of ITER.
398
399
   This function returns TRUE in almost all cases, FALSE is reserved to
400
   indicate an error (failing to find an opcode is not an error) a returned
401
   result of FALSE would indicate that the disassembler can't continue.
402
403
   If no matching opcode is found then the returned result will be TRUE, the
404
   value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
405
   INSN_LEN will be unchanged.
406
407
   If a matching opcode is found, then the returned result will be TRUE, the
408
   opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
409
   4 if the instruction requires a LIMM, and the LIMM value will have been
410
   loaded into a field of ITER.  Finally, ITER will have been initialised so
411
   that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
412
   operands.  */
413
414
static bool
415
find_format (bfd_vma                       memaddr,
416
       unsigned long long            insn,
417
       unsigned int *                insn_len,
418
             unsigned                      isa_mask,
419
       struct disassemble_info *     info,
420
             const struct arc_opcode **    opcode_result,
421
             struct arc_operand_iterator * iter)
422
517k
{
423
517k
  const struct arc_opcode *opcode = NULL;
424
517k
  bool needs_limm = false;
425
517k
  const extInstruction_t *einsn, *i;
426
517k
  unsigned limm = 0;
427
517k
  struct arc_disassemble_info *arc_infop = info->private_data;
428
429
  /* First, try the extension instructions.  */
430
517k
  if (*insn_len == 4)
431
204k
    {
432
204k
      einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
433
204k
      for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
434
0
  {
435
0
    const char *errmsg = NULL;
436
437
0
    opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
438
0
    if (opcode == NULL)
439
0
      {
440
0
        (*info->fprintf_styled_func)
441
0
    (info->stream, dis_style_text,
442
0
     _("An error occurred while generating "
443
0
       "the extension instruction operations"));
444
0
        *opcode_result = NULL;
445
0
        return false;
446
0
      }
447
448
0
    opcode = find_format_from_table (info, opcode, insn, *insn_len,
449
0
             isa_mask, &needs_limm, false);
450
0
  }
451
204k
    }
452
453
  /* Then, try finding the first match in the opcode table.  */
454
517k
  if (opcode == NULL)
455
517k
    opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
456
517k
             isa_mask, &needs_limm, true);
457
458
517k
  if (opcode != NULL && needs_limm)
459
5.85k
    {
460
5.85k
      bfd_byte buffer[4];
461
5.85k
      int status;
462
463
5.85k
      status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
464
5.85k
                                          4, info);
465
5.85k
      if (status != 0)
466
26
        {
467
26
          opcode = NULL;
468
26
        }
469
5.82k
      else
470
5.82k
        {
471
5.82k
          limm = ARRANGE_ENDIAN (info, buffer);
472
5.82k
          *insn_len += 4;
473
5.82k
        }
474
5.85k
    }
475
476
517k
  if (opcode != NULL)
477
464k
    {
478
464k
      iter->insn = insn;
479
464k
      iter->limm = limm;
480
464k
      iter->opcode = opcode;
481
464k
      iter->opidx = opcode->operands;
482
464k
    }
483
484
517k
  *opcode_result = opcode;
485
486
  /* Update private data.  */
487
517k
  arc_infop->opcode = opcode;
488
517k
  arc_infop->limm = limm;
489
517k
  arc_infop->limm_p = needs_limm;
490
491
517k
  return true;
492
517k
}
493
494
static void
495
print_flags (const struct arc_opcode *opcode,
496
       unsigned long long *insn,
497
       struct disassemble_info *info)
498
464k
{
499
464k
  const unsigned char *flgidx;
500
464k
  unsigned int value;
501
464k
  struct arc_disassemble_info *arc_infop = info->private_data;
502
503
  /* Now extract and print the flags.  */
504
811k
  for (flgidx = opcode->flags; *flgidx; flgidx++)
505
346k
    {
506
      /* Get a valid flag class.  */
507
346k
      const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
508
346k
      const unsigned *flgopridx;
509
510
      /* Check first the extensions.  */
511
346k
      if (cl_flags->flag_class & F_CLASS_EXTEND)
512
68.7k
  {
513
68.7k
    const char *name;
514
68.7k
    value = (insn[0] & 0x1F);
515
516
68.7k
    name = arcExtMap_condCodeName (value);
517
68.7k
    if (name)
518
0
      {
519
0
        (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
520
0
              ".%s", name);
521
0
        continue;
522
0
      }
523
68.7k
  }
524
525
2.87M
      for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
526
2.52M
  {
527
2.52M
    const struct arc_flag_operand *flg_operand =
528
2.52M
      &arc_flag_operands[*flgopridx];
529
530
    /* Implicit flags are only used for the insn decoder.  */
531
2.52M
    if (cl_flags->flag_class & F_CLASS_IMPLICIT)
532
73.7k
      {
533
73.7k
        if (cl_flags->flag_class & F_CLASS_COND)
534
22.7k
    arc_infop->condition_code = flg_operand->code;
535
50.9k
        else if (cl_flags->flag_class & F_CLASS_WB)
536
1.44k
    arc_infop->writeback_mode = flg_operand->code;
537
49.4k
        else if (cl_flags->flag_class & F_CLASS_ZZ)
538
49.4k
    info->data_size = flg_operand->code;
539
73.7k
        continue;
540
73.7k
      }
541
542
2.45M
    if (!flg_operand->favail)
543
953k
      continue;
544
545
1.49M
    value = (insn[0] >> flg_operand->shift)
546
1.49M
      & ((1 << flg_operand->bits) - 1);
547
1.49M
    if (value == flg_operand->code)
548
97.1k
      {
549
         /* FIXME!: print correctly nt/t flag.  */
550
97.1k
        if (!special_flag_p (opcode->name, flg_operand->name))
551
74.8k
    (*info->fprintf_styled_func) (info->stream,
552
74.8k
                dis_style_mnemonic, ".");
553
22.3k
        else if (info->insn_type == dis_dref)
554
9.10k
    {
555
9.10k
      switch (flg_operand->name[0])
556
9.10k
        {
557
3.51k
        case 'b':
558
3.51k
          info->data_size = 1;
559
3.51k
          break;
560
5.58k
        case 'h':
561
5.58k
        case 'w':
562
5.58k
          info->data_size = 2;
563
5.58k
          break;
564
0
        default:
565
0
          info->data_size = 4;
566
0
          break;
567
9.10k
        }
568
9.10k
    }
569
97.1k
        if (flg_operand->name[0] == 'd'
570
97.1k
      && flg_operand->name[1] == 0)
571
22.2k
    info->branch_delay_insns = 1;
572
573
        /* Check if it is a conditional flag.  */
574
97.1k
        if (cl_flags->flag_class & F_CLASS_COND)
575
18.9k
    {
576
18.9k
      if (info->insn_type == dis_jsr)
577
3.05k
        info->insn_type = dis_condjsr;
578
15.9k
      else if (info->insn_type == dis_branch)
579
11.6k
        info->insn_type = dis_condbranch;
580
18.9k
      arc_infop->condition_code = flg_operand->code;
581
18.9k
    }
582
583
        /* Check for the write back modes.  */
584
97.1k
        if (cl_flags->flag_class & F_CLASS_WB)
585
10.1k
    arc_infop->writeback_mode = flg_operand->code;
586
587
97.1k
        (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
588
97.1k
              "%s", flg_operand->name);
589
97.1k
      }
590
1.49M
  }
591
346k
    }
592
464k
}
593
594
static const char *
595
get_auxreg (const struct arc_opcode *opcode,
596
      int value,
597
      unsigned isa_mask)
598
470k
{
599
470k
  const char *name;
600
470k
  unsigned int i;
601
470k
  const struct arc_aux_reg *auxr = &arc_aux_regs[0];
602
603
470k
  if (opcode->insn_class != AUXREG)
604
464k
    return NULL;
605
606
6.44k
  name = arcExtMap_auxRegName (value);
607
6.44k
  if (name)
608
0
    return name;
609
610
965k
  for (i = 0; i < arc_num_aux_regs; i++, auxr++)
611
964k
    {
612
964k
      if (!(auxr->cpu & isa_mask))
613
358k
  continue;
614
615
606k
      if (auxr->subclass != NONE)
616
2.01k
  return NULL;
617
618
604k
      if (auxr->address == value)
619
3.45k
  return auxr->name;
620
604k
    }
621
980
  return NULL;
622
6.44k
}
623
624
/* Convert a value representing an address type to a string used to refer to
625
   the address type in assembly code.  */
626
627
static const char *
628
get_addrtype (int value)
629
3.10k
{
630
3.10k
  if (value < 0 || value > addrtypenames_max)
631
0
    return addrtypeunknown;
632
633
3.10k
  return addrtypenames[value];
634
3.10k
}
635
636
/* Calculate the instruction length for an instruction starting with MSB
637
   and LSB, the most and least significant byte.  The ISA_MASK is used to
638
   filter the instructions considered to only those that are part of the
639
   current architecture.
640
641
   The instruction lengths are calculated from the ARC_OPCODE table, and
642
   cached for later use.  */
643
644
static unsigned int
645
arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
646
518k
{
647
518k
  bfd_byte major_opcode = msb >> 3;
648
649
518k
  switch (info->mach)
650
518k
    {
651
243k
    case bfd_mach_arc_arc700:
652
      /* The nps400 extension set requires this special casing of the
653
   instruction length calculation.  Right now this is not causing any
654
   problems as none of the known extensions overlap in opcode space,
655
   but, if they ever do then we might need to start carrying
656
   information around in the elf about which extensions are in use.  */
657
243k
      if (major_opcode == 0xb)
658
12.8k
        {
659
12.8k
          bfd_byte minor_opcode = lsb & 0x1f;
660
661
12.8k
    if (minor_opcode < 4)
662
1.81k
      return 6;
663
11.0k
    else if (minor_opcode == 0x10 || minor_opcode == 0x11)
664
2.24k
      return 8;
665
12.8k
        }
666
239k
      if (major_opcode == 0xa)
667
3.85k
        {
668
3.85k
          return 8;
669
3.85k
        }
670
      /* Fall through.  */
671
268k
    case bfd_mach_arc_arc600:
672
268k
      return (major_opcode > 0xb) ? 2 : 4;
673
0
      break;
674
675
241k
    case bfd_mach_arc_arcv2:
676
241k
      return (major_opcode > 0x7) ? 2 : 4;
677
0
      break;
678
679
5
    default:
680
5
      return 0;
681
518k
    }
682
518k
}
683
684
/* Extract and return the value of OPERAND from the instruction whose value
685
   is held in the array INSN.  */
686
687
static int
688
extract_operand_value (const struct arc_operand *operand,
689
           unsigned long long insn,
690
           unsigned limm)
691
1.34M
{
692
1.34M
  int value;
693
694
  /* Read the limm operand, if required.  */
695
1.34M
  if (operand->flags & ARC_OPERAND_LIMM)
696
    /* The second part of the instruction value will have been loaded as
697
       part of the find_format call made earlier.  */
698
9.63k
    value = limm;
699
1.33M
  else
700
1.33M
    {
701
1.33M
      if (operand->extract)
702
916k
  value = (*operand->extract) (insn, (bool *) NULL);
703
414k
      else
704
414k
        {
705
414k
          if (operand->flags & ARC_OPERAND_ALIGNED32)
706
0
            {
707
0
              value = (insn >> operand->shift)
708
0
                & ((1 << (operand->bits - 2)) - 1);
709
0
              value = value << 2;
710
0
            }
711
414k
          else
712
414k
            {
713
414k
              value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
714
414k
            }
715
414k
          if (operand->flags & ARC_OPERAND_SIGNED)
716
673
            {
717
673
              int signbit = 1 << (operand->bits - 1);
718
673
              value = (value ^ signbit) - signbit;
719
673
            }
720
414k
        }
721
1.33M
    }
722
723
1.34M
  return value;
724
1.34M
}
725
726
/* Find the next operand, and the operands value from ITER.  Return TRUE if
727
   there is another operand, otherwise return FALSE.  If there is an
728
   operand returned then the operand is placed into OPERAND, and the value
729
   into VALUE.  If there is no operand returned then OPERAND and VALUE are
730
   unchanged.  */
731
732
static bool
733
operand_iterator_next (struct arc_operand_iterator *iter,
734
                       const struct arc_operand **operand,
735
                       int *value)
736
1.80M
{
737
1.80M
  if (*iter->opidx == 0)
738
464k
    {
739
464k
      *operand = NULL;
740
464k
      return false;
741
464k
    }
742
743
1.34M
  *operand = &arc_operands[*iter->opidx];
744
1.34M
  *value = extract_operand_value (*operand, iter->insn, iter->limm);
745
1.34M
  iter->opidx++;
746
747
1.34M
  return true;
748
1.80M
}
749
750
/* Helper for parsing the options.  */
751
752
static void
753
parse_option (const char *option)
754
6.82k
{
755
6.82k
  if (disassembler_options_cmp (option, "dsp") == 0)
756
78
    add_to_decodelist (DSP, NONE);
757
758
6.74k
  else if (disassembler_options_cmp (option, "spfp") == 0)
759
138
    add_to_decodelist (FLOAT, SPX);
760
761
6.61k
  else if (disassembler_options_cmp (option, "dpfp") == 0)
762
40
    add_to_decodelist (FLOAT, DPX);
763
764
6.57k
  else if (disassembler_options_cmp (option, "quarkse_em") == 0)
765
0
    {
766
0
      add_to_decodelist (FLOAT, DPX);
767
0
      add_to_decodelist (FLOAT, SPX);
768
0
      add_to_decodelist (FLOAT, QUARKSE1);
769
0
      add_to_decodelist (FLOAT, QUARKSE2);
770
0
    }
771
772
6.57k
  else if (disassembler_options_cmp (option, "fpuda") == 0)
773
38
    add_to_decodelist (FLOAT, DPA);
774
775
6.53k
  else if (disassembler_options_cmp (option, "nps400") == 0)
776
0
    {
777
0
      add_to_decodelist (ACL, NPS400);
778
0
      add_to_decodelist (ARITH, NPS400);
779
0
      add_to_decodelist (BITOP, NPS400);
780
0
      add_to_decodelist (BMU, NPS400);
781
0
      add_to_decodelist (CONTROL, NPS400);
782
0
      add_to_decodelist (DMA, NPS400);
783
0
      add_to_decodelist (DPI, NPS400);
784
0
      add_to_decodelist (MEMORY, NPS400);
785
0
      add_to_decodelist (MISC, NPS400);
786
0
      add_to_decodelist (NET, NPS400);
787
0
      add_to_decodelist (PMU, NPS400);
788
0
      add_to_decodelist (PROTOCOL_DECODE, NPS400);
789
0
      add_to_decodelist (ULTRAIP, NPS400);
790
0
    }
791
792
6.53k
  else if (disassembler_options_cmp (option, "fpus") == 0)
793
46
    {
794
46
      add_to_decodelist (FLOAT, SP);
795
46
      add_to_decodelist (FLOAT, CVT);
796
46
    }
797
798
6.48k
  else if (disassembler_options_cmp (option, "fpud") == 0)
799
46
    {
800
46
      add_to_decodelist (FLOAT, DP);
801
46
      add_to_decodelist (FLOAT, CVT);
802
46
    }
803
6.44k
  else if (startswith (option, "hex"))
804
156
    print_hex = true;
805
6.28k
  else
806
    /* xgettext:c-format */
807
6.28k
    opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
808
6.82k
}
809
810
#define ARC_CPU_TYPE_A6xx(NAME,EXTRA)     \
811
  { #NAME, ARC_OPCODE_ARC600, "ARC600" }
812
#define ARC_CPU_TYPE_A7xx(NAME,EXTRA)     \
813
  { #NAME, ARC_OPCODE_ARC700, "ARC700" }
814
#define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)      \
815
  { #NAME,  ARC_OPCODE_ARCv2EM, "ARC EM" }
816
#define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)      \
817
  { #NAME,  ARC_OPCODE_ARCv2HS, "ARC HS" }
818
#define ARC_CPU_TYPE_NONE       \
819
  { 0, 0, 0 }
820
821
/* A table of CPU names and opcode sets.  */
822
static const struct cpu_type
823
{
824
  const char *name;
825
  unsigned flags;
826
  const char *isa;
827
}
828
  cpu_types[] =
829
{
830
  #include "elf/arc-cpu.def"
831
};
832
833
/* Helper for parsing the CPU options.  Accept any of the ARC architectures
834
   values.  OPTION should be a value passed to cpu=.  */
835
836
static unsigned
837
parse_cpu_option (const char *option)
838
372
{
839
372
  int i;
840
841
6.98k
  for (i = 0; cpu_types[i].name; ++i)
842
6.81k
    {
843
6.81k
      if (!disassembler_options_cmp (cpu_types[i].name, option))
844
202
  {
845
202
    return cpu_types[i].flags;
846
202
  }
847
6.81k
    }
848
849
  /* xgettext:c-format */
850
170
  opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
851
170
  return ARC_OPCODE_NONE;
852
372
}
853
854
/* Go over the options list and parse it.  */
855
856
static void
857
parse_disassembler_options (const char *options)
858
2.49k
{
859
2.49k
  const char *option;
860
861
2.49k
  if (options == NULL)
862
0
    return;
863
864
  /* Disassembler might be reused for difference CPU's, and cpu option set for
865
     the first one shouldn't be applied to second (which might not have
866
     explicit cpu in its options.  Therefore it is required to reset enforced
867
     CPU when new options are being parsed.  */
868
2.49k
  enforced_isa_mask = ARC_OPCODE_NONE;
869
870
2.49k
  FOR_EACH_DISASSEMBLER_OPTION (option, options)
871
7.19k
    {
872
      /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
873
   preprocessor macro.  */
874
7.19k
      if (strncmp (option, "cpu=", 4) == 0)
875
  /* Strip leading `cpu=`.  */
876
372
  enforced_isa_mask = parse_cpu_option (option + 4);
877
6.82k
      else
878
6.82k
  parse_option (option);
879
7.19k
    }
880
2.49k
}
881
882
/* Return the instruction type for an instruction described by OPCODE.  */
883
884
static enum dis_insn_type
885
arc_opcode_to_insn_type (const struct arc_opcode *opcode)
886
464k
{
887
464k
  enum dis_insn_type insn_type;
888
889
464k
  switch (opcode->insn_class)
890
464k
    {
891
164k
    case BRANCH:
892
164k
    case BBIT0:
893
166k
    case BBIT1:
894
167k
    case BI:
895
167k
    case BIH:
896
180k
    case BRCC:
897
181k
    case DBNZ:
898
186k
    case EI:
899
189k
    case JLI:
900
192k
    case JUMP:
901
193k
    case LOOP:
902
193k
      if (!strncmp (opcode->name, "bl", 2)
903
193k
    || !strncmp (opcode->name, "jl", 2))
904
76.0k
  {
905
76.0k
    if (opcode->subclass == COND)
906
1.45k
      insn_type = dis_condjsr;
907
74.6k
    else
908
74.6k
      insn_type = dis_jsr;
909
76.0k
  }
910
117k
      else
911
117k
  {
912
117k
    if (opcode->subclass == COND)
913
21.4k
      insn_type = dis_condbranch;
914
95.7k
    else
915
95.7k
      insn_type = dis_branch;
916
117k
  }
917
193k
      break;
918
80.2k
    case LOAD:
919
122k
    case STORE:
920
123k
    case MEMORY:
921
124k
    case ENTER:
922
124k
    case PUSH:
923
125k
    case POP:
924
125k
      insn_type = dis_dref;
925
125k
      break;
926
6.72k
    case LEAVE:
927
6.72k
      insn_type = dis_branch;
928
6.72k
      break;
929
138k
    default:
930
138k
      insn_type = dis_nonbranch;
931
138k
      break;
932
464k
    }
933
934
464k
  return insn_type;
935
464k
}
936
937
/* Disassemble ARC instructions.  */
938
939
static int
940
print_insn_arc (bfd_vma memaddr,
941
    struct disassemble_info *info)
942
520k
{
943
520k
  bfd_byte buffer[8];
944
520k
  unsigned int highbyte, lowbyte;
945
520k
  int status;
946
520k
  unsigned int insn_len;
947
520k
  unsigned long long insn = 0;
948
520k
  unsigned isa_mask = ARC_OPCODE_NONE;
949
520k
  const struct arc_opcode *opcode;
950
520k
  bool need_comma;
951
520k
  bool open_braket;
952
520k
  int size;
953
520k
  const struct arc_operand *operand;
954
520k
  int value, vpcl;
955
520k
  struct arc_operand_iterator iter;
956
520k
  struct arc_disassemble_info *arc_infop;
957
520k
  bool rpcl = false, rset = false;
958
959
520k
  if (info->disassembler_options)
960
2.49k
    {
961
2.49k
      parse_disassembler_options (info->disassembler_options);
962
963
      /* Avoid repeated parsing of the options.  */
964
2.49k
      info->disassembler_options = NULL;
965
2.49k
    }
966
967
520k
  if (info->private_data == NULL && !init_arc_disasm_info (info))
968
0
    return -1;
969
970
520k
  memset (&iter, 0, sizeof (iter));
971
520k
  highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
972
520k
  lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
973
974
  /* Figure out CPU type, unless it was enforced via disassembler options.  */
975
520k
  if (enforced_isa_mask == ARC_OPCODE_NONE)
976
507k
    {
977
507k
      Elf_Internal_Ehdr *header = NULL;
978
979
507k
      if (info->section && info->section->owner)
980
2.37k
  header = elf_elfheader (info->section->owner);
981
982
507k
      switch (info->mach)
983
507k
  {
984
243k
  case bfd_mach_arc_arc700:
985
243k
    isa_mask = ARC_OPCODE_ARC700;
986
243k
    break;
987
988
20.6k
  case bfd_mach_arc_arc600:
989
20.6k
    isa_mask = ARC_OPCODE_ARC600;
990
20.6k
    break;
991
992
242k
  case bfd_mach_arc_arcv2:
993
242k
  default:
994
242k
    isa_mask = ARC_OPCODE_ARCv2EM;
995
    /* TODO: Perhaps remove definition of header since it is only used at
996
       this location.  */
997
242k
    if (header != NULL
998
242k
        && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
999
1.31k
      isa_mask = ARC_OPCODE_ARCv2HS;
1000
242k
    break;
1001
507k
  }
1002
507k
    }
1003
13.1k
  else
1004
13.1k
    isa_mask = enforced_isa_mask;
1005
1006
520k
  if (isa_mask == ARC_OPCODE_ARCv2HS)
1007
14.4k
    {
1008
      /* FPU instructions are not extensions for HS.  */
1009
14.4k
      add_to_decodelist (FLOAT, SP);
1010
14.4k
      add_to_decodelist (FLOAT, DP);
1011
14.4k
      add_to_decodelist (FLOAT, CVT);
1012
14.4k
    }
1013
1014
  /* This variable may be set by the instruction decoder.  It suggests
1015
     the number of bytes objdump should display on a single line.  If
1016
     the instruction decoder sets this, it should always set it to
1017
     the same value in order to get reasonable looking output.  */
1018
520k
  info->bytes_per_line  = 8;
1019
1020
  /* In the next lines, we set two info variables control the way
1021
     objdump displays the raw data.  For example, if bytes_per_line is
1022
     8 and bytes_per_chunk is 4, the output will look like this:
1023
     00:   00000000 00000000
1024
     with the chunks displayed according to "display_endian".  */
1025
520k
  if (info->section
1026
520k
      && !(info->section->flags & SEC_CODE))
1027
1.27k
    {
1028
      /* This is not a CODE section.  */
1029
1.27k
      switch (info->section->size)
1030
1.27k
  {
1031
2
  case 1:
1032
3
  case 2:
1033
4
  case 4:
1034
4
    size = info->section->size;
1035
4
    break;
1036
1.26k
  default:
1037
1.26k
    size = (info->section->size & 0x01) ? 1 : 4;
1038
1.26k
    break;
1039
1.27k
  }
1040
1.27k
      info->bytes_per_chunk = 1;
1041
1.27k
      info->display_endian = info->endian;
1042
1.27k
    }
1043
519k
  else
1044
519k
    {
1045
519k
      size = 2;
1046
519k
      info->bytes_per_chunk = 2;
1047
519k
      info->display_endian = info->endian;
1048
519k
    }
1049
1050
  /* Read the insn into a host word.  */
1051
520k
  status = (*info->read_memory_func) (memaddr, buffer, size, info);
1052
1053
520k
  if (status != 0)
1054
1.10k
    {
1055
1.10k
      (*info->memory_error_func) (status, memaddr, info);
1056
1.10k
      return -1;
1057
1.10k
    }
1058
1059
519k
  if (info->section
1060
519k
      && !(info->section->flags & SEC_CODE))
1061
1.27k
    {
1062
      /* Data section.  */
1063
1.27k
      unsigned long data;
1064
1065
1.27k
      data = bfd_get_bits (buffer, size * 8,
1066
1.27k
         info->display_endian == BFD_ENDIAN_BIG);
1067
1.27k
      switch (size)
1068
1.27k
  {
1069
996
  case 1:
1070
996
    (*info->fprintf_styled_func) (info->stream,
1071
996
          dis_style_assembler_directive,
1072
996
          ".byte");
1073
996
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1074
996
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1075
996
          "0x%02lx", data);
1076
996
    break;
1077
1
  case 2:
1078
1
    (*info->fprintf_styled_func) (info->stream,
1079
1
          dis_style_assembler_directive,
1080
1
          ".short");
1081
1
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1082
1
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1083
1
          "0x%04lx", data);
1084
1
    break;
1085
275
  case 4:
1086
275
    (*info->fprintf_styled_func) (info->stream,
1087
275
          dis_style_assembler_directive,
1088
275
          ".word");
1089
275
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1090
275
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1091
275
          "0x%08lx", data);
1092
275
    break;
1093
0
  default:
1094
0
    return -1;
1095
1.27k
  }
1096
1.27k
      return size;
1097
1.27k
    }
1098
1099
518k
  insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1100
518k
  pr_debug ("instruction length = %d bytes\n", insn_len);
1101
518k
  if (insn_len == 0)
1102
5
    return -1;
1103
1104
518k
  arc_infop = info->private_data;
1105
518k
  arc_infop->insn_len = insn_len;
1106
1107
518k
  switch (insn_len)
1108
518k
    {
1109
304k
    case 2:
1110
304k
      insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1111
304k
      break;
1112
1113
205k
    case 4:
1114
205k
      {
1115
  /* This is a long instruction: Read the remaning 2 bytes.  */
1116
205k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1117
205k
  if (status != 0)
1118
881
    {
1119
881
      (*info->memory_error_func) (status, memaddr + 2, info);
1120
881
      return -1;
1121
881
    }
1122
204k
  insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1123
204k
      }
1124
0
      break;
1125
1126
1.81k
    case 6:
1127
1.81k
      {
1128
1.81k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1129
1.81k
  if (status != 0)
1130
7
    {
1131
7
      (*info->memory_error_func) (status, memaddr + 2, info);
1132
7
      return -1;
1133
7
    }
1134
1.80k
  insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1135
1.80k
  insn |= ((unsigned long long) buffer[highbyte] << 40)
1136
1.80k
    | ((unsigned long long) buffer[lowbyte] << 32);
1137
1.80k
      }
1138
0
      break;
1139
1140
6.10k
    case 8:
1141
6.10k
      {
1142
6.10k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1143
6.10k
  if (status != 0)
1144
14
    {
1145
14
      (*info->memory_error_func) (status, memaddr + 2, info);
1146
14
      return -1;
1147
14
    }
1148
6.08k
  insn =
1149
6.08k
    ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1150
6.08k
     | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1151
6.08k
      }
1152
0
      break;
1153
1154
0
    default:
1155
      /* There is no instruction whose length is not 2, 4, 6, or 8.  */
1156
0
      return -1;
1157
518k
    }
1158
1159
517k
  pr_debug ("instruction value = %llx\n", insn);
1160
1161
  /* Set some defaults for the insn info.  */
1162
517k
  info->insn_info_valid    = 1;
1163
517k
  info->branch_delay_insns = 0;
1164
517k
  info->data_size    = 4;
1165
517k
  info->insn_type    = dis_nonbranch;
1166
517k
  info->target       = 0;
1167
517k
  info->target2      = 0;
1168
1169
  /* FIXME to be moved in dissasemble_init_for_target.  */
1170
517k
  info->disassembler_needs_relocs = true;
1171
1172
  /* Find the first match in the opcode table.  */
1173
517k
  if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1174
0
    return -1;
1175
1176
517k
  if (!opcode)
1177
52.9k
    {
1178
52.9k
      switch (insn_len)
1179
52.9k
  {
1180
8.07k
  case 2:
1181
8.07k
    (*info->fprintf_styled_func) (info->stream,
1182
8.07k
          dis_style_assembler_directive,
1183
8.07k
          ".short");
1184
8.07k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1185
8.07k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1186
8.07k
          "0x%04llx", insn & 0xffff);
1187
8.07k
    break;
1188
1189
40.7k
  case 4:
1190
40.7k
    (*info->fprintf_styled_func) (info->stream,
1191
40.7k
          dis_style_assembler_directive,
1192
40.7k
          ".word");
1193
40.7k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1194
40.7k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1195
40.7k
          "0x%08llx", insn & 0xffffffff);
1196
40.7k
    break;
1197
1198
403
  case 6:
1199
403
    (*info->fprintf_styled_func) (info->stream,
1200
403
          dis_style_assembler_directive,
1201
403
          ".long");
1202
403
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1203
403
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1204
403
               "0x%08llx", insn & 0xffffffff);
1205
403
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1206
403
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1207
403
          "0x%04llx", (insn >> 32) & 0xffff);
1208
403
    break;
1209
1210
3.74k
  case 8:
1211
3.74k
    (*info->fprintf_styled_func) (info->stream,
1212
3.74k
          dis_style_assembler_directive,
1213
3.74k
          ".long");
1214
3.74k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1215
3.74k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1216
3.74k
          "0x%08llx", insn & 0xffffffff);
1217
3.74k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1218
3.74k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1219
3.74k
          "0x%08llx", (insn >> 32));
1220
3.74k
    break;
1221
1222
0
  default:
1223
0
    return -1;
1224
52.9k
  }
1225
1226
52.9k
      info->insn_type = dis_noninsn;
1227
52.9k
      return insn_len;
1228
52.9k
    }
1229
1230
  /* Print the mnemonic.  */
1231
464k
  (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1232
464k
        "%s", opcode->name);
1233
1234
  /* Preselect the insn class.  */
1235
464k
  info->insn_type = arc_opcode_to_insn_type (opcode);
1236
1237
464k
  pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1238
1239
464k
  print_flags (opcode, &insn, info);
1240
1241
464k
  if (opcode->operands[0] != 0)
1242
463k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1243
1244
464k
  need_comma = false;
1245
464k
  open_braket = false;
1246
464k
  arc_infop->operands_count = 0;
1247
1248
  /* Now extract and print the operands.  */
1249
464k
  operand = NULL;
1250
464k
  vpcl = 0;
1251
1.80M
  while (operand_iterator_next (&iter, &operand, &value))
1252
1.34M
    {
1253
1.34M
      if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1254
144k
  {
1255
144k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
1256
144k
    open_braket = false;
1257
144k
    continue;
1258
144k
  }
1259
1260
      /* Only take input from real operands.  */
1261
1.19M
      if (ARC_OPERAND_IS_FAKE (operand))
1262
0
  continue;
1263
1264
1.19M
      if ((operand->flags & ARC_OPERAND_IGNORE)
1265
1.19M
    && (operand->flags & ARC_OPERAND_IR)
1266
1.19M
    && value == -1)
1267
13.9k
  continue;
1268
1269
1.18M
      if (operand->flags & ARC_OPERAND_COLON)
1270
3.10k
  {
1271
3.10k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, ":");
1272
3.10k
    continue;
1273
3.10k
  }
1274
1275
1.17M
      if (need_comma)
1276
568k
  (*info->fprintf_styled_func) (info->stream, dis_style_text,",");
1277
1278
1.17M
      if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1279
144k
  {
1280
144k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "[");
1281
144k
    open_braket = true;
1282
144k
    need_comma = false;
1283
144k
    continue;
1284
144k
  }
1285
1286
1.03M
      need_comma = true;
1287
1288
1.03M
      if (operand->flags & ARC_OPERAND_PCREL)
1289
186k
  {
1290
186k
    rpcl = true;
1291
186k
    vpcl = value;
1292
186k
    rset = true;
1293
1294
186k
    info->target = (bfd_vma) (memaddr & ~3) + value;
1295
186k
  }
1296
849k
      else if (!(operand->flags & ARC_OPERAND_IR))
1297
293k
  {
1298
293k
    vpcl = value;
1299
293k
    rset = true;
1300
293k
  }
1301
1302
      /* Print the operand as directed by the flags.  */
1303
1.03M
      if (operand->flags & ARC_OPERAND_IR)
1304
555k
  {
1305
555k
    const char *rname;
1306
1307
555k
    assert (value >=0 && value < 64);
1308
555k
    rname = arcExtMap_coreRegName (value);
1309
555k
    if (!rname)
1310
555k
      rname = regnames[value];
1311
555k
    (*info->fprintf_styled_func) (info->stream, dis_style_register,
1312
555k
          "%s", rname);
1313
1314
    /* Check if we have a double register to print.  */
1315
555k
    if (operand->flags & ARC_OPERAND_TRUNCATE)
1316
593
      {
1317
593
        if ((value & 0x01) == 0)
1318
334
    {
1319
334
      rname = arcExtMap_coreRegName (value + 1);
1320
334
      if (!rname)
1321
334
        rname = regnames[value + 1];
1322
334
    }
1323
259
        else
1324
259
    rname = _("\nWarning: illegal use of double register "
1325
593
        "pair.\n");
1326
593
        (*info->fprintf_styled_func) (info->stream, dis_style_register,
1327
593
              "%s", rname);
1328
593
      }
1329
555k
    if (value == 63)
1330
10.5k
      rpcl = true;
1331
544k
    else
1332
544k
      rpcl = false;
1333
555k
  }
1334
480k
      else if (operand->flags & ARC_OPERAND_LIMM)
1335
9.63k
  {
1336
9.63k
    const char *rname = get_auxreg (opcode, value, isa_mask);
1337
1338
9.63k
    if (rname && open_braket)
1339
1.15k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1340
1.15k
            "%s", rname);
1341
8.48k
    else
1342
8.48k
      {
1343
8.48k
        (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1344
8.48k
              "%#x", value);
1345
8.48k
        if (info->insn_type == dis_branch
1346
8.48k
      || info->insn_type == dis_jsr)
1347
424
    info->target = (bfd_vma) value;
1348
8.48k
      }
1349
9.63k
  }
1350
471k
      else if (operand->flags & ARC_OPERAND_SIGNED)
1351
216k
  {
1352
216k
    const char *rname = get_auxreg (opcode, value, isa_mask);
1353
216k
    if (rname && open_braket)
1354
284
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1355
284
            "%s", rname);
1356
215k
    else
1357
215k
      {
1358
215k
        if (print_hex)
1359
84.6k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1360
84.6k
                "%#x", value);
1361
131k
        else
1362
131k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1363
131k
                "%d", value);
1364
215k
      }
1365
216k
  }
1366
254k
      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1367
3.10k
  {
1368
3.10k
    const char *addrtype = get_addrtype (value);
1369
3.10k
    (*info->fprintf_styled_func) (info->stream, dis_style_address,
1370
3.10k
          "%s", addrtype);
1371
    /* A colon follow an address type.  */
1372
3.10k
    need_comma = false;
1373
3.10k
  }
1374
251k
      else
1375
251k
  {
1376
251k
    if (operand->flags & ARC_OPERAND_TRUNCATE
1377
251k
        && !(operand->flags & ARC_OPERAND_ALIGNED32)
1378
251k
        && !(operand->flags & ARC_OPERAND_ALIGNED16)
1379
251k
        && value >= 0 && value <= 14)
1380
6.91k
      {
1381
        /* Leave/Enter mnemonics.  */
1382
6.91k
        switch (value)
1383
6.91k
    {
1384
746
    case 0:
1385
746
      need_comma = false;
1386
746
      break;
1387
5.21k
    case 1:
1388
5.21k
      (*info->fprintf_styled_func) (info->stream,
1389
5.21k
            dis_style_register, "r13");
1390
5.21k
      break;
1391
946
    default:
1392
946
      (*info->fprintf_styled_func) (info->stream,
1393
946
            dis_style_register, "r13");
1394
946
      (*info->fprintf_styled_func) (info->stream,
1395
946
            dis_style_text, "-");
1396
946
      (*info->fprintf_styled_func) (info->stream,
1397
946
            dis_style_register, "%s",
1398
946
            regnames[13 + value - 1]);
1399
946
      break;
1400
6.91k
    }
1401
6.91k
        rpcl = false;
1402
6.91k
        rset = false;
1403
6.91k
      }
1404
244k
    else
1405
244k
      {
1406
244k
        const char *rname = get_auxreg (opcode, value, isa_mask);
1407
244k
        if (rname && open_braket)
1408
465
    (*info->fprintf_styled_func) (info->stream, dis_style_register,
1409
465
                "%s", rname);
1410
244k
        else
1411
244k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1412
244k
                "%#x", value);
1413
244k
      }
1414
251k
  }
1415
1416
1.03M
      if (operand->flags & ARC_OPERAND_LIMM)
1417
9.63k
  {
1418
9.63k
    arc_infop->operands[arc_infop->operands_count].kind
1419
9.63k
      = ARC_OPERAND_KIND_LIMM;
1420
    /* It is not important to have exactly the LIMM indicator
1421
       here.  */
1422
9.63k
    arc_infop->operands[arc_infop->operands_count].value = 63;
1423
9.63k
  }
1424
1.02M
      else
1425
1.02M
  {
1426
1.02M
    arc_infop->operands[arc_infop->operands_count].value = value;
1427
1.02M
    arc_infop->operands[arc_infop->operands_count].kind
1428
1.02M
      = (operand->flags & ARC_OPERAND_IR
1429
1.02M
         ? ARC_OPERAND_KIND_REG
1430
1.02M
         : ARC_OPERAND_KIND_SHIMM);
1431
1.02M
  }
1432
1.03M
      arc_infop->operands_count ++;
1433
1.03M
    }
1434
1435
  /* Pretty print extra info for pc-relative operands.  */
1436
464k
  if (rpcl && rset)
1437
187k
    {
1438
187k
      if (info->flags & INSN_HAS_RELOC)
1439
  /* If the instruction has a reloc associated with it, then the
1440
     offset field in the instruction will actually be the addend
1441
     for the reloc.  (We are using REL type relocs).  In such
1442
     cases, we can ignore the pc when computing addresses, since
1443
     the addend is not currently pc-relative.  */
1444
0
  memaddr = 0;
1445
1446
187k
      (*info->fprintf_styled_func) (info->stream,
1447
187k
            dis_style_comment_start, "\t;");
1448
187k
      (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
1449
187k
    }
1450
1451
464k
  return insn_len;
1452
464k
}
1453
1454
1455
disassembler_ftype
1456
arc_get_disassembler (bfd *abfd)
1457
2.81k
{
1458
  /* BFD my be absent, if opcodes is invoked from the debugger that
1459
     has connected to remote target and doesn't have an ELF file.  */
1460
2.81k
  if (abfd != NULL)
1461
37
    {
1462
      /* Read the extension insns and registers, if any.  */
1463
37
      build_ARC_extmap (abfd);
1464
#ifdef DEBUG
1465
      dump_ARC_extmap ();
1466
#endif
1467
37
    }
1468
1469
2.81k
  return print_insn_arc;
1470
2.81k
}
1471
1472
/* Indices into option argument vector for options that do require
1473
   an argument.  Use ARC_OPTION_ARG_NONE for options that don't
1474
   expect an argument.  */
1475
typedef enum
1476
{
1477
  ARC_OPTION_ARG_NONE = -1,
1478
  ARC_OPTION_ARG_ARCH,
1479
  ARC_OPTION_ARG_SIZE
1480
} arc_option_arg_t;
1481
1482
/* Valid ARC disassembler options.  */
1483
static struct
1484
{
1485
  const char *name;
1486
  const char *description;
1487
  arc_option_arg_t arg;
1488
} arc_options[] =
1489
{
1490
  { "cpu=",       N_("Enforce the designated architecture while decoding."),
1491
      ARC_OPTION_ARG_ARCH },
1492
  { "dsp",    N_("Recognize DSP instructions."),
1493
      ARC_OPTION_ARG_NONE },
1494
  { "spfp",   N_("Recognize FPX SP instructions."),
1495
      ARC_OPTION_ARG_NONE },
1496
  { "dpfp",   N_("Recognize FPX DP instructions."),
1497
      ARC_OPTION_ARG_NONE },
1498
  { "quarkse_em", N_("Recognize FPU QuarkSE-EM instructions."),
1499
      ARC_OPTION_ARG_NONE },
1500
  { "fpuda",    N_("Recognize double assist FPU instructions."),
1501
      ARC_OPTION_ARG_NONE },
1502
  { "fpus",   N_("Recognize single precision FPU instructions."),
1503
      ARC_OPTION_ARG_NONE },
1504
  { "fpud",   N_("Recognize double precision FPU instructions."),
1505
      ARC_OPTION_ARG_NONE },
1506
  { "nps400",   N_("Recognize NPS400 instructions."),
1507
      ARC_OPTION_ARG_NONE },
1508
  { "hex",    N_("Use only hexadecimal number to print immediates."),
1509
      ARC_OPTION_ARG_NONE }
1510
};
1511
1512
/* Populate the structure for representing ARC's disassembly options.
1513
   Such a dynamic initialization is desired, because it makes the maintenance
1514
   easier and also gdb uses this to enable the "disassembler-option".  */
1515
1516
const disasm_options_and_args_t *
1517
disassembler_options_arc (void)
1518
0
{
1519
0
  static disasm_options_and_args_t *opts_and_args;
1520
1521
0
  if (opts_and_args == NULL)
1522
0
    {
1523
0
      disasm_option_arg_t *args;
1524
0
      disasm_options_t *opts;
1525
0
      size_t i;
1526
0
      const size_t nr_of_options = ARRAY_SIZE (arc_options);
1527
      /* There is a null element at the end of CPU_TYPES, therefore
1528
   NR_OF_CPUS is actually 1 more and that is desired here too.  */
1529
0
      const size_t nr_of_cpus = ARRAY_SIZE (cpu_types);
1530
1531
0
      opts_and_args = XNEW (disasm_options_and_args_t);
1532
0
      opts_and_args->args
1533
0
  = XNEWVEC (disasm_option_arg_t, ARC_OPTION_ARG_SIZE + 1);
1534
0
      opts_and_args->options.name
1535
0
  = XNEWVEC (const char *, nr_of_options + 1);
1536
0
      opts_and_args->options.description
1537
0
  = XNEWVEC (const char *, nr_of_options + 1);
1538
0
      opts_and_args->options.arg
1539
0
  = XNEWVEC (const disasm_option_arg_t *, nr_of_options + 1);
1540
1541
      /* Populate the arguments for "cpu=" option.  */
1542
0
      args = opts_and_args->args;
1543
0
      args[ARC_OPTION_ARG_ARCH].name = "ARCH";
1544
0
      args[ARC_OPTION_ARG_ARCH].values = XNEWVEC (const char *, nr_of_cpus);
1545
0
      for (i = 0; i < nr_of_cpus; ++i)
1546
0
  args[ARC_OPTION_ARG_ARCH].values[i] = cpu_types[i].name;
1547
0
      args[ARC_OPTION_ARG_SIZE].name = NULL;
1548
0
      args[ARC_OPTION_ARG_SIZE].values = NULL;
1549
1550
      /* Populate the options.  */
1551
0
      opts = &opts_and_args->options;
1552
0
      for (i = 0; i < nr_of_options; ++i)
1553
0
  {
1554
0
    opts->name[i] = arc_options[i].name;
1555
0
    opts->description[i] = arc_options[i].description;
1556
0
    if (arc_options[i].arg != ARC_OPTION_ARG_NONE)
1557
0
      opts->arg[i] = &args[arc_options[i].arg];
1558
0
    else
1559
0
      opts->arg[i] = NULL;
1560
0
  }
1561
0
      opts->name[nr_of_options] = NULL;
1562
0
      opts->description[nr_of_options] = NULL;
1563
0
      opts->arg[nr_of_options] = NULL;
1564
0
    }
1565
1566
0
  return opts_and_args;
1567
0
}
1568
1569
1570
void
1571
print_arc_disassembler_options (FILE *stream)
1572
0
{
1573
0
  const disasm_options_and_args_t *opts_and_args;
1574
0
  const disasm_option_arg_t *args;
1575
0
  const disasm_options_t *opts;
1576
0
  size_t i, j;
1577
0
  size_t max_len = 0;
1578
1579
0
  opts_and_args = disassembler_options_arc ();
1580
0
  opts = &opts_and_args->options;
1581
0
  args = opts_and_args->args;
1582
1583
0
  fprintf (stream, _("\nThe following ARC specific disassembler options are"
1584
0
         " supported for use \nwith the -M switch (multiple"
1585
0
         " options should be separated by commas):\n"));
1586
1587
  /* Find the maximum length for printing options (and their arg name).  */
1588
0
  for (i = 0; opts->name[i] != NULL; ++i)
1589
0
    {
1590
0
      size_t len = strlen (opts->name[i]);
1591
0
      len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
1592
0
      max_len = (len > max_len) ? len : max_len;
1593
0
    }
1594
1595
  /* Print the options, their arg and description, if any.  */
1596
0
  for (i = 0, ++max_len; opts->name[i] != NULL; ++i)
1597
0
    {
1598
0
      fprintf (stream, "  %s", opts->name[i]);
1599
0
      if (opts->arg[i] != NULL)
1600
0
  fprintf (stream, "%s", opts->arg[i]->name);
1601
0
      if (opts->description[i] != NULL)
1602
0
  {
1603
0
    size_t len = strlen (opts->name[i]);
1604
0
    len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
1605
0
    fprintf (stream,
1606
0
       "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
1607
0
  }
1608
0
      fprintf (stream, _("\n"));
1609
0
    }
1610
1611
  /* Print the possible values of an argument.  */
1612
0
  for (i = 0; args[i].name != NULL; ++i)
1613
0
    {
1614
0
      size_t len = 3;
1615
0
      if (args[i].values == NULL)
1616
0
  continue;
1617
0
      fprintf (stream, _("\n\
1618
0
  For the options above, the following values are supported for \"%s\":\n   "),
1619
0
         args[i].name);
1620
0
      for (j = 0; args[i].values[j] != NULL; ++j)
1621
0
  {
1622
0
    fprintf (stream, " %s", args[i].values[j]);
1623
0
    len += strlen (args[i].values[j]) + 1;
1624
    /* reset line if printed too long.  */
1625
0
    if (len >= 78)
1626
0
      {
1627
0
        fprintf (stream, _("\n   "));
1628
0
        len = 3;
1629
0
      }
1630
0
  }
1631
0
      fprintf (stream, _("\n"));
1632
0
    }
1633
1634
0
  fprintf (stream, _("\n"));
1635
0
}
1636
1637
void arc_insn_decode (bfd_vma addr,
1638
          struct disassemble_info *info,
1639
          disassembler_ftype disasm_func,
1640
          struct arc_instruction *insn)
1641
0
{
1642
0
  const struct arc_opcode *opcode;
1643
0
  struct arc_disassemble_info *arc_infop;
1644
1645
  /* Ensure that insn would be in the reset state.  */
1646
0
  memset (insn, 0, sizeof (struct arc_instruction));
1647
1648
  /* There was an error when disassembling, for example memory read error.  */
1649
0
  if (disasm_func (addr, info) < 0)
1650
0
    {
1651
0
      insn->valid = false;
1652
0
      return;
1653
0
    }
1654
1655
0
  assert (info->private_data != NULL);
1656
0
  arc_infop = info->private_data;
1657
1658
0
  insn->length  = arc_infop->insn_len;;
1659
0
  insn->address = addr;
1660
1661
  /* Quick exit if memory at this address is not an instruction.  */
1662
0
  if (info->insn_type == dis_noninsn)
1663
0
    {
1664
0
      insn->valid = false;
1665
0
      return;
1666
0
    }
1667
1668
0
  insn->valid = true;
1669
1670
0
  opcode = (const struct arc_opcode *) arc_infop->opcode;
1671
0
  insn->insn_class = opcode->insn_class;
1672
0
  insn->limm_value = arc_infop->limm;
1673
0
  insn->limm_p     = arc_infop->limm_p;
1674
1675
0
  insn->is_control_flow = (info->insn_type == dis_branch
1676
0
         || info->insn_type == dis_condbranch
1677
0
         || info->insn_type == dis_jsr
1678
0
         || info->insn_type == dis_condjsr);
1679
1680
0
  insn->has_delay_slot = info->branch_delay_insns;
1681
0
  insn->writeback_mode
1682
0
    = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1683
0
  insn->data_size_mode = info->data_size;
1684
0
  insn->condition_code = arc_infop->condition_code;
1685
0
  memcpy (insn->operands, arc_infop->operands,
1686
0
    sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1687
0
  insn->operands_count = arc_infop->operands_count;
1688
0
}
1689
1690
/* Local variables:
1691
   eval: (c-set-style "gnu")
1692
   indent-tabs-mode: t
1693
   End:  */