Coverage Report

Created: 2023-06-29 07:13

/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-2023 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
322k
  (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))  \
138
322k
   : bfd_getb32 (buf))
139
140
700k
#define BITS(word,s,e)  (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1))
141
700k
#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.99k
{
149
2.99k
  struct arc_disassemble_info *arc_infop
150
2.99k
    = calloc (sizeof (*arc_infop), 1);
151
152
2.99k
  if (arc_infop == NULL)
153
0
    return false;
154
155
2.99k
  info->private_data = arc_infop;
156
2.99k
  return true;
157
2.99k
}
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
63.1k
{
165
63.1k
  linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
166
167
63.1k
  t->insn_class = insn_class;
168
63.1k
  t->subclass = subclass;
169
63.1k
  t->nxt = decodelist;
170
63.1k
  decodelist = t;
171
63.1k
}
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
213k
{
179
213k
  linkclass t = decodelist;
180
181
  /* Check opcode for major 0x06, return if it is not in.  */
182
213k
  if (arc_opcode_len (opcode) == 4
183
213k
      && (OPCODE_32BIT_INSN (opcode->opcode) != 0x06
184
    /* Can be an APEX extensions.  */
185
213k
    && OPCODE_32BIT_INSN (opcode->opcode) != 0x07))
186
195k
    return false;
187
188
  /* or not a known truble class.  */
189
18.0k
  switch (opcode->insn_class)
190
18.0k
    {
191
9.42k
    case FLOAT:
192
11.6k
    case DSP:
193
14.0k
    case ARITH:
194
14.8k
    case MPY:
195
14.8k
      break;
196
3.16k
    default:
197
3.16k
      return false;
198
18.0k
    }
199
200
195M
  while (t != NULL)
201
195M
    {
202
195M
      if ((t->insn_class == opcode->insn_class)
203
195M
    && (t->subclass == opcode->subclass))
204
5.55k
  return false;
205
195M
      t = t->nxt;
206
195M
    }
207
208
9.30k
  return true;
209
14.8k
}
210
211
static bfd_vma
212
bfd_getm32 (unsigned int data)
213
321k
{
214
321k
  bfd_vma value = 0;
215
216
321k
  value = ((data & 0xff00) | (data & 0xff)) << 16;
217
321k
  value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
218
321k
  return value;
219
321k
}
220
221
static bool
222
special_flag_p (const char *opname,
223
    const char *flgname)
224
145k
{
225
145k
  const struct arc_flag_special *flg_spec;
226
145k
  unsigned i, j, flgidx;
227
228
1.25M
  for (i = 0; i < arc_num_flag_special; i++)
229
1.14M
    {
230
1.14M
      flg_spec = &arc_flag_special_cases[i];
231
232
1.14M
      if (strcmp (opname, flg_spec->name))
233
1.04M
  continue;
234
235
      /* Found potential special case instruction.  */
236
1.38M
      for (j=0;; ++j)
237
1.48M
  {
238
1.48M
    flgidx = flg_spec->flags[j];
239
1.48M
    if (flgidx == 0)
240
64.9k
      break; /* End of the array.  */
241
242
1.41M
    if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
243
34.4k
      return true;
244
1.41M
  }
245
99.3k
    }
246
111k
  return false;
247
145k
}
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
745k
{
261
745k
  unsigned int i = 0;
262
745k
  const struct arc_opcode *opcode = NULL;
263
745k
  const struct arc_opcode *t_op = NULL;
264
745k
  const unsigned char *opidx;
265
745k
  const unsigned char *flgidx;
266
745k
  bool warn_p = false;
267
268
745k
  do
269
2.21G
    {
270
2.21G
      bool invalid = false;
271
272
2.21G
      opcode = &arc_table[i++];
273
274
2.21G
      if (!(opcode->cpu & isa_mask))
275
1.14G
  continue;
276
277
1.07G
      if (arc_opcode_len (opcode) != (int) insn_len)
278
618M
  continue;
279
280
452M
      if ((insn & opcode->mask) != opcode->opcode)
281
451M
  continue;
282
283
675k
      *has_limm = false;
284
285
      /* Possible candidate, check the operands.  */
286
2.79M
      for (opidx = opcode->operands; *opidx; opidx++)
287
2.12M
  {
288
2.12M
    int value, limmind;
289
2.12M
    const struct arc_operand *operand = &arc_operands[*opidx];
290
291
2.12M
    if (operand->flags & ARC_OPERAND_FAKE)
292
448k
      continue;
293
294
1.68M
    if (operand->extract)
295
1.39M
      value = (*operand->extract) (insn, &invalid);
296
289k
    else
297
289k
      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.68M
    limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
302
1.68M
    if (operand->flags & ARC_OPERAND_IR
303
1.68M
        && !(operand->flags & ARC_OPERAND_LIMM))
304
905k
      {
305
905k
        if ((value == 0x3E && insn_len == 4)
306
905k
      || (value == limmind && insn_len == 2))
307
10.8k
    {
308
10.8k
      invalid = true;
309
10.8k
      break;
310
10.8k
    }
311
905k
      }
312
313
1.66M
    if (operand->flags & ARC_OPERAND_LIMM
314
1.66M
        && !(operand->flags & ARC_OPERAND_DUPLICATE))
315
6.52k
      *has_limm = true;
316
1.66M
  }
317
318
      /* Check the flags.  */
319
1.17M
      for (flgidx = opcode->flags; *flgidx; flgidx++)
320
511k
  {
321
    /* Get a valid flag class.  */
322
511k
    const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
323
511k
    const unsigned *flgopridx;
324
511k
    int foundA = 0, foundB = 0;
325
511k
    unsigned int value;
326
327
    /* Check first the extensions.  */
328
511k
    if (cl_flags->flag_class & F_CLASS_EXTEND)
329
85.1k
      {
330
85.1k
        value = (insn & 0x1F);
331
85.1k
        if (arcExtMap_condCodeName (value))
332
0
    continue;
333
85.1k
      }
334
335
    /* Check for the implicit flags.  */
336
511k
    if (cl_flags->flag_class & F_CLASS_IMPLICIT)
337
116k
      continue;
338
339
3.54M
    for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
340
3.15M
      {
341
3.15M
        const struct arc_flag_operand *flg_operand =
342
3.15M
    &arc_flag_operands[*flgopridx];
343
344
3.15M
        value = (insn >> flg_operand->shift)
345
3.15M
    & ((1 << flg_operand->bits) - 1);
346
3.15M
        if (value == flg_operand->code)
347
446k
    foundA = 1;
348
3.15M
        if (value)
349
1.41M
    foundB = 1;
350
3.15M
      }
351
352
394k
    if (!foundA && foundB)
353
8.43k
      {
354
8.43k
        invalid = true;
355
8.43k
        break;
356
8.43k
      }
357
394k
  }
358
359
675k
      if (invalid)
360
27.8k
  continue;
361
362
647k
      if (insn_len == 4
363
647k
    && overlaps)
364
213k
  {
365
213k
    warn_p = true;
366
213k
    t_op = opcode;
367
213k
    if (skip_this_opcode (opcode))
368
9.30k
      continue;
369
213k
  }
370
371
      /* The instruction is valid.  */
372
638k
      return opcode;
373
647k
    }
374
2.21G
  while (opcode->mask);
375
376
107k
  if (warn_p)
377
8.28k
    {
378
8.28k
      info->fprintf_styled_func
379
8.28k
  (info->stream, dis_style_text,
380
8.28k
   _("\nWarning: disassembly may be wrong due to "
381
8.28k
     "guessed opcode class choice.\n"
382
8.28k
     "Use -M<class[,class]> to select the correct "
383
8.28k
     "opcode class(es).\n\t\t\t\t"));
384
8.28k
      return t_op;
385
8.28k
    }
386
387
98.8k
  return NULL;
388
107k
}
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
745k
{
423
745k
  const struct arc_opcode *opcode = NULL;
424
745k
  bool needs_limm = false;
425
745k
  const extInstruction_t *einsn, *i;
426
745k
  unsigned limm = 0;
427
745k
  struct arc_disassemble_info *arc_infop = info->private_data;
428
429
  /* First, try the extension instructions.  */
430
745k
  if (*insn_len == 4)
431
287k
    {
432
287k
      einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
433
287k
      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
287k
    }
452
453
  /* Then, try finding the first match in the opcode table.  */
454
745k
  if (opcode == NULL)
455
745k
    opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
456
745k
             isa_mask, &needs_limm, true);
457
458
745k
  if (opcode != NULL && needs_limm)
459
4.45k
    {
460
4.45k
      bfd_byte buffer[4];
461
4.45k
      int status;
462
463
4.45k
      status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
464
4.45k
                                          4, info);
465
4.45k
      if (status != 0)
466
24
        {
467
24
          opcode = NULL;
468
24
        }
469
4.42k
      else
470
4.42k
        {
471
4.42k
          limm = ARRANGE_ENDIAN (info, buffer);
472
4.42k
          *insn_len += 4;
473
4.42k
        }
474
4.45k
    }
475
476
745k
  if (opcode != NULL)
477
646k
    {
478
646k
      iter->insn = insn;
479
646k
      iter->limm = limm;
480
646k
      iter->opcode = opcode;
481
646k
      iter->opidx = opcode->operands;
482
646k
    }
483
484
745k
  *opcode_result = opcode;
485
486
  /* Update private data.  */
487
745k
  arc_infop->opcode = opcode;
488
745k
  arc_infop->limm = limm;
489
745k
  arc_infop->limm_p = needs_limm;
490
491
745k
  return true;
492
745k
}
493
494
static void
495
print_flags (const struct arc_opcode *opcode,
496
       unsigned long long *insn,
497
       struct disassemble_info *info)
498
646k
{
499
646k
  const unsigned char *flgidx;
500
646k
  unsigned int value;
501
646k
  struct arc_disassemble_info *arc_infop = info->private_data;
502
503
  /* Now extract and print the flags.  */
504
1.13M
  for (flgidx = opcode->flags; *flgidx; flgidx++)
505
485k
    {
506
      /* Get a valid flag class.  */
507
485k
      const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
508
485k
      const unsigned *flgopridx;
509
510
      /* Check first the extensions.  */
511
485k
      if (cl_flags->flag_class & F_CLASS_EXTEND)
512
82.5k
  {
513
82.5k
    const char *name;
514
82.5k
    value = (insn[0] & 0x1F);
515
516
82.5k
    name = arcExtMap_condCodeName (value);
517
82.5k
    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
82.5k
  }
524
525
3.62M
      for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
526
3.14M
  {
527
3.14M
    const struct arc_flag_operand *flg_operand =
528
3.14M
      &arc_flag_operands[*flgopridx];
529
530
    /* Implicit flags are only used for the insn decoder.  */
531
3.14M
    if (cl_flags->flag_class & F_CLASS_IMPLICIT)
532
116k
      {
533
116k
        if (cl_flags->flag_class & F_CLASS_COND)
534
33.6k
    arc_infop->condition_code = flg_operand->code;
535
82.9k
        else if (cl_flags->flag_class & F_CLASS_WB)
536
2.39k
    arc_infop->writeback_mode = flg_operand->code;
537
80.5k
        else if (cl_flags->flag_class & F_CLASS_ZZ)
538
80.5k
    info->data_size = flg_operand->code;
539
116k
        continue;
540
116k
      }
541
542
3.02M
    if (!flg_operand->favail)
543
1.16M
      continue;
544
545
1.86M
    value = (insn[0] >> flg_operand->shift)
546
1.86M
      & ((1 << flg_operand->bits) - 1);
547
1.86M
    if (value == flg_operand->code)
548
145k
      {
549
         /* FIXME!: print correctly nt/t flag.  */
550
145k
        if (!special_flag_p (opcode->name, flg_operand->name))
551
111k
    (*info->fprintf_styled_func) (info->stream,
552
111k
                dis_style_mnemonic, ".");
553
34.4k
        else if (info->insn_type == dis_dref)
554
14.3k
    {
555
14.3k
      switch (flg_operand->name[0])
556
14.3k
        {
557
5.49k
        case 'b':
558
5.49k
          info->data_size = 1;
559
5.49k
          break;
560
8.89k
        case 'h':
561
8.89k
        case 'w':
562
8.89k
          info->data_size = 2;
563
8.89k
          break;
564
0
        default:
565
0
          info->data_size = 4;
566
0
          break;
567
14.3k
        }
568
14.3k
    }
569
145k
        if (flg_operand->name[0] == 'd'
570
145k
      && flg_operand->name[1] == 0)
571
33.9k
    info->branch_delay_insns = 1;
572
573
        /* Check if it is a conditional flag.  */
574
145k
        if (cl_flags->flag_class & F_CLASS_COND)
575
24.2k
    {
576
24.2k
      if (info->insn_type == dis_jsr)
577
3.46k
        info->insn_type = dis_condjsr;
578
20.7k
      else if (info->insn_type == dis_branch)
579
16.5k
        info->insn_type = dis_condbranch;
580
24.2k
      arc_infop->condition_code = flg_operand->code;
581
24.2k
    }
582
583
        /* Check for the write back modes.  */
584
145k
        if (cl_flags->flag_class & F_CLASS_WB)
585
15.4k
    arc_infop->writeback_mode = flg_operand->code;
586
587
145k
        (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
588
145k
              "%s", flg_operand->name);
589
145k
      }
590
1.86M
  }
591
485k
    }
592
646k
}
593
594
static const char *
595
get_auxreg (const struct arc_opcode *opcode,
596
      int value,
597
      unsigned isa_mask)
598
692k
{
599
692k
  const char *name;
600
692k
  unsigned int i;
601
692k
  const struct arc_aux_reg *auxr = &arc_aux_regs[0];
602
603
692k
  if (opcode->insn_class != AUXREG)
604
688k
    return NULL;
605
606
3.87k
  name = arcExtMap_auxRegName (value);
607
3.87k
  if (name)
608
0
    return name;
609
610
593k
  for (i = 0; i < arc_num_aux_regs; i++, auxr++)
611
592k
    {
612
592k
      if (!(auxr->cpu & isa_mask))
613
220k
  continue;
614
615
371k
      if (auxr->subclass != NONE)
616
1.06k
  return NULL;
617
618
370k
      if (auxr->address == value)
619
2.11k
  return auxr->name;
620
370k
    }
621
692
  return NULL;
622
3.87k
}
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
4.07k
{
630
4.07k
  if (value < 0 || value > addrtypenames_max)
631
0
    return addrtypeunknown;
632
633
4.07k
  return addrtypenames[value];
634
4.07k
}
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
746k
{
647
746k
  bfd_byte major_opcode = msb >> 3;
648
649
746k
  switch (info->mach)
650
746k
    {
651
466k
    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
466k
      if (major_opcode == 0xb)
658
21.1k
        {
659
21.1k
          bfd_byte minor_opcode = lsb & 0x1f;
660
661
21.1k
    if (minor_opcode < 4)
662
4.02k
      return 6;
663
17.1k
    else if (minor_opcode == 0x10 || minor_opcode == 0x11)
664
7.30k
      return 8;
665
21.1k
        }
666
454k
      if (major_opcode == 0xa)
667
6.00k
        {
668
6.00k
          return 8;
669
6.00k
        }
670
      /* Fall through.  */
671
475k
    case bfd_mach_arc_arc600:
672
475k
      return (major_opcode > 0xb) ? 2 : 4;
673
0
      break;
674
675
253k
    case bfd_mach_arc_arcv2:
676
253k
      return (major_opcode > 0x7) ? 2 : 4;
677
0
      break;
678
679
7
    default:
680
7
      return 0;
681
746k
    }
682
746k
}
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.97M
{
692
1.97M
  int value;
693
694
  /* Read the limm operand, if required.  */
695
1.97M
  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
5.88k
    value = limm;
699
1.97M
  else
700
1.97M
    {
701
1.97M
      if (operand->extract)
702
1.31M
  value = (*operand->extract) (insn, (bool *) NULL);
703
658k
      else
704
658k
        {
705
658k
          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
658k
          else
712
658k
            {
713
658k
              value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
714
658k
            }
715
658k
          if (operand->flags & ARC_OPERAND_SIGNED)
716
1.87k
            {
717
1.87k
              int signbit = 1 << (operand->bits - 1);
718
1.87k
              value = (value ^ signbit) - signbit;
719
1.87k
            }
720
658k
        }
721
1.97M
    }
722
723
1.97M
  return value;
724
1.97M
}
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
2.62M
{
737
2.62M
  if (*iter->opidx == 0)
738
646k
    {
739
646k
      *operand = NULL;
740
646k
      return false;
741
646k
    }
742
743
1.97M
  *operand = &arc_operands[*iter->opidx];
744
1.97M
  *value = extract_operand_value (*operand, iter->insn, iter->limm);
745
1.97M
  iter->opidx++;
746
747
1.97M
  return true;
748
2.62M
}
749
750
/* Helper for parsing the options.  */
751
752
static void
753
parse_option (const char *option)
754
7.66k
{
755
7.66k
  if (disassembler_options_cmp (option, "dsp") == 0)
756
118
    add_to_decodelist (DSP, NONE);
757
758
7.55k
  else if (disassembler_options_cmp (option, "spfp") == 0)
759
114
    add_to_decodelist (FLOAT, SPX);
760
761
7.43k
  else if (disassembler_options_cmp (option, "dpfp") == 0)
762
46
    add_to_decodelist (FLOAT, DPX);
763
764
7.39k
  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
7.39k
  else if (disassembler_options_cmp (option, "fpuda") == 0)
773
76
    add_to_decodelist (FLOAT, DPA);
774
775
7.31k
  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
7.31k
  else if (disassembler_options_cmp (option, "fpus") == 0)
793
40
    {
794
40
      add_to_decodelist (FLOAT, SP);
795
40
      add_to_decodelist (FLOAT, CVT);
796
40
    }
797
798
7.27k
  else if (disassembler_options_cmp (option, "fpud") == 0)
799
50
    {
800
50
      add_to_decodelist (FLOAT, DP);
801
50
      add_to_decodelist (FLOAT, CVT);
802
50
    }
803
7.22k
  else if (startswith (option, "hex"))
804
140
    print_hex = true;
805
7.08k
  else
806
    /* xgettext:c-format */
807
7.08k
    opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
808
7.66k
}
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
468
{
839
468
  int i;
840
841
9.36k
  for (i = 0; cpu_types[i].name; ++i)
842
9.10k
    {
843
9.10k
      if (!disassembler_options_cmp (cpu_types[i].name, option))
844
214
  {
845
214
    return cpu_types[i].flags;
846
214
  }
847
9.10k
    }
848
849
  /* xgettext:c-format */
850
254
  opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
851
254
  return ARC_OPCODE_NONE;
852
468
}
853
854
/* Go over the options list and parse it.  */
855
856
static void
857
parse_disassembler_options (const char *options)
858
2.57k
{
859
2.57k
  const char *option;
860
861
2.57k
  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.57k
  enforced_isa_mask = ARC_OPCODE_NONE;
869
870
2.57k
  FOR_EACH_DISASSEMBLER_OPTION (option, options)
871
8.13k
    {
872
      /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
873
   preprocessor macro.  */
874
8.13k
      if (strncmp (option, "cpu=", 4) == 0)
875
  /* Strip leading `cpu=`.  */
876
468
  enforced_isa_mask = parse_cpu_option (option + 4);
877
7.66k
      else
878
7.66k
  parse_option (option);
879
8.13k
    }
880
2.57k
}
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
646k
{
887
646k
  enum dis_insn_type insn_type;
888
889
646k
  switch (opcode->insn_class)
890
646k
    {
891
217k
    case BRANCH:
892
218k
    case BBIT0:
893
220k
    case BBIT1:
894
223k
    case BI:
895
224k
    case BIH:
896
241k
    case BRCC:
897
247k
    case EI:
898
250k
    case JLI:
899
254k
    case JUMP:
900
254k
    case LOOP:
901
254k
      if (!strncmp (opcode->name, "bl", 2)
902
254k
    || !strncmp (opcode->name, "jl", 2))
903
102k
  {
904
102k
    if (opcode->subclass == COND)
905
4.02k
      insn_type = dis_condjsr;
906
98.0k
    else
907
98.0k
      insn_type = dis_jsr;
908
102k
  }
909
152k
      else
910
152k
  {
911
152k
    if (opcode->subclass == COND)
912
32.1k
      insn_type = dis_condbranch;
913
120k
    else
914
120k
      insn_type = dis_branch;
915
152k
  }
916
254k
      break;
917
132k
    case LOAD:
918
192k
    case STORE:
919
194k
    case MEMORY:
920
195k
    case ENTER:
921
195k
    case PUSH:
922
197k
    case POP:
923
197k
      insn_type = dis_dref;
924
197k
      break;
925
4.04k
    case LEAVE:
926
4.04k
      insn_type = dis_branch;
927
4.04k
      break;
928
190k
    default:
929
190k
      insn_type = dis_nonbranch;
930
190k
      break;
931
646k
    }
932
933
646k
  return insn_type;
934
646k
}
935
936
/* Disassemble ARC instructions.  */
937
938
static int
939
print_insn_arc (bfd_vma memaddr,
940
    struct disassemble_info *info)
941
749k
{
942
749k
  bfd_byte buffer[8];
943
749k
  unsigned int highbyte, lowbyte;
944
749k
  int status;
945
749k
  unsigned int insn_len;
946
749k
  unsigned long long insn = 0;
947
749k
  unsigned isa_mask = ARC_OPCODE_NONE;
948
749k
  const struct arc_opcode *opcode;
949
749k
  bool need_comma;
950
749k
  bool open_braket;
951
749k
  int size;
952
749k
  const struct arc_operand *operand;
953
749k
  int value, vpcl;
954
749k
  struct arc_operand_iterator iter;
955
749k
  struct arc_disassemble_info *arc_infop;
956
749k
  bool rpcl = false, rset = false;
957
958
749k
  if (info->disassembler_options)
959
2.57k
    {
960
2.57k
      parse_disassembler_options (info->disassembler_options);
961
962
      /* Avoid repeated parsing of the options.  */
963
2.57k
      info->disassembler_options = NULL;
964
2.57k
    }
965
966
749k
  if (info->private_data == NULL && !init_arc_disasm_info (info))
967
0
    return -1;
968
969
749k
  memset (&iter, 0, sizeof (iter));
970
749k
  highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
971
749k
  lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
972
973
  /* Figure out CPU type, unless it was enforced via disassembler options.  */
974
749k
  if (enforced_isa_mask == ARC_OPCODE_NONE)
975
728k
    {
976
728k
      Elf_Internal_Ehdr *header = NULL;
977
978
728k
      if (info->section && info->section->owner)
979
2.53k
  header = elf_elfheader (info->section->owner);
980
981
728k
      switch (info->mach)
982
728k
  {
983
466k
  case bfd_mach_arc_arc700:
984
466k
    isa_mask = ARC_OPCODE_ARC700;
985
466k
    break;
986
987
7.72k
  case bfd_mach_arc_arc600:
988
7.72k
    isa_mask = ARC_OPCODE_ARC600;
989
7.72k
    break;
990
991
254k
  case bfd_mach_arc_arcv2:
992
254k
  default:
993
254k
    isa_mask = ARC_OPCODE_ARCv2EM;
994
    /* TODO: Perhaps remove definition of header since it is only used at
995
       this location.  */
996
254k
    if (header != NULL
997
254k
        && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
998
0
      isa_mask = ARC_OPCODE_ARCv2HS;
999
254k
    break;
1000
728k
  }
1001
728k
    }
1002
20.8k
  else
1003
20.8k
    isa_mask = enforced_isa_mask;
1004
1005
749k
  if (isa_mask == ARC_OPCODE_ARCv2HS)
1006
20.8k
    {
1007
      /* FPU instructions are not extensions for HS.  */
1008
20.8k
      add_to_decodelist (FLOAT, SP);
1009
20.8k
      add_to_decodelist (FLOAT, DP);
1010
20.8k
      add_to_decodelist (FLOAT, CVT);
1011
20.8k
    }
1012
1013
  /* This variable may be set by the instruction decoder.  It suggests
1014
     the number of bytes objdump should display on a single line.  If
1015
     the instruction decoder sets this, it should always set it to
1016
     the same value in order to get reasonable looking output.  */
1017
749k
  info->bytes_per_line  = 8;
1018
1019
  /* In the next lines, we set two info variables control the way
1020
     objdump displays the raw data.  For example, if bytes_per_line is
1021
     8 and bytes_per_chunk is 4, the output will look like this:
1022
     00:   00000000 00000000
1023
     with the chunks displayed according to "display_endian".  */
1024
749k
  if (info->section
1025
749k
      && !(info->section->flags & SEC_CODE))
1026
1.90k
    {
1027
      /* This is not a CODE section.  */
1028
1.90k
      switch (info->section->size)
1029
1.90k
  {
1030
0
  case 1:
1031
0
  case 2:
1032
0
  case 4:
1033
0
    size = info->section->size;
1034
0
    break;
1035
1.90k
  default:
1036
1.90k
    size = (info->section->size & 0x01) ? 1 : 4;
1037
1.90k
    break;
1038
1.90k
  }
1039
1.90k
      info->bytes_per_chunk = 1;
1040
1.90k
      info->display_endian = info->endian;
1041
1.90k
    }
1042
747k
  else
1043
747k
    {
1044
747k
      size = 2;
1045
747k
      info->bytes_per_chunk = 2;
1046
747k
      info->display_endian = info->endian;
1047
747k
    }
1048
1049
  /* Read the insn into a host word.  */
1050
749k
  status = (*info->read_memory_func) (memaddr, buffer, size, info);
1051
1052
749k
  if (status != 0)
1053
1.21k
    {
1054
1.21k
      (*info->memory_error_func) (status, memaddr, info);
1055
1.21k
      return -1;
1056
1.21k
    }
1057
1058
748k
  if (info->section
1059
748k
      && !(info->section->flags & SEC_CODE))
1060
1.89k
    {
1061
      /* Data section.  */
1062
1.89k
      unsigned long data;
1063
1064
1.89k
      data = bfd_get_bits (buffer, size * 8,
1065
1.89k
         info->display_endian == BFD_ENDIAN_BIG);
1066
1.89k
      switch (size)
1067
1.89k
  {
1068
1.56k
  case 1:
1069
1.56k
    (*info->fprintf_styled_func) (info->stream,
1070
1.56k
          dis_style_assembler_directive,
1071
1.56k
          ".byte");
1072
1.56k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1073
1.56k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1074
1.56k
          "0x%02lx", data);
1075
1.56k
    break;
1076
0
  case 2:
1077
0
    (*info->fprintf_styled_func) (info->stream,
1078
0
          dis_style_assembler_directive,
1079
0
          ".short");
1080
0
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1081
0
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1082
0
          "0x%04lx", data);
1083
0
    break;
1084
334
  case 4:
1085
334
    (*info->fprintf_styled_func) (info->stream,
1086
334
          dis_style_assembler_directive,
1087
334
          ".word");
1088
334
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1089
334
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1090
334
          "0x%08lx", data);
1091
334
    break;
1092
0
  default:
1093
0
    return -1;
1094
1.89k
  }
1095
1.89k
      return size;
1096
1.89k
    }
1097
1098
746k
  insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1099
746k
  pr_debug ("instruction length = %d bytes\n", insn_len);
1100
746k
  if (insn_len == 0)
1101
7
    return -1;
1102
1103
746k
  arc_infop = info->private_data;
1104
746k
  arc_infop->insn_len = insn_len;
1105
1106
746k
  switch (insn_len)
1107
746k
    {
1108
440k
    case 2:
1109
440k
      insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1110
440k
      break;
1111
1112
287k
    case 4:
1113
287k
      {
1114
  /* This is a long instruction: Read the remaning 2 bytes.  */
1115
287k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1116
287k
  if (status != 0)
1117
863
    {
1118
863
      (*info->memory_error_func) (status, memaddr + 2, info);
1119
863
      return -1;
1120
863
    }
1121
287k
  insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1122
287k
      }
1123
0
      break;
1124
1125
4.02k
    case 6:
1126
4.02k
      {
1127
4.02k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1128
4.02k
  if (status != 0)
1129
13
    {
1130
13
      (*info->memory_error_func) (status, memaddr + 2, info);
1131
13
      return -1;
1132
13
    }
1133
4.00k
  insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1134
4.00k
  insn |= ((unsigned long long) buffer[highbyte] << 40)
1135
4.00k
    | ((unsigned long long) buffer[lowbyte] << 32);
1136
4.00k
      }
1137
0
      break;
1138
1139
13.3k
    case 8:
1140
13.3k
      {
1141
13.3k
  status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1142
13.3k
  if (status != 0)
1143
18
    {
1144
18
      (*info->memory_error_func) (status, memaddr + 2, info);
1145
18
      return -1;
1146
18
    }
1147
13.2k
  insn =
1148
13.2k
    ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1149
13.2k
     | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1150
13.2k
      }
1151
0
      break;
1152
1153
0
    default:
1154
      /* There is no instruction whose length is not 2, 4, 6, or 8.  */
1155
0
      return -1;
1156
746k
    }
1157
1158
745k
  pr_debug ("instruction value = %llx\n", insn);
1159
1160
  /* Set some defaults for the insn info.  */
1161
745k
  info->insn_info_valid    = 1;
1162
745k
  info->branch_delay_insns = 0;
1163
745k
  info->data_size    = 4;
1164
745k
  info->insn_type    = dis_nonbranch;
1165
745k
  info->target       = 0;
1166
745k
  info->target2      = 0;
1167
1168
  /* FIXME to be moved in dissasemble_init_for_target.  */
1169
745k
  info->disassembler_needs_relocs = true;
1170
1171
  /* Find the first match in the opcode table.  */
1172
745k
  if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1173
0
    return -1;
1174
1175
745k
  if (!opcode)
1176
98.8k
    {
1177
98.8k
      switch (insn_len)
1178
98.8k
  {
1179
17.4k
  case 2:
1180
17.4k
    (*info->fprintf_styled_func) (info->stream,
1181
17.4k
          dis_style_assembler_directive,
1182
17.4k
          ".short");
1183
17.4k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1184
17.4k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1185
17.4k
          "0x%04llx", insn & 0xffff);
1186
17.4k
    break;
1187
1188
74.8k
  case 4:
1189
74.8k
    (*info->fprintf_styled_func) (info->stream,
1190
74.8k
          dis_style_assembler_directive,
1191
74.8k
          ".word");
1192
74.8k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1193
74.8k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1194
74.8k
          "0x%08llx", insn & 0xffffffff);
1195
74.8k
    break;
1196
1197
697
  case 6:
1198
697
    (*info->fprintf_styled_func) (info->stream,
1199
697
          dis_style_assembler_directive,
1200
697
          ".long");
1201
697
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1202
697
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1203
697
               "0x%08llx", insn & 0xffffffff);
1204
697
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1205
697
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1206
697
          "0x%04llx", (insn >> 32) & 0xffff);
1207
697
    break;
1208
1209
5.80k
  case 8:
1210
5.80k
    (*info->fprintf_styled_func) (info->stream,
1211
5.80k
          dis_style_assembler_directive,
1212
5.80k
          ".long");
1213
5.80k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1214
5.80k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1215
5.80k
          "0x%08llx", insn & 0xffffffff);
1216
5.80k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1217
5.80k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1218
5.80k
          "0x%08llx", (insn >> 32));
1219
5.80k
    break;
1220
1221
0
  default:
1222
0
    return -1;
1223
98.8k
  }
1224
1225
98.8k
      info->insn_type = dis_noninsn;
1226
98.8k
      return insn_len;
1227
98.8k
    }
1228
1229
  /* Print the mnemonic.  */
1230
646k
  (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1231
646k
        "%s", opcode->name);
1232
1233
  /* Preselect the insn class.  */
1234
646k
  info->insn_type = arc_opcode_to_insn_type (opcode);
1235
1236
646k
  pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1237
1238
646k
  print_flags (opcode, &insn, info);
1239
1240
646k
  if (opcode->operands[0] != 0)
1241
645k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
1242
1243
646k
  need_comma = false;
1244
646k
  open_braket = false;
1245
646k
  arc_infop->operands_count = 0;
1246
1247
  /* Now extract and print the operands.  */
1248
646k
  operand = NULL;
1249
646k
  vpcl = 0;
1250
2.62M
  while (operand_iterator_next (&iter, &operand, &value))
1251
1.97M
    {
1252
1.97M
      if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1253
212k
  {
1254
212k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
1255
212k
    open_braket = false;
1256
212k
    continue;
1257
212k
  }
1258
1259
      /* Only take input from real operands.  */
1260
1.76M
      if (ARC_OPERAND_IS_FAKE (operand))
1261
0
  continue;
1262
1263
1.76M
      if ((operand->flags & ARC_OPERAND_IGNORE)
1264
1.76M
    && (operand->flags & ARC_OPERAND_IR)
1265
1.76M
    && value == -1)
1266
8.66k
  continue;
1267
1268
1.75M
      if (operand->flags & ARC_OPERAND_COLON)
1269
4.07k
  {
1270
4.07k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, ":");
1271
4.07k
    continue;
1272
4.07k
  }
1273
1274
1.75M
      if (need_comma)
1275
889k
  (*info->fprintf_styled_func) (info->stream, dis_style_text,",");
1276
1277
1.75M
      if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1278
212k
  {
1279
212k
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "[");
1280
212k
    open_braket = true;
1281
212k
    need_comma = false;
1282
212k
    continue;
1283
212k
  }
1284
1285
1.53M
      need_comma = true;
1286
1287
1.53M
      if (operand->flags & ARC_OPERAND_PCREL)
1288
250k
  {
1289
250k
    rpcl = true;
1290
250k
    vpcl = value;
1291
250k
    rset = true;
1292
1293
250k
    info->target = (bfd_vma) (memaddr & ~3) + value;
1294
250k
  }
1295
1.28M
      else if (!(operand->flags & ARC_OPERAND_IR))
1296
450k
  {
1297
450k
    vpcl = value;
1298
450k
    rset = true;
1299
450k
  }
1300
1301
      /* Print the operand as directed by the flags.  */
1302
1.53M
      if (operand->flags & ARC_OPERAND_IR)
1303
838k
  {
1304
838k
    const char *rname;
1305
1306
838k
    assert (value >=0 && value < 64);
1307
838k
    rname = arcExtMap_coreRegName (value);
1308
838k
    if (!rname)
1309
838k
      rname = regnames[value];
1310
838k
    (*info->fprintf_styled_func) (info->stream, dis_style_register,
1311
838k
          "%s", rname);
1312
1313
    /* Check if we have a double register to print.  */
1314
838k
    if (operand->flags & ARC_OPERAND_TRUNCATE)
1315
827
      {
1316
827
        if ((value & 0x01) == 0)
1317
500
    {
1318
500
      rname = arcExtMap_coreRegName (value + 1);
1319
500
      if (!rname)
1320
500
        rname = regnames[value + 1];
1321
500
    }
1322
327
        else
1323
327
    rname = _("\nWarning: illegal use of double register "
1324
827
        "pair.\n");
1325
827
        (*info->fprintf_styled_func) (info->stream, dis_style_register,
1326
827
              "%s", rname);
1327
827
      }
1328
838k
    if (value == 63)
1329
15.4k
      rpcl = true;
1330
822k
    else
1331
822k
      rpcl = false;
1332
838k
  }
1333
700k
      else if (operand->flags & ARC_OPERAND_LIMM)
1334
5.88k
  {
1335
5.88k
    const char *rname = get_auxreg (opcode, value, isa_mask);
1336
1337
5.88k
    if (rname && open_braket)
1338
352
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1339
352
            "%s", rname);
1340
5.53k
    else
1341
5.53k
      {
1342
5.53k
        (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1343
5.53k
              "%#x", value);
1344
5.53k
        if (info->insn_type == dis_branch
1345
5.53k
      || info->insn_type == dis_jsr)
1346
450
    info->target = (bfd_vma) value;
1347
5.53k
      }
1348
5.88k
  }
1349
694k
      else if (operand->flags & ARC_OPERAND_SIGNED)
1350
295k
  {
1351
295k
    const char *rname = get_auxreg (opcode, value, isa_mask);
1352
295k
    if (rname && open_braket)
1353
416
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1354
416
            "%s", rname);
1355
294k
    else
1356
294k
      {
1357
294k
        if (print_hex)
1358
112k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1359
112k
                "%#x", value);
1360
181k
        else
1361
181k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1362
181k
                "%d", value);
1363
294k
      }
1364
295k
  }
1365
399k
      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1366
4.07k
  {
1367
4.07k
    const char *addrtype = get_addrtype (value);
1368
4.07k
    (*info->fprintf_styled_func) (info->stream, dis_style_address,
1369
4.07k
          "%s", addrtype);
1370
    /* A colon follow an address type.  */
1371
4.07k
    need_comma = false;
1372
4.07k
  }
1373
395k
      else
1374
395k
  {
1375
395k
    if (operand->flags & ARC_OPERAND_TRUNCATE
1376
395k
        && !(operand->flags & ARC_OPERAND_ALIGNED32)
1377
395k
        && !(operand->flags & ARC_OPERAND_ALIGNED16)
1378
395k
        && value >= 0 && value <= 14)
1379
4.22k
      {
1380
        /* Leave/Enter mnemonics.  */
1381
4.22k
        switch (value)
1382
4.22k
    {
1383
1.02k
    case 0:
1384
1.02k
      need_comma = false;
1385
1.02k
      break;
1386
2.11k
    case 1:
1387
2.11k
      (*info->fprintf_styled_func) (info->stream,
1388
2.11k
            dis_style_register, "r13");
1389
2.11k
      break;
1390
1.09k
    default:
1391
1.09k
      (*info->fprintf_styled_func) (info->stream,
1392
1.09k
            dis_style_register, "r13");
1393
1.09k
      (*info->fprintf_styled_func) (info->stream,
1394
1.09k
            dis_style_text, "-");
1395
1.09k
      (*info->fprintf_styled_func) (info->stream,
1396
1.09k
            dis_style_register, "%s",
1397
1.09k
            regnames[13 + value - 1]);
1398
1.09k
      break;
1399
4.22k
    }
1400
4.22k
        rpcl = false;
1401
4.22k
        rset = false;
1402
4.22k
      }
1403
391k
    else
1404
391k
      {
1405
391k
        const char *rname = get_auxreg (opcode, value, isa_mask);
1406
391k
        if (rname && open_braket)
1407
424
    (*info->fprintf_styled_func) (info->stream, dis_style_register,
1408
424
                "%s", rname);
1409
390k
        else
1410
390k
    (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1411
390k
                "%#x", value);
1412
391k
      }
1413
395k
  }
1414
1415
1.53M
      if (operand->flags & ARC_OPERAND_LIMM)
1416
5.88k
  {
1417
5.88k
    arc_infop->operands[arc_infop->operands_count].kind
1418
5.88k
      = ARC_OPERAND_KIND_LIMM;
1419
    /* It is not important to have exactly the LIMM indicator
1420
       here.  */
1421
5.88k
    arc_infop->operands[arc_infop->operands_count].value = 63;
1422
5.88k
  }
1423
1.53M
      else
1424
1.53M
  {
1425
1.53M
    arc_infop->operands[arc_infop->operands_count].value = value;
1426
1.53M
    arc_infop->operands[arc_infop->operands_count].kind
1427
1.53M
      = (operand->flags & ARC_OPERAND_IR
1428
1.53M
         ? ARC_OPERAND_KIND_REG
1429
1.53M
         : ARC_OPERAND_KIND_SHIMM);
1430
1.53M
  }
1431
1.53M
      arc_infop->operands_count ++;
1432
1.53M
    }
1433
1434
  /* Pretty print extra info for pc-relative operands.  */
1435
646k
  if (rpcl && rset)
1436
251k
    {
1437
251k
      if (info->flags & INSN_HAS_RELOC)
1438
  /* If the instruction has a reloc associated with it, then the
1439
     offset field in the instruction will actually be the addend
1440
     for the reloc.  (We are using REL type relocs).  In such
1441
     cases, we can ignore the pc when computing addresses, since
1442
     the addend is not currently pc-relative.  */
1443
0
  memaddr = 0;
1444
1445
251k
      (*info->fprintf_styled_func) (info->stream,
1446
251k
            dis_style_comment_start, "\t;");
1447
251k
      (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
1448
251k
    }
1449
1450
646k
  return insn_len;
1451
646k
}
1452
1453
1454
disassembler_ftype
1455
arc_get_disassembler (bfd *abfd)
1456
2.99k
{
1457
  /* BFD my be absent, if opcodes is invoked from the debugger that
1458
     has connected to remote target and doesn't have an ELF file.  */
1459
2.99k
  if (abfd != NULL)
1460
23
    {
1461
      /* Read the extension insns and registers, if any.  */
1462
23
      build_ARC_extmap (abfd);
1463
#ifdef DEBUG
1464
      dump_ARC_extmap ();
1465
#endif
1466
23
    }
1467
1468
2.99k
  return print_insn_arc;
1469
2.99k
}
1470
1471
/* Indices into option argument vector for options that do require
1472
   an argument.  Use ARC_OPTION_ARG_NONE for options that don't
1473
   expect an argument.  */
1474
typedef enum
1475
{
1476
  ARC_OPTION_ARG_NONE = -1,
1477
  ARC_OPTION_ARG_ARCH,
1478
  ARC_OPTION_ARG_SIZE
1479
} arc_option_arg_t;
1480
1481
/* Valid ARC disassembler options.  */
1482
static struct
1483
{
1484
  const char *name;
1485
  const char *description;
1486
  arc_option_arg_t arg;
1487
} arc_options[] =
1488
{
1489
  { "cpu=",       N_("Enforce the designated architecture while decoding."),
1490
      ARC_OPTION_ARG_ARCH },
1491
  { "dsp",    N_("Recognize DSP instructions."),
1492
      ARC_OPTION_ARG_NONE },
1493
  { "spfp",   N_("Recognize FPX SP instructions."),
1494
      ARC_OPTION_ARG_NONE },
1495
  { "dpfp",   N_("Recognize FPX DP instructions."),
1496
      ARC_OPTION_ARG_NONE },
1497
  { "quarkse_em", N_("Recognize FPU QuarkSE-EM instructions."),
1498
      ARC_OPTION_ARG_NONE },
1499
  { "fpuda",    N_("Recognize double assist FPU instructions."),
1500
      ARC_OPTION_ARG_NONE },
1501
  { "fpus",   N_("Recognize single precision FPU instructions."),
1502
      ARC_OPTION_ARG_NONE },
1503
  { "fpud",   N_("Recognize double precision FPU instructions."),
1504
      ARC_OPTION_ARG_NONE },
1505
  { "nps400",   N_("Recognize NPS400 instructions."),
1506
      ARC_OPTION_ARG_NONE },
1507
  { "hex",    N_("Use only hexadecimal number to print immediates."),
1508
      ARC_OPTION_ARG_NONE }
1509
};
1510
1511
/* Populate the structure for representing ARC's disassembly options.
1512
   Such a dynamic initialization is desired, because it makes the maintenance
1513
   easier and also gdb uses this to enable the "disassembler-option".  */
1514
1515
const disasm_options_and_args_t *
1516
disassembler_options_arc (void)
1517
0
{
1518
0
  static disasm_options_and_args_t *opts_and_args;
1519
1520
0
  if (opts_and_args == NULL)
1521
0
    {
1522
0
      disasm_option_arg_t *args;
1523
0
      disasm_options_t *opts;
1524
0
      size_t i;
1525
0
      const size_t nr_of_options = ARRAY_SIZE (arc_options);
1526
      /* There is a null element at the end of CPU_TYPES, therefore
1527
   NR_OF_CPUS is actually 1 more and that is desired here too.  */
1528
0
      const size_t nr_of_cpus = ARRAY_SIZE (cpu_types);
1529
1530
0
      opts_and_args = XNEW (disasm_options_and_args_t);
1531
0
      opts_and_args->args
1532
0
  = XNEWVEC (disasm_option_arg_t, ARC_OPTION_ARG_SIZE + 1);
1533
0
      opts_and_args->options.name
1534
0
  = XNEWVEC (const char *, nr_of_options + 1);
1535
0
      opts_and_args->options.description
1536
0
  = XNEWVEC (const char *, nr_of_options + 1);
1537
0
      opts_and_args->options.arg
1538
0
  = XNEWVEC (const disasm_option_arg_t *, nr_of_options + 1);
1539
1540
      /* Populate the arguments for "cpu=" option.  */
1541
0
      args = opts_and_args->args;
1542
0
      args[ARC_OPTION_ARG_ARCH].name = "ARCH";
1543
0
      args[ARC_OPTION_ARG_ARCH].values = XNEWVEC (const char *, nr_of_cpus);
1544
0
      for (i = 0; i < nr_of_cpus; ++i)
1545
0
  args[ARC_OPTION_ARG_ARCH].values[i] = cpu_types[i].name;
1546
0
      args[ARC_OPTION_ARG_SIZE].name = NULL;
1547
0
      args[ARC_OPTION_ARG_SIZE].values = NULL;
1548
1549
      /* Populate the options.  */
1550
0
      opts = &opts_and_args->options;
1551
0
      for (i = 0; i < nr_of_options; ++i)
1552
0
  {
1553
0
    opts->name[i] = arc_options[i].name;
1554
0
    opts->description[i] = arc_options[i].description;
1555
0
    if (arc_options[i].arg != ARC_OPTION_ARG_NONE)
1556
0
      opts->arg[i] = &args[arc_options[i].arg];
1557
0
    else
1558
0
      opts->arg[i] = NULL;
1559
0
  }
1560
0
      opts->name[nr_of_options] = NULL;
1561
0
      opts->description[nr_of_options] = NULL;
1562
0
      opts->arg[nr_of_options] = NULL;
1563
0
    }
1564
1565
0
  return opts_and_args;
1566
0
}
1567
1568
1569
void
1570
print_arc_disassembler_options (FILE *stream)
1571
0
{
1572
0
  const disasm_options_and_args_t *opts_and_args;
1573
0
  const disasm_option_arg_t *args;
1574
0
  const disasm_options_t *opts;
1575
0
  size_t i, j;
1576
0
  size_t max_len = 0;
1577
1578
0
  opts_and_args = disassembler_options_arc ();
1579
0
  opts = &opts_and_args->options;
1580
0
  args = opts_and_args->args;
1581
1582
0
  fprintf (stream, _("\nThe following ARC specific disassembler options are"
1583
0
         " supported for use \nwith the -M switch (multiple"
1584
0
         " options should be separated by commas):\n"));
1585
1586
  /* Find the maximum length for printing options (and their arg name).  */
1587
0
  for (i = 0; opts->name[i] != NULL; ++i)
1588
0
    {
1589
0
      size_t len = strlen (opts->name[i]);
1590
0
      len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
1591
0
      max_len = (len > max_len) ? len : max_len;
1592
0
    }
1593
1594
  /* Print the options, their arg and description, if any.  */
1595
0
  for (i = 0, ++max_len; opts->name[i] != NULL; ++i)
1596
0
    {
1597
0
      fprintf (stream, "  %s", opts->name[i]);
1598
0
      if (opts->arg[i] != NULL)
1599
0
  fprintf (stream, "%s", opts->arg[i]->name);
1600
0
      if (opts->description[i] != NULL)
1601
0
  {
1602
0
    size_t len = strlen (opts->name[i]);
1603
0
    len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
1604
0
    fprintf (stream,
1605
0
       "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
1606
0
  }
1607
0
      fprintf (stream, _("\n"));
1608
0
    }
1609
1610
  /* Print the possible values of an argument.  */
1611
0
  for (i = 0; args[i].name != NULL; ++i)
1612
0
    {
1613
0
      size_t len = 3;
1614
0
      if (args[i].values == NULL)
1615
0
  continue;
1616
0
      fprintf (stream, _("\n\
1617
0
  For the options above, the following values are supported for \"%s\":\n   "),
1618
0
         args[i].name);
1619
0
      for (j = 0; args[i].values[j] != NULL; ++j)
1620
0
  {
1621
0
    fprintf (stream, " %s", args[i].values[j]);
1622
0
    len += strlen (args[i].values[j]) + 1;
1623
    /* reset line if printed too long.  */
1624
0
    if (len >= 78)
1625
0
      {
1626
0
        fprintf (stream, _("\n   "));
1627
0
        len = 3;
1628
0
      }
1629
0
  }
1630
0
      fprintf (stream, _("\n"));
1631
0
    }
1632
1633
0
  fprintf (stream, _("\n"));
1634
0
}
1635
1636
void arc_insn_decode (bfd_vma addr,
1637
          struct disassemble_info *info,
1638
          disassembler_ftype disasm_func,
1639
          struct arc_instruction *insn)
1640
0
{
1641
0
  const struct arc_opcode *opcode;
1642
0
  struct arc_disassemble_info *arc_infop;
1643
1644
  /* Ensure that insn would be in the reset state.  */
1645
0
  memset (insn, 0, sizeof (struct arc_instruction));
1646
1647
  /* There was an error when disassembling, for example memory read error.  */
1648
0
  if (disasm_func (addr, info) < 0)
1649
0
    {
1650
0
      insn->valid = false;
1651
0
      return;
1652
0
    }
1653
1654
0
  assert (info->private_data != NULL);
1655
0
  arc_infop = info->private_data;
1656
1657
0
  insn->length  = arc_infop->insn_len;;
1658
0
  insn->address = addr;
1659
1660
  /* Quick exit if memory at this address is not an instruction.  */
1661
0
  if (info->insn_type == dis_noninsn)
1662
0
    {
1663
0
      insn->valid = false;
1664
0
      return;
1665
0
    }
1666
1667
0
  insn->valid = true;
1668
1669
0
  opcode = (const struct arc_opcode *) arc_infop->opcode;
1670
0
  insn->insn_class = opcode->insn_class;
1671
0
  insn->limm_value = arc_infop->limm;
1672
0
  insn->limm_p     = arc_infop->limm_p;
1673
1674
0
  insn->is_control_flow = (info->insn_type == dis_branch
1675
0
         || info->insn_type == dis_condbranch
1676
0
         || info->insn_type == dis_jsr
1677
0
         || info->insn_type == dis_condjsr);
1678
1679
0
  insn->has_delay_slot = info->branch_delay_insns;
1680
0
  insn->writeback_mode
1681
0
    = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1682
0
  insn->data_size_mode = info->data_size;
1683
0
  insn->condition_code = arc_infop->condition_code;
1684
0
  memcpy (insn->operands, arc_infop->operands,
1685
0
    sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1686
0
  insn->operands_count = arc_infop->operands_count;
1687
0
}
1688
1689
/* Local variables:
1690
   eval: (c-set-style "gnu")
1691
   indent-tabs-mode: t
1692
   End:  */