Coverage Report

Created: 2023-08-28 06:23

/src/binutils-gdb/opcodes/aarch64-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* aarch64-dis.c -- AArch64 disassembler.
2
   Copyright (C) 2009-2023 Free Software Foundation, Inc.
3
   Contributed by ARM Ltd.
4
5
   This file is part of the GNU opcodes library.
6
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; see the file COPYING3. If not,
19
   see <http://www.gnu.org/licenses/>.  */
20
21
#include "sysdep.h"
22
#include <stdint.h>
23
#include "disassemble.h"
24
#include "libiberty.h"
25
#include "opintl.h"
26
#include "aarch64-dis.h"
27
#include "elf-bfd.h"
28
#include "safe-ctype.h"
29
#include "obstack.h"
30
31
#define obstack_chunk_alloc xmalloc
32
#define obstack_chunk_free free
33
34
0
#define INSNLEN 4
35
36
/* This character is used to encode style information within the output
37
   buffers.  See get_style_text and print_operands for more details.  */
38
0
#define STYLE_MARKER_CHAR '\002'
39
40
/* Cached mapping symbol state.  */
41
enum map_type
42
{
43
  MAP_INSN,
44
  MAP_DATA
45
};
46
47
static aarch64_feature_set arch_variant; /* See select_aarch64_variant.  */
48
static enum map_type last_type;
49
static int last_mapping_sym = -1;
50
static bfd_vma last_stop_offset = 0;
51
static bfd_vma last_mapping_addr = 0;
52
53
/* Other options */
54
static int no_aliases = 0;  /* If set disassemble as most general inst.  */
55
static int no_notes = 1; /* If set do not print disassemble notes in the
56
          output as comments.  */
57
58
/* Currently active instruction sequence.  */
59
static aarch64_instr_sequence insn_sequence;
60
61
static void
62
set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
63
0
{
64
0
}
65
66
static void
67
parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
68
0
{
69
  /* Try to match options that are simple flags */
70
0
  if (startswith (option, "no-aliases"))
71
0
    {
72
0
      no_aliases = 1;
73
0
      return;
74
0
    }
75
76
0
  if (startswith (option, "aliases"))
77
0
    {
78
0
      no_aliases = 0;
79
0
      return;
80
0
    }
81
82
0
  if (startswith (option, "no-notes"))
83
0
    {
84
0
      no_notes = 1;
85
0
      return;
86
0
    }
87
88
0
  if (startswith (option, "notes"))
89
0
    {
90
0
      no_notes = 0;
91
0
      return;
92
0
    }
93
94
#ifdef DEBUG_AARCH64
95
  if (startswith (option, "debug_dump"))
96
    {
97
      debug_dump = 1;
98
      return;
99
    }
100
#endif /* DEBUG_AARCH64 */
101
102
  /* Invalid option.  */
103
0
  opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
104
0
}
105
106
static void
107
parse_aarch64_dis_options (const char *options)
108
0
{
109
0
  const char *option_end;
110
111
0
  if (options == NULL)
112
0
    return;
113
114
0
  while (*options != '\0')
115
0
    {
116
      /* Skip empty options.  */
117
0
      if (*options == ',')
118
0
  {
119
0
    options++;
120
0
    continue;
121
0
  }
122
123
      /* We know that *options is neither NUL or a comma.  */
124
0
      option_end = options + 1;
125
0
      while (*option_end != ',' && *option_end != '\0')
126
0
  option_end++;
127
128
0
      parse_aarch64_dis_option (options, option_end - options);
129
130
      /* Go on to the next one.  If option_end points to a comma, it
131
   will be skipped above.  */
132
0
      options = option_end;
133
0
    }
134
0
}
135

136
/* Functions doing the instruction disassembling.  */
137
138
/* The unnamed arguments consist of the number of fields and information about
139
   these fields where the VALUE will be extracted from CODE and returned.
140
   MASK can be zero or the base mask of the opcode.
141
142
   N.B. the fields are required to be in such an order than the most signficant
143
   field for VALUE comes the first, e.g. the <index> in
144
    SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
145
   is encoded in H:L:M in some cases, the fields H:L:M should be passed in
146
   the order of H, L, M.  */
147
148
aarch64_insn
149
extract_fields (aarch64_insn code, aarch64_insn mask, ...)
150
0
{
151
0
  uint32_t num;
152
0
  const aarch64_field *field;
153
0
  enum aarch64_field_kind kind;
154
0
  va_list va;
155
156
0
  va_start (va, mask);
157
0
  num = va_arg (va, uint32_t);
158
0
  assert (num <= 5);
159
0
  aarch64_insn value = 0x0;
160
0
  while (num--)
161
0
    {
162
0
      kind = va_arg (va, enum aarch64_field_kind);
163
0
      field = &fields[kind];
164
0
      value <<= field->width;
165
0
      value |= extract_field (kind, code, mask);
166
0
    }
167
0
  va_end (va);
168
0
  return value;
169
0
}
170
171
/* Extract the value of all fields in SELF->fields after START from
172
   instruction CODE.  The least significant bit comes from the final field.  */
173
174
static aarch64_insn
175
extract_all_fields_after (const aarch64_operand *self, unsigned int start,
176
        aarch64_insn code)
177
0
{
178
0
  aarch64_insn value;
179
0
  unsigned int i;
180
0
  enum aarch64_field_kind kind;
181
182
0
  value = 0;
183
0
  for (i = start;
184
0
       i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i)
185
0
    {
186
0
      kind = self->fields[i];
187
0
      value <<= fields[kind].width;
188
0
      value |= extract_field (kind, code, 0);
189
0
    }
190
0
  return value;
191
0
}
192
193
/* Extract the value of all fields in SELF->fields from instruction CODE.
194
   The least significant bit comes from the final field.  */
195
196
static aarch64_insn
197
extract_all_fields (const aarch64_operand *self, aarch64_insn code)
198
0
{
199
0
  return extract_all_fields_after (self, 0, code);
200
0
}
201
202
/* Sign-extend bit I of VALUE.  */
203
static inline uint64_t
204
sign_extend (aarch64_insn value, unsigned i)
205
0
{
206
0
  uint64_t ret, sign;
207
208
0
  assert (i < 32);
209
0
  ret = value;
210
0
  sign = (uint64_t) 1 << i;
211
0
  return ((ret & (sign + sign - 1)) ^ sign) - sign;
212
0
}
213
214
/* N.B. the following inline helpfer functions create a dependency on the
215
   order of operand qualifier enumerators.  */
216
217
/* Given VALUE, return qualifier for a general purpose register.  */
218
static inline enum aarch64_opnd_qualifier
219
get_greg_qualifier_from_value (aarch64_insn value)
220
0
{
221
0
  enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
222
0
  assert (value <= 0x1
223
0
    && aarch64_get_qualifier_standard_value (qualifier) == value);
224
0
  return qualifier;
225
0
}
226
227
/* Given VALUE, return qualifier for a vector register.  This does not support
228
   decoding instructions that accept the 2H vector type.  */
229
230
static inline enum aarch64_opnd_qualifier
231
get_vreg_qualifier_from_value (aarch64_insn value)
232
0
{
233
0
  enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
234
235
  /* Instructions using vector type 2H should not call this function.  Skip over
236
     the 2H qualifier.  */
237
0
  if (qualifier >= AARCH64_OPND_QLF_V_2H)
238
0
    qualifier += 1;
239
240
0
  assert (value <= 0x8
241
0
    && aarch64_get_qualifier_standard_value (qualifier) == value);
242
0
  return qualifier;
243
0
}
244
245
/* Given VALUE, return qualifier for an FP or AdvSIMD scalar register.  */
246
static inline enum aarch64_opnd_qualifier
247
get_sreg_qualifier_from_value (aarch64_insn value)
248
0
{
249
0
  enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
250
251
0
  assert (value <= 0x4
252
0
    && aarch64_get_qualifier_standard_value (qualifier) == value);
253
0
  return qualifier;
254
0
}
255
256
/* Given the instruction in *INST which is probably half way through the
257
   decoding and our caller wants to know the expected qualifier for operand
258
   I.  Return such a qualifier if we can establish it; otherwise return
259
   AARCH64_OPND_QLF_NIL.  */
260
261
static aarch64_opnd_qualifier_t
262
get_expected_qualifier (const aarch64_inst *inst, int i)
263
0
{
264
0
  aarch64_opnd_qualifier_seq_t qualifiers;
265
  /* Should not be called if the qualifier is known.  */
266
0
  assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
267
0
  int invalid_count;
268
0
  if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
269
0
             i, qualifiers, &invalid_count))
270
0
    return qualifiers[i];
271
0
  else
272
0
    return AARCH64_OPND_QLF_NIL;
273
0
}
274
275
/* Operand extractors.  */
276
277
bool
278
aarch64_ext_none (const aarch64_operand *self ATTRIBUTE_UNUSED,
279
      aarch64_opnd_info *info ATTRIBUTE_UNUSED,
280
      const aarch64_insn code ATTRIBUTE_UNUSED,
281
      const aarch64_inst *inst ATTRIBUTE_UNUSED,
282
      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
283
0
{
284
0
  return true;
285
0
}
286
287
bool
288
aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
289
       const aarch64_insn code,
290
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
291
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
292
0
{
293
0
  info->reg.regno = (extract_field (self->fields[0], code, 0)
294
0
         + get_operand_specific_data (self));
295
0
  return true;
296
0
}
297
298
bool
299
aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
300
       const aarch64_insn code ATTRIBUTE_UNUSED,
301
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
302
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
303
0
{
304
0
  assert (info->idx == 1
305
0
    || info->idx ==3);
306
0
  info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
307
0
  return true;
308
0
}
309
310
/* e.g. IC <ic_op>{, <Xt>}.  */
311
bool
312
aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
313
        const aarch64_insn code,
314
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
315
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
316
0
{
317
0
  info->reg.regno = extract_field (self->fields[0], code, 0);
318
0
  assert (info->idx == 1
319
0
    && (aarch64_get_operand_class (inst->operands[0].type)
320
0
        == AARCH64_OPND_CLASS_SYSTEM));
321
  /* This will make the constraint checking happy and more importantly will
322
     help the disassembler determine whether this operand is optional or
323
     not.  */
324
0
  info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
325
326
0
  return true;
327
0
}
328
329
/* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
330
bool
331
aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
332
         const aarch64_insn code,
333
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
334
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
335
0
{
336
  /* regno */
337
0
  info->reglane.regno = extract_field (self->fields[0], code,
338
0
               inst->opcode->mask);
339
340
  /* Index and/or type.  */
341
0
  if (inst->opcode->iclass == asisdone
342
0
    || inst->opcode->iclass == asimdins)
343
0
    {
344
0
      if (info->type == AARCH64_OPND_En
345
0
    && inst->opcode->operands[0] == AARCH64_OPND_Ed)
346
0
  {
347
0
    unsigned shift;
348
    /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>].  */
349
0
    assert (info->idx == 1);  /* Vn */
350
0
    aarch64_insn value = extract_field (FLD_imm4_11, code, 0);
351
    /* Depend on AARCH64_OPND_Ed to determine the qualifier.  */
352
0
    info->qualifier = get_expected_qualifier (inst, info->idx);
353
0
    shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
354
0
    info->reglane.index = value >> shift;
355
0
  }
356
0
      else
357
0
  {
358
    /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
359
       imm5<3:0>  <V>
360
       0000 RESERVED
361
       xxx1 B
362
       xx10 H
363
       x100 S
364
       1000 D  */
365
0
    int pos = -1;
366
0
    aarch64_insn value = extract_field (FLD_imm5, code, 0);
367
0
    while (++pos <= 3 && (value & 0x1) == 0)
368
0
      value >>= 1;
369
0
    if (pos > 3)
370
0
      return false;
371
0
    info->qualifier = get_sreg_qualifier_from_value (pos);
372
0
    info->reglane.index = (unsigned) (value >> 1);
373
0
  }
374
0
    }
375
0
  else if (inst->opcode->iclass == dotproduct)
376
0
    {
377
      /* Need information in other operand(s) to help decoding.  */
378
0
      info->qualifier = get_expected_qualifier (inst, info->idx);
379
0
      switch (info->qualifier)
380
0
  {
381
0
  case AARCH64_OPND_QLF_S_4B:
382
0
  case AARCH64_OPND_QLF_S_2H:
383
    /* L:H */
384
0
    info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
385
0
    info->reglane.regno &= 0x1f;
386
0
    break;
387
0
  default:
388
0
    return false;
389
0
  }
390
0
    }
391
0
  else if (inst->opcode->iclass == cryptosm3)
392
0
    {
393
      /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>].  */
394
0
      info->reglane.index = extract_field (FLD_SM3_imm2, code, 0);
395
0
    }
396
0
  else
397
0
    {
398
      /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
399
         or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
400
401
      /* Need information in other operand(s) to help decoding.  */
402
0
      info->qualifier = get_expected_qualifier (inst, info->idx);
403
0
      switch (info->qualifier)
404
0
  {
405
0
  case AARCH64_OPND_QLF_S_H:
406
0
    if (info->type == AARCH64_OPND_Em16)
407
0
      {
408
        /* h:l:m */
409
0
        info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
410
0
                FLD_M);
411
0
        info->reglane.regno &= 0xf;
412
0
      }
413
0
    else
414
0
      {
415
        /* h:l */
416
0
        info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
417
0
      }
418
0
    break;
419
0
  case AARCH64_OPND_QLF_S_S:
420
    /* h:l */
421
0
    info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
422
0
    break;
423
0
  case AARCH64_OPND_QLF_S_D:
424
    /* H */
425
0
    info->reglane.index = extract_field (FLD_H, code, 0);
426
0
    break;
427
0
  default:
428
0
    return false;
429
0
  }
430
431
0
      if (inst->opcode->op == OP_FCMLA_ELEM
432
0
    && info->qualifier != AARCH64_OPND_QLF_S_H)
433
0
  {
434
    /* Complex operand takes two elements.  */
435
0
    if (info->reglane.index & 1)
436
0
      return false;
437
0
    info->reglane.index /= 2;
438
0
  }
439
0
    }
440
441
0
  return true;
442
0
}
443
444
bool
445
aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
446
         const aarch64_insn code,
447
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
448
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
449
0
{
450
  /* R */
451
0
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
452
  /* len */
453
0
  info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
454
0
  info->reglist.stride = 1;
455
0
  return true;
456
0
}
457
458
/* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions.  */
459
bool
460
aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
461
        aarch64_opnd_info *info, const aarch64_insn code,
462
        const aarch64_inst *inst,
463
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
464
0
{
465
0
  aarch64_insn value;
466
  /* Number of elements in each structure to be loaded/stored.  */
467
0
  unsigned expected_num = get_opcode_dependent_value (inst->opcode);
468
469
0
  struct
470
0
    {
471
0
      unsigned is_reserved;
472
0
      unsigned num_regs;
473
0
      unsigned num_elements;
474
0
    } data [] =
475
0
  {   {0, 4, 4},
476
0
      {1, 4, 4},
477
0
      {0, 4, 1},
478
0
      {0, 4, 2},
479
0
      {0, 3, 3},
480
0
      {1, 3, 3},
481
0
      {0, 3, 1},
482
0
      {0, 1, 1},
483
0
      {0, 2, 2},
484
0
      {1, 2, 2},
485
0
      {0, 2, 1},
486
0
  };
487
488
  /* Rt */
489
0
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
490
  /* opcode */
491
0
  value = extract_field (FLD_opcode, code, 0);
492
  /* PR 21595: Check for a bogus value.  */
493
0
  if (value >= ARRAY_SIZE (data))
494
0
    return false;
495
0
  if (expected_num != data[value].num_elements || data[value].is_reserved)
496
0
    return false;
497
0
  info->reglist.num_regs = data[value].num_regs;
498
0
  info->reglist.stride = 1;
499
500
0
  return true;
501
0
}
502
503
/* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
504
   lanes instructions.  */
505
bool
506
aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
507
          aarch64_opnd_info *info, const aarch64_insn code,
508
          const aarch64_inst *inst,
509
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
510
0
{
511
0
  aarch64_insn value;
512
513
  /* Rt */
514
0
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
515
  /* S */
516
0
  value = extract_field (FLD_S, code, 0);
517
518
  /* Number of registers is equal to the number of elements in
519
     each structure to be loaded/stored.  */
520
0
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
521
0
  assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
522
523
  /* Except when it is LD1R.  */
524
0
  if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
525
0
    info->reglist.num_regs = 2;
526
527
0
  info->reglist.stride = 1;
528
0
  return true;
529
0
}
530
531
/* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
532
   load/store single element instructions.  */
533
bool
534
aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
535
         aarch64_opnd_info *info, const aarch64_insn code,
536
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
537
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
538
0
{
539
0
  aarch64_field field = {0, 0};
540
0
  aarch64_insn QSsize;    /* fields Q:S:size.  */
541
0
  aarch64_insn opcodeh2;  /* opcode<2:1> */
542
543
  /* Rt */
544
0
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
545
546
  /* Decode the index, opcode<2:1> and size.  */
547
0
  gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
548
0
  opcodeh2 = extract_field_2 (&field, code, 0);
549
0
  QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
550
0
  switch (opcodeh2)
551
0
    {
552
0
    case 0x0:
553
0
      info->qualifier = AARCH64_OPND_QLF_S_B;
554
      /* Index encoded in "Q:S:size".  */
555
0
      info->reglist.index = QSsize;
556
0
      break;
557
0
    case 0x1:
558
0
      if (QSsize & 0x1)
559
  /* UND.  */
560
0
  return false;
561
0
      info->qualifier = AARCH64_OPND_QLF_S_H;
562
      /* Index encoded in "Q:S:size<1>".  */
563
0
      info->reglist.index = QSsize >> 1;
564
0
      break;
565
0
    case 0x2:
566
0
      if ((QSsize >> 1) & 0x1)
567
  /* UND.  */
568
0
  return false;
569
0
      if ((QSsize & 0x1) == 0)
570
0
  {
571
0
    info->qualifier = AARCH64_OPND_QLF_S_S;
572
    /* Index encoded in "Q:S".  */
573
0
    info->reglist.index = QSsize >> 2;
574
0
  }
575
0
      else
576
0
  {
577
0
    if (extract_field (FLD_S, code, 0))
578
      /* UND */
579
0
      return false;
580
0
    info->qualifier = AARCH64_OPND_QLF_S_D;
581
    /* Index encoded in "Q".  */
582
0
    info->reglist.index = QSsize >> 3;
583
0
  }
584
0
      break;
585
0
    default:
586
0
      return false;
587
0
    }
588
589
0
  info->reglist.has_index = 1;
590
0
  info->reglist.num_regs = 0;
591
0
  info->reglist.stride = 1;
592
  /* Number of registers is equal to the number of elements in
593
     each structure to be loaded/stored.  */
594
0
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
595
0
  assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
596
597
0
  return true;
598
0
}
599
600
/* Decode fields immh:immb and/or Q for e.g.
601
   SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
602
   or SSHR <V><d>, <V><n>, #<shift>.  */
603
604
bool
605
aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
606
             aarch64_opnd_info *info, const aarch64_insn code,
607
             const aarch64_inst *inst,
608
             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
609
0
{
610
0
  int pos;
611
0
  aarch64_insn Q, imm, immh;
612
0
  enum aarch64_insn_class iclass = inst->opcode->iclass;
613
614
0
  immh = extract_field (FLD_immh, code, 0);
615
0
  if (immh == 0)
616
0
    return false;
617
0
  imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
618
0
  pos = 4;
619
  /* Get highest set bit in immh.  */
620
0
  while (--pos >= 0 && (immh & 0x8) == 0)
621
0
    immh <<= 1;
622
623
0
  assert ((iclass == asimdshf || iclass == asisdshf)
624
0
    && (info->type == AARCH64_OPND_IMM_VLSR
625
0
        || info->type == AARCH64_OPND_IMM_VLSL));
626
627
0
  if (iclass == asimdshf)
628
0
    {
629
0
      Q = extract_field (FLD_Q, code, 0);
630
      /* immh Q <T>
631
   0000 x SEE AdvSIMD modified immediate
632
   0001 0 8B
633
   0001 1 16B
634
   001x 0 4H
635
   001x 1 8H
636
   01xx 0 2S
637
   01xx 1 4S
638
   1xxx 0 RESERVED
639
   1xxx 1 2D  */
640
0
      info->qualifier =
641
0
  get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
642
0
    }
643
0
  else
644
0
    info->qualifier = get_sreg_qualifier_from_value (pos);
645
646
0
  if (info->type == AARCH64_OPND_IMM_VLSR)
647
    /* immh <shift>
648
       0000 SEE AdvSIMD modified immediate
649
       0001 (16-UInt(immh:immb))
650
       001x (32-UInt(immh:immb))
651
       01xx (64-UInt(immh:immb))
652
       1xxx (128-UInt(immh:immb))  */
653
0
    info->imm.value = (16 << pos) - imm;
654
0
  else
655
    /* immh:immb
656
       immh <shift>
657
       0000 SEE AdvSIMD modified immediate
658
       0001 (UInt(immh:immb)-8)
659
       001x (UInt(immh:immb)-16)
660
       01xx (UInt(immh:immb)-32)
661
       1xxx (UInt(immh:immb)-64)  */
662
0
    info->imm.value = imm - (8 << pos);
663
664
0
  return true;
665
0
}
666
667
/* Decode shift immediate for e.g. sshr (imm).  */
668
bool
669
aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
670
          aarch64_opnd_info *info, const aarch64_insn code,
671
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
672
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
673
0
{
674
0
  int64_t imm;
675
0
  aarch64_insn val;
676
0
  val = extract_field (FLD_size, code, 0);
677
0
  switch (val)
678
0
    {
679
0
    case 0: imm = 8; break;
680
0
    case 1: imm = 16; break;
681
0
    case 2: imm = 32; break;
682
0
    default: return false;
683
0
    }
684
0
  info->imm.value = imm;
685
0
  return true;
686
0
}
687
688
/* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
689
   value in the field(s) will be extracted as unsigned immediate value.  */
690
bool
691
aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
692
     const aarch64_insn code,
693
     const aarch64_inst *inst,
694
     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
695
0
{
696
0
  uint64_t imm;
697
698
0
  imm = extract_all_fields (self, code);
699
700
0
  if (operand_need_sign_extension (self))
701
0
    imm = sign_extend (imm, get_operand_fields_width (self) - 1);
702
703
0
  if (operand_need_shift_by_two (self))
704
0
    imm <<= 2;
705
0
  else if (operand_need_shift_by_three (self))
706
0
    imm <<= 3;
707
0
  else if (operand_need_shift_by_four (self))
708
0
    imm <<= 4;
709
710
0
  if (info->type == AARCH64_OPND_ADDR_ADRP)
711
0
    imm <<= 12;
712
713
0
  if (inst->operands[0].type == AARCH64_OPND_PSTATEFIELD
714
0
      && inst->operands[0].sysreg.flags & F_IMM_IN_CRM)
715
0
    imm &= PSTATE_DECODE_CRM_IMM (inst->operands[0].sysreg.flags);
716
717
0
  info->imm.value = imm;
718
0
  return true;
719
0
}
720
721
/* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}.  */
722
bool
723
aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
724
          const aarch64_insn code,
725
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
726
          aarch64_operand_error *errors)
727
0
{
728
0
  aarch64_ext_imm (self, info, code, inst, errors);
729
0
  info->shifter.kind = AARCH64_MOD_LSL;
730
0
  info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
731
0
  return true;
732
0
}
733
734
/* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
735
     MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}.  */
736
bool
737
aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
738
          aarch64_opnd_info *info,
739
          const aarch64_insn code,
740
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
741
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
742
0
{
743
0
  uint64_t imm;
744
0
  enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
745
0
  aarch64_field field = {0, 0};
746
747
0
  assert (info->idx == 1);
748
749
0
  if (info->type == AARCH64_OPND_SIMD_FPIMM)
750
0
    info->imm.is_fp = 1;
751
752
  /* a:b:c:d:e:f:g:h */
753
0
  imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
754
0
  if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
755
0
    {
756
      /* Either MOVI <Dd>, #<imm>
757
   or     MOVI <Vd>.2D, #<imm>.
758
   <imm> is a 64-bit immediate
759
   'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
760
   encoded in "a:b:c:d:e:f:g:h".  */
761
0
      int i;
762
0
      unsigned abcdefgh = imm;
763
0
      for (imm = 0ull, i = 0; i < 8; i++)
764
0
  if (((abcdefgh >> i) & 0x1) != 0)
765
0
    imm |= 0xffull << (8 * i);
766
0
    }
767
0
  info->imm.value = imm;
768
769
  /* cmode */
770
0
  info->qualifier = get_expected_qualifier (inst, info->idx);
771
0
  switch (info->qualifier)
772
0
    {
773
0
    case AARCH64_OPND_QLF_NIL:
774
      /* no shift */
775
0
      info->shifter.kind = AARCH64_MOD_NONE;
776
0
      return 1;
777
0
    case AARCH64_OPND_QLF_LSL:
778
      /* shift zeros */
779
0
      info->shifter.kind = AARCH64_MOD_LSL;
780
0
      switch (aarch64_get_qualifier_esize (opnd0_qualifier))
781
0
  {
782
0
  case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
783
0
  case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
784
0
  case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
785
0
  default: return false;
786
0
  }
787
      /* 00: 0; 01: 8; 10:16; 11:24.  */
788
0
      info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
789
0
      break;
790
0
    case AARCH64_OPND_QLF_MSL:
791
      /* shift ones */
792
0
      info->shifter.kind = AARCH64_MOD_MSL;
793
0
      gen_sub_field (FLD_cmode, 0, 1, &field);    /* per word */
794
0
      info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
795
0
      break;
796
0
    default:
797
0
      return false;
798
0
    }
799
800
0
  return true;
801
0
}
802
803
/* Decode an 8-bit floating-point immediate.  */
804
bool
805
aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info,
806
       const aarch64_insn code,
807
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
808
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
809
0
{
810
0
  info->imm.value = extract_all_fields (self, code);
811
0
  info->imm.is_fp = 1;
812
0
  return true;
813
0
}
814
815
/* Decode a 1-bit rotate immediate (#90 or #270).  */
816
bool
817
aarch64_ext_imm_rotate1 (const aarch64_operand *self, aarch64_opnd_info *info,
818
       const aarch64_insn code,
819
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
820
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
821
0
{
822
0
  uint64_t rot = extract_field (self->fields[0], code, 0);
823
0
  assert (rot < 2U);
824
0
  info->imm.value = rot * 180 + 90;
825
0
  return true;
826
0
}
827
828
/* Decode a 2-bit rotate immediate (#0, #90, #180 or #270).  */
829
bool
830
aarch64_ext_imm_rotate2 (const aarch64_operand *self, aarch64_opnd_info *info,
831
       const aarch64_insn code,
832
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
833
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
834
0
{
835
0
  uint64_t rot = extract_field (self->fields[0], code, 0);
836
0
  assert (rot < 4U);
837
0
  info->imm.value = rot * 90;
838
0
  return true;
839
0
}
840
841
/* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>.  */
842
bool
843
aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
844
       aarch64_opnd_info *info, const aarch64_insn code,
845
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
846
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
847
0
{
848
0
  info->imm.value = 64- extract_field (FLD_scale, code, 0);
849
0
  return true;
850
0
}
851
852
/* Decode arithmetic immediate for e.g.
853
     SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}.  */
854
bool
855
aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
856
      aarch64_opnd_info *info, const aarch64_insn code,
857
      const aarch64_inst *inst ATTRIBUTE_UNUSED,
858
      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
859
0
{
860
0
  aarch64_insn value;
861
862
0
  info->shifter.kind = AARCH64_MOD_LSL;
863
  /* shift */
864
0
  value = extract_field (FLD_shift, code, 0);
865
0
  if (value >= 2)
866
0
    return false;
867
0
  info->shifter.amount = value ? 12 : 0;
868
  /* imm12 (unsigned) */
869
0
  info->imm.value = extract_field (FLD_imm12, code, 0);
870
871
0
  return true;
872
0
}
873
874
/* Return true if VALUE is a valid logical immediate encoding, storing the
875
   decoded value in *RESULT if so.  ESIZE is the number of bytes in the
876
   decoded immediate.  */
877
static bool
878
decode_limm (uint32_t esize, aarch64_insn value, int64_t *result)
879
0
{
880
0
  uint64_t imm, mask;
881
0
  uint32_t N, R, S;
882
0
  unsigned simd_size;
883
884
  /* value is N:immr:imms.  */
885
0
  S = value & 0x3f;
886
0
  R = (value >> 6) & 0x3f;
887
0
  N = (value >> 12) & 0x1;
888
889
  /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
890
     (in other words, right rotated by R), then replicated.  */
891
0
  if (N != 0)
892
0
    {
893
0
      simd_size = 64;
894
0
      mask = 0xffffffffffffffffull;
895
0
    }
896
0
  else
897
0
    {
898
0
      switch (S)
899
0
  {
900
0
  case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32;           break;
901
0
  case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
902
0
  case 0x30 ... 0x37: /* 110xxx */ simd_size =  8; S &= 0x7; break;
903
0
  case 0x38 ... 0x3b: /* 1110xx */ simd_size =  4; S &= 0x3; break;
904
0
  case 0x3c ... 0x3d: /* 11110x */ simd_size =  2; S &= 0x1; break;
905
0
  default: return false;
906
0
  }
907
0
      mask = (1ull << simd_size) - 1;
908
      /* Top bits are IGNORED.  */
909
0
      R &= simd_size - 1;
910
0
    }
911
912
0
  if (simd_size > esize * 8)
913
0
    return false;
914
915
  /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
916
0
  if (S == simd_size - 1)
917
0
    return false;
918
  /* S+1 consecutive bits to 1.  */
919
  /* NOTE: S can't be 63 due to detection above.  */
920
0
  imm = (1ull << (S + 1)) - 1;
921
  /* Rotate to the left by simd_size - R.  */
922
0
  if (R != 0)
923
0
    imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
924
  /* Replicate the value according to SIMD size.  */
925
0
  switch (simd_size)
926
0
    {
927
0
    case  2: imm = (imm <<  2) | imm;
928
      /* Fall through.  */
929
0
    case  4: imm = (imm <<  4) | imm;
930
      /* Fall through.  */
931
0
    case  8: imm = (imm <<  8) | imm;
932
      /* Fall through.  */
933
0
    case 16: imm = (imm << 16) | imm;
934
      /* Fall through.  */
935
0
    case 32: imm = (imm << 32) | imm;
936
      /* Fall through.  */
937
0
    case 64: break;
938
0
    default: return 0;
939
0
    }
940
941
0
  *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
942
943
0
  return true;
944
0
}
945
946
/* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */
947
bool
948
aarch64_ext_limm (const aarch64_operand *self,
949
      aarch64_opnd_info *info, const aarch64_insn code,
950
      const aarch64_inst *inst,
951
      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
952
0
{
953
0
  uint32_t esize;
954
0
  aarch64_insn value;
955
956
0
  value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
957
0
        self->fields[2]);
958
0
  esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
959
0
  return decode_limm (esize, value, &info->imm.value);
960
0
}
961
962
/* Decode a logical immediate for the BIC alias of AND (etc.).  */
963
bool
964
aarch64_ext_inv_limm (const aarch64_operand *self,
965
          aarch64_opnd_info *info, const aarch64_insn code,
966
          const aarch64_inst *inst,
967
          aarch64_operand_error *errors)
968
0
{
969
0
  if (!aarch64_ext_limm (self, info, code, inst, errors))
970
0
    return false;
971
0
  info->imm.value = ~info->imm.value;
972
0
  return true;
973
0
}
974
975
/* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
976
   or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>.  */
977
bool
978
aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
979
    aarch64_opnd_info *info,
980
    const aarch64_insn code, const aarch64_inst *inst,
981
    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
982
0
{
983
0
  aarch64_insn value;
984
985
  /* Rt */
986
0
  info->reg.regno = extract_field (FLD_Rt, code, 0);
987
988
  /* size */
989
0
  value = extract_field (FLD_ldst_size, code, 0);
990
0
  if (inst->opcode->iclass == ldstpair_indexed
991
0
      || inst->opcode->iclass == ldstnapair_offs
992
0
      || inst->opcode->iclass == ldstpair_off
993
0
      || inst->opcode->iclass == loadlit)
994
0
    {
995
0
      enum aarch64_opnd_qualifier qualifier;
996
0
      switch (value)
997
0
  {
998
0
  case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
999
0
  case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
1000
0
  case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
1001
0
  default: return false;
1002
0
  }
1003
0
      info->qualifier = qualifier;
1004
0
    }
1005
0
  else
1006
0
    {
1007
      /* opc1:size */
1008
0
      value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
1009
0
      if (value > 0x4)
1010
0
  return false;
1011
0
      info->qualifier = get_sreg_qualifier_from_value (value);
1012
0
    }
1013
1014
0
  return true;
1015
0
}
1016
1017
/* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}].  */
1018
bool
1019
aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
1020
       aarch64_opnd_info *info,
1021
       aarch64_insn code,
1022
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1023
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1024
0
{
1025
  /* Rn */
1026
0
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1027
0
  return true;
1028
0
}
1029
1030
/* Decode the address operand for e.g.
1031
     stlur <Xt>, [<Xn|SP>{, <amount>}].  */
1032
bool
1033
aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
1034
       aarch64_opnd_info *info,
1035
       aarch64_insn code, const aarch64_inst *inst,
1036
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1037
0
{
1038
0
  info->qualifier = get_expected_qualifier (inst, info->idx);
1039
1040
  /* Rn */
1041
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1042
1043
  /* simm9 */
1044
0
  aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
1045
0
  info->addr.offset.imm = sign_extend (imm, 8);
1046
0
  if (extract_field (self->fields[2], code, 0) == 1) {
1047
0
    info->addr.writeback = 1;
1048
0
    info->addr.preind = 1;
1049
0
  }
1050
0
  return true;
1051
0
}
1052
1053
/* Decode the address operand for e.g.
1054
     STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
1055
bool
1056
aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
1057
       aarch64_opnd_info *info,
1058
       aarch64_insn code, const aarch64_inst *inst,
1059
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1060
0
{
1061
0
  aarch64_insn S, value;
1062
1063
  /* Rn */
1064
0
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1065
  /* Rm */
1066
0
  info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1067
  /* option */
1068
0
  value = extract_field (FLD_option, code, 0);
1069
0
  info->shifter.kind =
1070
0
    aarch64_get_operand_modifier_from_value (value, true /* extend_p */);
1071
  /* Fix-up the shifter kind; although the table-driven approach is
1072
     efficient, it is slightly inflexible, thus needing this fix-up.  */
1073
0
  if (info->shifter.kind == AARCH64_MOD_UXTX)
1074
0
    info->shifter.kind = AARCH64_MOD_LSL;
1075
  /* S */
1076
0
  S = extract_field (FLD_S, code, 0);
1077
0
  if (S == 0)
1078
0
    {
1079
0
      info->shifter.amount = 0;
1080
0
      info->shifter.amount_present = 0;
1081
0
    }
1082
0
  else
1083
0
    {
1084
0
      int size;
1085
      /* Need information in other operand(s) to help achieve the decoding
1086
   from 'S' field.  */
1087
0
      info->qualifier = get_expected_qualifier (inst, info->idx);
1088
      /* Get the size of the data element that is accessed, which may be
1089
   different from that of the source register size, e.g. in strb/ldrb.  */
1090
0
      size = aarch64_get_qualifier_esize (info->qualifier);
1091
0
      info->shifter.amount = get_logsz (size);
1092
0
      info->shifter.amount_present = 1;
1093
0
    }
1094
1095
0
  return true;
1096
0
}
1097
1098
/* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>.  */
1099
bool
1100
aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
1101
           aarch64_insn code, const aarch64_inst *inst,
1102
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1103
0
{
1104
0
  aarch64_insn imm;
1105
0
  info->qualifier = get_expected_qualifier (inst, info->idx);
1106
1107
  /* Rn */
1108
0
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1109
  /* simm (imm9 or imm7)  */
1110
0
  imm = extract_field (self->fields[0], code, 0);
1111
0
  info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
1112
0
  if (self->fields[0] == FLD_imm7
1113
0
      || info->qualifier == AARCH64_OPND_QLF_imm_tag)
1114
    /* scaled immediate in ld/st pair instructions.  */
1115
0
    info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
1116
  /* qualifier */
1117
0
  if (inst->opcode->iclass == ldst_unscaled
1118
0
      || inst->opcode->iclass == ldstnapair_offs
1119
0
      || inst->opcode->iclass == ldstpair_off
1120
0
      || inst->opcode->iclass == ldst_unpriv)
1121
0
    info->addr.writeback = 0;
1122
0
  else
1123
0
    {
1124
      /* pre/post- index */
1125
0
      info->addr.writeback = 1;
1126
0
      if (extract_field (self->fields[1], code, 0) == 1)
1127
0
  info->addr.preind = 1;
1128
0
      else
1129
0
  info->addr.postind = 1;
1130
0
    }
1131
1132
0
  return true;
1133
0
}
1134
1135
/* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}].  */
1136
bool
1137
aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
1138
       aarch64_insn code,
1139
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1140
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1141
0
{
1142
0
  int shift;
1143
0
  info->qualifier = get_expected_qualifier (inst, info->idx);
1144
0
  shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
1145
  /* Rn */
1146
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1147
  /* uimm12 */
1148
0
  info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
1149
0
  return true;
1150
0
}
1151
1152
/* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}].  */
1153
bool
1154
aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info,
1155
       aarch64_insn code,
1156
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1157
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1158
0
{
1159
0
  aarch64_insn imm;
1160
1161
0
  info->qualifier = get_expected_qualifier (inst, info->idx);
1162
  /* Rn */
1163
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1164
  /* simm10 */
1165
0
  imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
1166
0
  info->addr.offset.imm = sign_extend (imm, 9) << 3;
1167
0
  if (extract_field (self->fields[3], code, 0) == 1) {
1168
0
    info->addr.writeback = 1;
1169
0
    info->addr.preind = 1;
1170
0
  }
1171
0
  return true;
1172
0
}
1173
1174
/* Decode the address operand for e.g.
1175
     LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>.  */
1176
bool
1177
aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
1178
          aarch64_opnd_info *info,
1179
          aarch64_insn code, const aarch64_inst *inst,
1180
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1181
0
{
1182
  /* The opcode dependent area stores the number of elements in
1183
     each structure to be loaded/stored.  */
1184
0
  int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
1185
1186
  /* Rn */
1187
0
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1188
  /* Rm | #<amount>  */
1189
0
  info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1190
0
  if (info->addr.offset.regno == 31)
1191
0
    {
1192
0
      if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
1193
  /* Special handling of loading single structure to all lane.  */
1194
0
  info->addr.offset.imm = (is_ld1r ? 1
1195
0
         : inst->operands[0].reglist.num_regs)
1196
0
    * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1197
0
      else
1198
0
  info->addr.offset.imm = inst->operands[0].reglist.num_regs
1199
0
    * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
1200
0
    * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
1201
0
    }
1202
0
  else
1203
0
    info->addr.offset.is_reg = 1;
1204
0
  info->addr.writeback = 1;
1205
1206
0
  return true;
1207
0
}
1208
1209
/* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>.  */
1210
bool
1211
aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
1212
      aarch64_opnd_info *info,
1213
      aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1214
      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1215
0
{
1216
0
  aarch64_insn value;
1217
  /* cond */
1218
0
  value = extract_field (FLD_cond, code, 0);
1219
0
  info->cond = get_cond_from_value (value);
1220
0
  return true;
1221
0
}
1222
1223
/* Decode the system register operand for e.g. MRS <Xt>, <systemreg>.  */
1224
bool
1225
aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
1226
        aarch64_opnd_info *info,
1227
        aarch64_insn code,
1228
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
1229
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1230
0
{
1231
  /* op0:op1:CRn:CRm:op2 */
1232
0
  info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
1233
0
               FLD_CRm, FLD_op2);
1234
0
  info->sysreg.flags = 0;
1235
1236
  /* If a system instruction, check which restrictions should be on the register
1237
     value during decoding, these will be enforced then.  */
1238
0
  if (inst->opcode->iclass == ic_system)
1239
0
    {
1240
      /* Check to see if it's read-only, else check if it's write only.
1241
   if it's both or unspecified don't care.  */
1242
0
      if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ)
1243
0
  info->sysreg.flags = F_REG_READ;
1244
0
      else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE))
1245
0
         == F_SYS_WRITE)
1246
0
  info->sysreg.flags = F_REG_WRITE;
1247
0
    }
1248
1249
0
  return true;
1250
0
}
1251
1252
/* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>.  */
1253
bool
1254
aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
1255
       aarch64_opnd_info *info, aarch64_insn code,
1256
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1257
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1258
0
{
1259
0
  int i;
1260
0
  aarch64_insn fld_crm = extract_field (FLD_CRm, code, 0);
1261
  /* op1:op2 */
1262
0
  info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1263
0
  for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1264
0
    if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1265
0
      {
1266
        /* PSTATEFIELD name can be encoded partially in CRm[3:1].  */
1267
0
        uint32_t flags = aarch64_pstatefields[i].flags;
1268
0
        if ((flags & F_REG_IN_CRM)
1269
0
            && ((fld_crm & 0xe) != PSTATE_DECODE_CRM (flags)))
1270
0
          continue;
1271
0
        info->sysreg.flags = flags;
1272
0
        return true;
1273
0
      }
1274
  /* Reserved value in <pstatefield>.  */
1275
0
  return false;
1276
0
}
1277
1278
/* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>.  */
1279
bool
1280
aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
1281
           aarch64_opnd_info *info,
1282
           aarch64_insn code,
1283
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
1284
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1285
0
{
1286
0
  int i;
1287
0
  aarch64_insn value;
1288
0
  const aarch64_sys_ins_reg *sysins_ops;
1289
  /* op0:op1:CRn:CRm:op2 */
1290
0
  value = extract_fields (code, 0, 5,
1291
0
        FLD_op0, FLD_op1, FLD_CRn,
1292
0
        FLD_CRm, FLD_op2);
1293
1294
0
  switch (info->type)
1295
0
    {
1296
0
    case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1297
0
    case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1298
0
    case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1299
0
    case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1300
0
    case AARCH64_OPND_SYSREG_SR:
1301
0
  sysins_ops = aarch64_sys_regs_sr;
1302
   /* Let's remove op2 for rctx.  Refer to comments in the definition of
1303
      aarch64_sys_regs_sr[].  */
1304
0
  value = value & ~(0x7);
1305
0
  break;
1306
0
    default: return false;
1307
0
    }
1308
1309
0
  for (i = 0; sysins_ops[i].name != NULL; ++i)
1310
0
    if (sysins_ops[i].value == value)
1311
0
      {
1312
0
  info->sysins_op = sysins_ops + i;
1313
0
  DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1314
0
         info->sysins_op->name,
1315
0
         (unsigned)info->sysins_op->value,
1316
0
         aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1317
0
  return true;
1318
0
      }
1319
1320
0
  return false;
1321
0
}
1322
1323
/* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>.  */
1324
1325
bool
1326
aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
1327
         aarch64_opnd_info *info,
1328
         aarch64_insn code,
1329
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
1330
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1331
0
{
1332
  /* CRm */
1333
0
  info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1334
0
  return true;
1335
0
}
1336
1337
/* Decode the memory barrier option operand for DSB <option>nXS|#<imm>.  */
1338
1339
bool
1340
aarch64_ext_barrier_dsb_nxs (const aarch64_operand *self ATTRIBUTE_UNUSED,
1341
         aarch64_opnd_info *info,
1342
         aarch64_insn code,
1343
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
1344
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1345
0
{
1346
  /* For the DSB nXS barrier variant immediate is encoded in 2-bit field.  */
1347
0
  aarch64_insn field = extract_field (FLD_CRm_dsb_nxs, code, 0);
1348
0
  info->barrier = aarch64_barrier_dsb_nxs_options + field;
1349
0
  return true;
1350
0
}
1351
1352
/* Decode the prefetch operation option operand for e.g.
1353
     PRFM <prfop>, [<Xn|SP>{, #<pimm>}].  */
1354
1355
bool
1356
aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
1357
       aarch64_opnd_info *info,
1358
       aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1359
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1360
0
{
1361
  /* prfop in Rt */
1362
0
  info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1363
0
  return true;
1364
0
}
1365
1366
/* Decode the hint number for an alias taking an operand.  Set info->hint_option
1367
   to the matching name/value pair in aarch64_hint_options.  */
1368
1369
bool
1370
aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
1371
      aarch64_opnd_info *info,
1372
      aarch64_insn code,
1373
      const aarch64_inst *inst ATTRIBUTE_UNUSED,
1374
      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1375
0
{
1376
  /* CRm:op2.  */
1377
0
  unsigned hint_number;
1378
0
  int i;
1379
1380
0
  hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1381
1382
0
  for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1383
0
    {
1384
0
      if (hint_number == HINT_VAL (aarch64_hint_options[i].value))
1385
0
  {
1386
0
    info->hint_option = &(aarch64_hint_options[i]);
1387
0
    return true;
1388
0
  }
1389
0
    }
1390
1391
0
  return false;
1392
0
}
1393
1394
/* Decode the extended register operand for e.g.
1395
     STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
1396
bool
1397
aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
1398
        aarch64_opnd_info *info,
1399
        aarch64_insn code,
1400
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
1401
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1402
0
{
1403
0
  aarch64_insn value;
1404
1405
  /* Rm */
1406
0
  info->reg.regno = extract_field (FLD_Rm, code, 0);
1407
  /* option */
1408
0
  value = extract_field (FLD_option, code, 0);
1409
0
  info->shifter.kind =
1410
0
    aarch64_get_operand_modifier_from_value (value, true /* extend_p */);
1411
  /* imm3 */
1412
0
  info->shifter.amount = extract_field (FLD_imm3_10, code,  0);
1413
1414
  /* This makes the constraint checking happy.  */
1415
0
  info->shifter.operator_present = 1;
1416
1417
  /* Assume inst->operands[0].qualifier has been resolved.  */
1418
0
  assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
1419
0
  info->qualifier = AARCH64_OPND_QLF_W;
1420
0
  if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1421
0
      && (info->shifter.kind == AARCH64_MOD_UXTX
1422
0
    || info->shifter.kind == AARCH64_MOD_SXTX))
1423
0
    info->qualifier = AARCH64_OPND_QLF_X;
1424
1425
0
  return true;
1426
0
}
1427
1428
/* Decode the shifted register operand for e.g.
1429
     SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}.  */
1430
bool
1431
aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
1432
       aarch64_opnd_info *info,
1433
       aarch64_insn code,
1434
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1435
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1436
0
{
1437
0
  aarch64_insn value;
1438
1439
  /* Rm */
1440
0
  info->reg.regno = extract_field (FLD_Rm, code, 0);
1441
  /* shift */
1442
0
  value = extract_field (FLD_shift, code, 0);
1443
0
  info->shifter.kind =
1444
0
    aarch64_get_operand_modifier_from_value (value, false /* extend_p */);
1445
0
  if (info->shifter.kind == AARCH64_MOD_ROR
1446
0
      && inst->opcode->iclass != log_shift)
1447
    /* ROR is not available for the shifted register operand in arithmetic
1448
       instructions.  */
1449
0
    return false;
1450
  /* imm6 */
1451
0
  info->shifter.amount = extract_field (FLD_imm6_10, code,  0);
1452
1453
  /* This makes the constraint checking happy.  */
1454
0
  info->shifter.operator_present = 1;
1455
1456
0
  return true;
1457
0
}
1458
1459
/* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1460
   where <offset> is given by the OFFSET parameter and where <factor> is
1461
   1 plus SELF's operand-dependent value.  fields[0] specifies the field
1462
   that holds <base>.  */
1463
static bool
1464
aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand *self,
1465
         aarch64_opnd_info *info, aarch64_insn code,
1466
         int64_t offset)
1467
0
{
1468
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1469
0
  info->addr.offset.imm = offset * (1 + get_operand_specific_data (self));
1470
0
  info->addr.offset.is_reg = false;
1471
0
  info->addr.writeback = false;
1472
0
  info->addr.preind = true;
1473
0
  if (offset != 0)
1474
0
    info->shifter.kind = AARCH64_MOD_MUL_VL;
1475
0
  info->shifter.amount = 1;
1476
0
  info->shifter.operator_present = (info->addr.offset.imm != 0);
1477
0
  info->shifter.amount_present = false;
1478
0
  return true;
1479
0
}
1480
1481
/* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1482
   where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1483
   SELF's operand-dependent value.  fields[0] specifies the field that
1484
   holds <base>.  <simm4> is encoded in the SVE_imm4 field.  */
1485
bool
1486
aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand *self,
1487
             aarch64_opnd_info *info, aarch64_insn code,
1488
             const aarch64_inst *inst ATTRIBUTE_UNUSED,
1489
             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1490
0
{
1491
0
  int offset;
1492
1493
0
  offset = extract_field (FLD_SVE_imm4, code, 0);
1494
0
  offset = ((offset + 8) & 15) - 8;
1495
0
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1496
0
}
1497
1498
/* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1499
   where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1500
   SELF's operand-dependent value.  fields[0] specifies the field that
1501
   holds <base>.  <simm6> is encoded in the SVE_imm6 field.  */
1502
bool
1503
aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand *self,
1504
             aarch64_opnd_info *info, aarch64_insn code,
1505
             const aarch64_inst *inst ATTRIBUTE_UNUSED,
1506
             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1507
0
{
1508
0
  int offset;
1509
1510
0
  offset = extract_field (FLD_SVE_imm6, code, 0);
1511
0
  offset = (((offset + 32) & 63) - 32);
1512
0
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1513
0
}
1514
1515
/* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1516
   where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1517
   SELF's operand-dependent value.  fields[0] specifies the field that
1518
   holds <base>.  <simm9> is encoded in the concatenation of the SVE_imm6
1519
   and imm3 fields, with imm3 being the less-significant part.  */
1520
bool
1521
aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand *self,
1522
             aarch64_opnd_info *info,
1523
             aarch64_insn code,
1524
             const aarch64_inst *inst ATTRIBUTE_UNUSED,
1525
             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1526
0
{
1527
0
  int offset;
1528
1529
0
  offset = extract_fields (code, 0, 2, FLD_SVE_imm6, FLD_imm3_10);
1530
0
  offset = (((offset + 256) & 511) - 256);
1531
0
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1532
0
}
1533
1534
/* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1535
   is given by the OFFSET parameter and where <shift> is SELF's operand-
1536
   dependent value.  fields[0] specifies the base register field <base>.  */
1537
static bool
1538
aarch64_ext_sve_addr_reg_imm (const aarch64_operand *self,
1539
            aarch64_opnd_info *info, aarch64_insn code,
1540
            int64_t offset)
1541
0
{
1542
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1543
0
  info->addr.offset.imm = offset * (1 << get_operand_specific_data (self));
1544
0
  info->addr.offset.is_reg = false;
1545
0
  info->addr.writeback = false;
1546
0
  info->addr.preind = true;
1547
0
  info->shifter.operator_present = false;
1548
0
  info->shifter.amount_present = false;
1549
0
  return true;
1550
0
}
1551
1552
/* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1553
   is a 4-bit signed number and where <shift> is SELF's operand-dependent
1554
   value.  fields[0] specifies the base register field.  */
1555
bool
1556
aarch64_ext_sve_addr_ri_s4 (const aarch64_operand *self,
1557
          aarch64_opnd_info *info, aarch64_insn code,
1558
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
1559
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1560
0
{
1561
0
  int offset = sign_extend (extract_field (FLD_SVE_imm4, code, 0), 3);
1562
0
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1563
0
}
1564
1565
/* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1566
   is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1567
   value.  fields[0] specifies the base register field.  */
1568
bool
1569
aarch64_ext_sve_addr_ri_u6 (const aarch64_operand *self,
1570
          aarch64_opnd_info *info, aarch64_insn code,
1571
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
1572
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1573
0
{
1574
0
  int offset = extract_field (FLD_SVE_imm6, code, 0);
1575
0
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1576
0
}
1577
1578
/* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1579
   is SELF's operand-dependent value.  fields[0] specifies the base
1580
   register field and fields[1] specifies the offset register field.  */
1581
bool
1582
aarch64_ext_sve_addr_rr_lsl (const aarch64_operand *self,
1583
           aarch64_opnd_info *info, aarch64_insn code,
1584
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
1585
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1586
0
{
1587
0
  int index_regno;
1588
1589
0
  index_regno = extract_field (self->fields[1], code, 0);
1590
0
  if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
1591
0
    return false;
1592
1593
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1594
0
  info->addr.offset.regno = index_regno;
1595
0
  info->addr.offset.is_reg = true;
1596
0
  info->addr.writeback = false;
1597
0
  info->addr.preind = true;
1598
0
  info->shifter.kind = AARCH64_MOD_LSL;
1599
0
  info->shifter.amount = get_operand_specific_data (self);
1600
0
  info->shifter.operator_present = (info->shifter.amount != 0);
1601
0
  info->shifter.amount_present = (info->shifter.amount != 0);
1602
0
  return true;
1603
0
}
1604
1605
/* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1606
   <shift> is SELF's operand-dependent value.  fields[0] specifies the
1607
   base register field, fields[1] specifies the offset register field and
1608
   fields[2] is a single-bit field that selects SXTW over UXTW.  */
1609
bool
1610
aarch64_ext_sve_addr_rz_xtw (const aarch64_operand *self,
1611
           aarch64_opnd_info *info, aarch64_insn code,
1612
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
1613
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1614
0
{
1615
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1616
0
  info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1617
0
  info->addr.offset.is_reg = true;
1618
0
  info->addr.writeback = false;
1619
0
  info->addr.preind = true;
1620
0
  if (extract_field (self->fields[2], code, 0))
1621
0
    info->shifter.kind = AARCH64_MOD_SXTW;
1622
0
  else
1623
0
    info->shifter.kind = AARCH64_MOD_UXTW;
1624
0
  info->shifter.amount = get_operand_specific_data (self);
1625
0
  info->shifter.operator_present = true;
1626
0
  info->shifter.amount_present = (info->shifter.amount != 0);
1627
0
  return true;
1628
0
}
1629
1630
/* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1631
   5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1632
   fields[0] specifies the base register field.  */
1633
bool
1634
aarch64_ext_sve_addr_zi_u5 (const aarch64_operand *self,
1635
          aarch64_opnd_info *info, aarch64_insn code,
1636
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
1637
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1638
0
{
1639
0
  int offset = extract_field (FLD_imm5, code, 0);
1640
0
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1641
0
}
1642
1643
/* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1644
   where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1645
   number.  fields[0] specifies the base register field and fields[1]
1646
   specifies the offset register field.  */
1647
static bool
1648
aarch64_ext_sve_addr_zz (const aarch64_operand *self, aarch64_opnd_info *info,
1649
       aarch64_insn code, enum aarch64_modifier_kind kind)
1650
0
{
1651
0
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1652
0
  info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1653
0
  info->addr.offset.is_reg = true;
1654
0
  info->addr.writeback = false;
1655
0
  info->addr.preind = true;
1656
0
  info->shifter.kind = kind;
1657
0
  info->shifter.amount = extract_field (FLD_SVE_msz, code, 0);
1658
0
  info->shifter.operator_present = (kind != AARCH64_MOD_LSL
1659
0
            || info->shifter.amount != 0);
1660
0
  info->shifter.amount_present = (info->shifter.amount != 0);
1661
0
  return true;
1662
0
}
1663
1664
/* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1665
   <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
1666
   field and fields[1] specifies the offset register field.  */
1667
bool
1668
aarch64_ext_sve_addr_zz_lsl (const aarch64_operand *self,
1669
           aarch64_opnd_info *info, aarch64_insn code,
1670
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
1671
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1672
0
{
1673
0
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_LSL);
1674
0
}
1675
1676
/* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1677
   <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
1678
   field and fields[1] specifies the offset register field.  */
1679
bool
1680
aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand *self,
1681
            aarch64_opnd_info *info, aarch64_insn code,
1682
            const aarch64_inst *inst ATTRIBUTE_UNUSED,
1683
            aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1684
0
{
1685
0
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_SXTW);
1686
0
}
1687
1688
/* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1689
   <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
1690
   field and fields[1] specifies the offset register field.  */
1691
bool
1692
aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand *self,
1693
            aarch64_opnd_info *info, aarch64_insn code,
1694
            const aarch64_inst *inst ATTRIBUTE_UNUSED,
1695
            aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1696
0
{
1697
0
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
1698
0
}
1699
1700
/* Finish decoding an SVE arithmetic immediate, given that INFO already
1701
   has the raw field value and that the low 8 bits decode to VALUE.  */
1702
static bool
1703
decode_sve_aimm (aarch64_opnd_info *info, int64_t value)
1704
0
{
1705
0
  info->shifter.kind = AARCH64_MOD_LSL;
1706
0
  info->shifter.amount = 0;
1707
0
  if (info->imm.value & 0x100)
1708
0
    {
1709
0
      if (value == 0)
1710
  /* Decode 0x100 as #0, LSL #8.  */
1711
0
  info->shifter.amount = 8;
1712
0
      else
1713
0
  value *= 256;
1714
0
    }
1715
0
  info->shifter.operator_present = (info->shifter.amount != 0);
1716
0
  info->shifter.amount_present = (info->shifter.amount != 0);
1717
0
  info->imm.value = value;
1718
0
  return true;
1719
0
}
1720
1721
/* Decode an SVE ADD/SUB immediate.  */
1722
bool
1723
aarch64_ext_sve_aimm (const aarch64_operand *self,
1724
          aarch64_opnd_info *info, const aarch64_insn code,
1725
          const aarch64_inst *inst,
1726
          aarch64_operand_error *errors)
1727
0
{
1728
0
  return (aarch64_ext_imm (self, info, code, inst, errors)
1729
0
    && decode_sve_aimm (info, (uint8_t) info->imm.value));
1730
0
}
1731
1732
bool
1733
aarch64_ext_sve_aligned_reglist (const aarch64_operand *self,
1734
         aarch64_opnd_info *info, aarch64_insn code,
1735
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
1736
         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1737
0
{
1738
0
  unsigned int num_regs = get_operand_specific_data (self);
1739
0
  unsigned int val = extract_field (self->fields[0], code, 0);
1740
0
  info->reglist.first_regno = val * num_regs;
1741
0
  info->reglist.num_regs = num_regs;
1742
0
  info->reglist.stride = 1;
1743
0
  return true;
1744
0
}
1745
1746
/* Decode an SVE CPY/DUP immediate.  */
1747
bool
1748
aarch64_ext_sve_asimm (const aarch64_operand *self,
1749
           aarch64_opnd_info *info, const aarch64_insn code,
1750
           const aarch64_inst *inst,
1751
           aarch64_operand_error *errors)
1752
0
{
1753
0
  return (aarch64_ext_imm (self, info, code, inst, errors)
1754
0
    && decode_sve_aimm (info, (int8_t) info->imm.value));
1755
0
}
1756
1757
/* Decode a single-bit immediate that selects between #0.5 and #1.0.
1758
   The fields array specifies which field to use.  */
1759
bool
1760
aarch64_ext_sve_float_half_one (const aarch64_operand *self,
1761
        aarch64_opnd_info *info, aarch64_insn code,
1762
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
1763
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1764
0
{
1765
0
  if (extract_field (self->fields[0], code, 0))
1766
0
    info->imm.value = 0x3f800000;
1767
0
  else
1768
0
    info->imm.value = 0x3f000000;
1769
0
  info->imm.is_fp = true;
1770
0
  return true;
1771
0
}
1772
1773
/* Decode a single-bit immediate that selects between #0.5 and #2.0.
1774
   The fields array specifies which field to use.  */
1775
bool
1776
aarch64_ext_sve_float_half_two (const aarch64_operand *self,
1777
        aarch64_opnd_info *info, aarch64_insn code,
1778
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
1779
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1780
0
{
1781
0
  if (extract_field (self->fields[0], code, 0))
1782
0
    info->imm.value = 0x40000000;
1783
0
  else
1784
0
    info->imm.value = 0x3f000000;
1785
0
  info->imm.is_fp = true;
1786
0
  return true;
1787
0
}
1788
1789
/* Decode a single-bit immediate that selects between #0.0 and #1.0.
1790
   The fields array specifies which field to use.  */
1791
bool
1792
aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
1793
        aarch64_opnd_info *info, aarch64_insn code,
1794
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
1795
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1796
0
{
1797
0
  if (extract_field (self->fields[0], code, 0))
1798
0
    info->imm.value = 0x3f800000;
1799
0
  else
1800
0
    info->imm.value = 0x0;
1801
0
  info->imm.is_fp = true;
1802
0
  return true;
1803
0
}
1804
1805
/* Decode ZA tile vector, vector indicator, vector selector, qualifier and
1806
   immediate on numerous SME instruction fields such as MOVA.  */
1807
bool
1808
aarch64_ext_sme_za_hv_tiles (const aarch64_operand *self,
1809
                             aarch64_opnd_info *info, aarch64_insn code,
1810
                             const aarch64_inst *inst ATTRIBUTE_UNUSED,
1811
                             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1812
0
{
1813
0
  int fld_size = extract_field (self->fields[0], code, 0);
1814
0
  int fld_q = extract_field (self->fields[1], code, 0);
1815
0
  int fld_v = extract_field (self->fields[2], code, 0);
1816
0
  int fld_rv = extract_field (self->fields[3], code, 0);
1817
0
  int fld_zan_imm = extract_field (self->fields[4], code, 0);
1818
1819
  /* Deduce qualifier encoded in size and Q fields.  */
1820
0
  if (fld_size == 0)
1821
0
    {
1822
0
      info->indexed_za.regno = 0;
1823
0
      info->indexed_za.index.imm = fld_zan_imm;
1824
0
    }
1825
0
  else if (fld_size == 1)
1826
0
    {
1827
0
      info->indexed_za.regno = fld_zan_imm >> 3;
1828
0
      info->indexed_za.index.imm = fld_zan_imm & 0x07;
1829
0
    }
1830
0
  else if (fld_size == 2)
1831
0
    {
1832
0
      info->indexed_za.regno = fld_zan_imm >> 2;
1833
0
      info->indexed_za.index.imm = fld_zan_imm & 0x03;
1834
0
    }
1835
0
  else if (fld_size == 3 && fld_q == 0)
1836
0
    {
1837
0
      info->indexed_za.regno = fld_zan_imm >> 1;
1838
0
      info->indexed_za.index.imm = fld_zan_imm & 0x01;
1839
0
    }
1840
0
  else if (fld_size == 3 && fld_q == 1)
1841
0
    {
1842
0
      info->indexed_za.regno = fld_zan_imm;
1843
0
      info->indexed_za.index.imm = 0;
1844
0
    }
1845
0
  else
1846
0
    return false;
1847
1848
0
  info->indexed_za.index.regno = fld_rv + 12;
1849
0
  info->indexed_za.v = fld_v;
1850
1851
0
  return true;
1852
0
}
1853
1854
bool
1855
aarch64_ext_sme_za_hv_tiles_range (const aarch64_operand *self,
1856
           aarch64_opnd_info *info, aarch64_insn code,
1857
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
1858
           aarch64_operand_error *errors
1859
             ATTRIBUTE_UNUSED)
1860
0
{
1861
0
  int ebytes = aarch64_get_qualifier_esize (info->qualifier);
1862
0
  int range_size = get_opcode_dependent_value (inst->opcode);
1863
0
  int fld_v = extract_field (self->fields[0], code, 0);
1864
0
  int fld_rv = extract_field (self->fields[1], code, 0);
1865
0
  int fld_zan_imm = extract_field (self->fields[2], code, 0);
1866
0
  int max_value = 16 / range_size / ebytes;
1867
1868
0
  if (max_value == 0)
1869
0
    max_value = 1;
1870
1871
0
  int regno = fld_zan_imm / max_value;
1872
0
  if (regno >= ebytes)
1873
0
    return false;
1874
1875
0
  info->indexed_za.regno = regno;
1876
0
  info->indexed_za.index.imm = (fld_zan_imm % max_value) * range_size;
1877
0
  info->indexed_za.index.countm1 = range_size - 1;
1878
0
  info->indexed_za.index.regno = fld_rv + 12;
1879
0
  info->indexed_za.v = fld_v;
1880
1881
0
  return true;
1882
0
}
1883
1884
/* Decode in SME instruction ZERO list of up to eight 64-bit element tile names
1885
   separated by commas, encoded in the "imm8" field.
1886
1887
   For programmer convenience an assembler must also accept the names of
1888
   32-bit, 16-bit and 8-bit element tiles which are converted into the
1889
   corresponding set of 64-bit element tiles.
1890
*/
1891
bool
1892
aarch64_ext_sme_za_list (const aarch64_operand *self,
1893
                         aarch64_opnd_info *info, aarch64_insn code,
1894
                         const aarch64_inst *inst ATTRIBUTE_UNUSED,
1895
                         aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1896
0
{
1897
0
  int mask = extract_field (self->fields[0], code, 0);
1898
0
  info->imm.value = mask;
1899
0
  return true;
1900
0
}
1901
1902
/* Decode ZA array vector select register (Rv field), optional vector and
1903
   memory offset (imm4_11 field).
1904
*/
1905
bool
1906
aarch64_ext_sme_za_array (const aarch64_operand *self,
1907
                          aarch64_opnd_info *info, aarch64_insn code,
1908
                          const aarch64_inst *inst,
1909
                          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1910
0
{
1911
0
  int regno = extract_field (self->fields[0], code, 0);
1912
0
  if (info->type == AARCH64_OPND_SME_ZA_array_off4)
1913
0
    regno += 12;
1914
0
  else
1915
0
    regno += 8;
1916
0
  int imm = extract_field (self->fields[1], code, 0);
1917
0
  int num_offsets = get_operand_specific_data (self);
1918
0
  if (num_offsets == 0)
1919
0
    num_offsets = 1;
1920
0
  info->indexed_za.index.regno = regno;
1921
0
  info->indexed_za.index.imm = imm * num_offsets;
1922
0
  info->indexed_za.index.countm1 = num_offsets - 1;
1923
0
  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
1924
0
  return true;
1925
0
}
1926
1927
bool
1928
aarch64_ext_sme_addr_ri_u4xvl (const aarch64_operand *self,
1929
                               aarch64_opnd_info *info, aarch64_insn code,
1930
                               const aarch64_inst *inst ATTRIBUTE_UNUSED,
1931
                               aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1932
0
{
1933
0
  int regno = extract_field (self->fields[0], code, 0);
1934
0
  int imm = extract_field (self->fields[1], code, 0);
1935
0
  info->addr.base_regno = regno;
1936
0
  info->addr.offset.imm = imm;
1937
  /* MUL VL operator is always present for this operand.  */
1938
0
  info->shifter.kind = AARCH64_MOD_MUL_VL;
1939
0
  info->shifter.operator_present = (imm != 0);
1940
0
  return true;
1941
0
}
1942
1943
/* Decode {SM|ZA} filed for SMSTART and SMSTOP instructions.  */
1944
bool
1945
aarch64_ext_sme_sm_za (const aarch64_operand *self,
1946
                       aarch64_opnd_info *info, aarch64_insn code,
1947
                       const aarch64_inst *inst ATTRIBUTE_UNUSED,
1948
                       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1949
0
{
1950
0
  info->pstatefield = 0x1b;
1951
0
  aarch64_insn fld_crm = extract_field (self->fields[0], code, 0);
1952
0
  fld_crm >>= 1;    /* CRm[3:1].  */
1953
1954
0
  if (fld_crm == 0x1)
1955
0
    info->reg.regno = 's';
1956
0
  else if (fld_crm == 0x2)
1957
0
    info->reg.regno = 'z';
1958
0
  else
1959
0
    return false;
1960
1961
0
  return true;
1962
0
}
1963
1964
bool
1965
aarch64_ext_sme_pred_reg_with_index (const aarch64_operand *self,
1966
             aarch64_opnd_info *info, aarch64_insn code,
1967
             const aarch64_inst *inst ATTRIBUTE_UNUSED,
1968
             aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1969
0
{
1970
0
  aarch64_insn fld_rm = extract_field (self->fields[0], code, 0);
1971
0
  aarch64_insn fld_pn = extract_field (self->fields[1], code, 0);
1972
0
  aarch64_insn fld_i1 = extract_field (self->fields[2], code, 0);
1973
0
  aarch64_insn fld_tszh = extract_field (self->fields[3], code, 0);
1974
0
  aarch64_insn fld_tszl = extract_field (self->fields[4], code, 0);
1975
0
  int imm;
1976
1977
0
  info->indexed_za.regno = fld_pn;
1978
0
  info->indexed_za.index.regno = fld_rm + 12;
1979
1980
0
  if (fld_tszl & 0x1)
1981
0
    imm = (fld_i1 << 3) | (fld_tszh << 2) | (fld_tszl >> 1);
1982
0
  else if (fld_tszl & 0x2)
1983
0
    imm = (fld_i1 << 2) | (fld_tszh << 1) | (fld_tszl >> 2);
1984
0
  else if (fld_tszl & 0x4)
1985
0
    imm = (fld_i1 << 1) | fld_tszh;
1986
0
  else if (fld_tszh)
1987
0
    imm = fld_i1;
1988
0
  else
1989
0
    return false;
1990
1991
0
  info->indexed_za.index.imm = imm;
1992
0
  return true;
1993
0
}
1994
1995
/* Decode Zn[MM], where MM has a 7-bit triangular encoding.  The fields
1996
   array specifies which field to use for Zn.  MM is encoded in the
1997
   concatenation of imm5 and SVE_tszh, with imm5 being the less
1998
   significant part.  */
1999
bool
2000
aarch64_ext_sve_index (const aarch64_operand *self,
2001
           aarch64_opnd_info *info, aarch64_insn code,
2002
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
2003
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2004
0
{
2005
0
  int val;
2006
2007
0
  info->reglane.regno = extract_field (self->fields[0], code, 0);
2008
0
  val = extract_fields (code, 0, 2, FLD_SVE_tszh, FLD_imm5);
2009
0
  if ((val & 31) == 0)
2010
0
    return 0;
2011
0
  while ((val & 1) == 0)
2012
0
    val /= 2;
2013
0
  info->reglane.index = val / 2;
2014
0
  return true;
2015
0
}
2016
2017
/* Decode a logical immediate for the MOV alias of SVE DUPM.  */
2018
bool
2019
aarch64_ext_sve_limm_mov (const aarch64_operand *self,
2020
        aarch64_opnd_info *info, const aarch64_insn code,
2021
        const aarch64_inst *inst,
2022
        aarch64_operand_error *errors)
2023
0
{
2024
0
  int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
2025
0
  return (aarch64_ext_limm (self, info, code, inst, errors)
2026
0
    && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
2027
0
}
2028
2029
/* Decode Zn[MM], where Zn occupies the least-significant part of the field
2030
   and where MM occupies the most-significant part.  The operand-dependent
2031
   value specifies the number of bits in Zn.  */
2032
bool
2033
aarch64_ext_sve_quad_index (const aarch64_operand *self,
2034
          aarch64_opnd_info *info, aarch64_insn code,
2035
          const aarch64_inst *inst ATTRIBUTE_UNUSED,
2036
          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2037
0
{
2038
0
  unsigned int reg_bits = get_operand_specific_data (self);
2039
0
  unsigned int val = extract_all_fields (self, code);
2040
0
  info->reglane.regno = val & ((1 << reg_bits) - 1);
2041
0
  info->reglane.index = val >> reg_bits;
2042
0
  return true;
2043
0
}
2044
2045
/* Decode {Zn.<T> - Zm.<T>}.  The fields array specifies which field
2046
   to use for Zn.  The opcode-dependent value specifies the number
2047
   of registers in the list.  */
2048
bool
2049
aarch64_ext_sve_reglist (const aarch64_operand *self,
2050
       aarch64_opnd_info *info, aarch64_insn code,
2051
       const aarch64_inst *inst ATTRIBUTE_UNUSED,
2052
       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2053
0
{
2054
0
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
2055
0
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
2056
0
  info->reglist.stride = 1;
2057
0
  return true;
2058
0
}
2059
2060
/* Decode a strided register list.  The first field holds the top bit
2061
   (0 or 16) and the second field holds the lower bits.  The stride is
2062
   16 divided by the list length.  */
2063
bool
2064
aarch64_ext_sve_strided_reglist (const aarch64_operand *self,
2065
         aarch64_opnd_info *info, aarch64_insn code,
2066
         const aarch64_inst *inst ATTRIBUTE_UNUSED,
2067
         aarch64_operand_error *errors
2068
           ATTRIBUTE_UNUSED)
2069
0
{
2070
0
  unsigned int upper = extract_field (self->fields[0], code, 0);
2071
0
  unsigned int lower = extract_field (self->fields[1], code, 0);
2072
0
  info->reglist.first_regno = upper * 16 + lower;
2073
0
  info->reglist.num_regs = get_operand_specific_data (self);
2074
0
  info->reglist.stride = 16 / info->reglist.num_regs;
2075
0
  return true;
2076
0
}
2077
2078
/* Decode <pattern>{, MUL #<amount>}.  The fields array specifies which
2079
   fields to use for <pattern>.  <amount> - 1 is encoded in the SVE_imm4
2080
   field.  */
2081
bool
2082
aarch64_ext_sve_scale (const aarch64_operand *self,
2083
           aarch64_opnd_info *info, aarch64_insn code,
2084
           const aarch64_inst *inst, aarch64_operand_error *errors)
2085
0
{
2086
0
  int val;
2087
2088
0
  if (!aarch64_ext_imm (self, info, code, inst, errors))
2089
0
    return false;
2090
0
  val = extract_field (FLD_SVE_imm4, code, 0);
2091
0
  info->shifter.kind = AARCH64_MOD_MUL;
2092
0
  info->shifter.amount = val + 1;
2093
0
  info->shifter.operator_present = (val != 0);
2094
0
  info->shifter.amount_present = (val != 0);
2095
0
  return true;
2096
0
}
2097
2098
/* Return the top set bit in VALUE, which is expected to be relatively
2099
   small.  */
2100
static uint64_t
2101
get_top_bit (uint64_t value)
2102
0
{
2103
0
  while ((value & -value) != value)
2104
0
    value -= value & -value;
2105
0
  return value;
2106
0
}
2107
2108
/* Decode an SVE shift-left immediate.  */
2109
bool
2110
aarch64_ext_sve_shlimm (const aarch64_operand *self,
2111
      aarch64_opnd_info *info, const aarch64_insn code,
2112
      const aarch64_inst *inst, aarch64_operand_error *errors)
2113
0
{
2114
0
  if (!aarch64_ext_imm (self, info, code, inst, errors)
2115
0
      || info->imm.value == 0)
2116
0
    return false;
2117
2118
0
  info->imm.value -= get_top_bit (info->imm.value);
2119
0
  return true;
2120
0
}
2121
2122
/* Decode an SVE shift-right immediate.  */
2123
bool
2124
aarch64_ext_sve_shrimm (const aarch64_operand *self,
2125
      aarch64_opnd_info *info, const aarch64_insn code,
2126
      const aarch64_inst *inst, aarch64_operand_error *errors)
2127
0
{
2128
0
  if (!aarch64_ext_imm (self, info, code, inst, errors)
2129
0
      || info->imm.value == 0)
2130
0
    return false;
2131
2132
0
  info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
2133
0
  return true;
2134
0
}
2135
2136
/* Decode X0-X30.  Register 31 is unallocated.  */
2137
bool
2138
aarch64_ext_x0_to_x30 (const aarch64_operand *self, aarch64_opnd_info *info,
2139
           const aarch64_insn code,
2140
           const aarch64_inst *inst ATTRIBUTE_UNUSED,
2141
           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2142
0
{
2143
0
  info->reg.regno = extract_field (self->fields[0], code, 0);
2144
0
  return info->reg.regno <= 30;
2145
0
}
2146
2147
/* Decode an indexed register, with the first field being the register
2148
   number and the remaining fields being the index.  */
2149
bool
2150
aarch64_ext_simple_index (const aarch64_operand *self, aarch64_opnd_info *info,
2151
        const aarch64_insn code,
2152
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
2153
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2154
0
{
2155
0
  int bias = get_operand_specific_data (self);
2156
0
  info->reglane.regno = extract_field (self->fields[0], code, 0) + bias;
2157
0
  info->reglane.index = extract_all_fields_after (self, 1, code);
2158
0
  return true;
2159
0
}
2160
2161
/* Decode a plain shift-right immediate, when there is only a single
2162
   element size.  */
2163
bool
2164
aarch64_ext_plain_shrimm (const aarch64_operand *self, aarch64_opnd_info *info,
2165
        const aarch64_insn code,
2166
        const aarch64_inst *inst ATTRIBUTE_UNUSED,
2167
        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
2168
0
{
2169
0
  unsigned int base = 1 << get_operand_field_width (self, 0);
2170
0
  info->imm.value = base - extract_field (self->fields[0], code, 0);
2171
0
  return true;
2172
0
}
2173

2174
/* Bitfields that are commonly used to encode certain operands' information
2175
   may be partially used as part of the base opcode in some instructions.
2176
   For example, the bit 1 of the field 'size' in
2177
     FCVTXN <Vb><d>, <Va><n>
2178
   is actually part of the base opcode, while only size<0> is available
2179
   for encoding the register type.  Another example is the AdvSIMD
2180
   instruction ORR (register), in which the field 'size' is also used for
2181
   the base opcode, leaving only the field 'Q' available to encode the
2182
   vector register arrangement specifier '8B' or '16B'.
2183
2184
   This function tries to deduce the qualifier from the value of partially
2185
   constrained field(s).  Given the VALUE of such a field or fields, the
2186
   qualifiers CANDIDATES and the MASK (indicating which bits are valid for
2187
   operand encoding), the function returns the matching qualifier or
2188
   AARCH64_OPND_QLF_NIL if nothing matches.
2189
2190
   N.B. CANDIDATES is a group of possible qualifiers that are valid for
2191
   one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
2192
   may end with AARCH64_OPND_QLF_NIL.  */
2193
2194
static enum aarch64_opnd_qualifier
2195
get_qualifier_from_partial_encoding (aarch64_insn value,
2196
             const enum aarch64_opnd_qualifier* \
2197
             candidates,
2198
             aarch64_insn mask)
2199
0
{
2200
0
  int i;
2201
0
  DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
2202
0
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
2203
0
    {
2204
0
      aarch64_insn standard_value;
2205
0
      if (candidates[i] == AARCH64_OPND_QLF_NIL)
2206
0
  break;
2207
0
      standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
2208
0
      if ((standard_value & mask) == (value & mask))
2209
0
  return candidates[i];
2210
0
    }
2211
0
  return AARCH64_OPND_QLF_NIL;
2212
0
}
2213
2214
/* Given a list of qualifier sequences, return all possible valid qualifiers
2215
   for operand IDX in QUALIFIERS.
2216
   Assume QUALIFIERS is an array whose length is large enough.  */
2217
2218
static void
2219
get_operand_possible_qualifiers (int idx,
2220
         const aarch64_opnd_qualifier_seq_t *list,
2221
         enum aarch64_opnd_qualifier *qualifiers)
2222
0
{
2223
0
  int i;
2224
0
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
2225
0
    if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
2226
0
      break;
2227
0
}
2228
2229
/* Decode the size Q field for e.g. SHADD.
2230
   We tag one operand with the qualifer according to the code;
2231
   whether the qualifier is valid for this opcode or not, it is the
2232
   duty of the semantic checking.  */
2233
2234
static int
2235
decode_sizeq (aarch64_inst *inst)
2236
0
{
2237
0
  int idx;
2238
0
  enum aarch64_opnd_qualifier qualifier;
2239
0
  aarch64_insn code;
2240
0
  aarch64_insn value, mask;
2241
0
  enum aarch64_field_kind fld_sz;
2242
0
  enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2243
2244
0
  if (inst->opcode->iclass == asisdlse
2245
0
     || inst->opcode->iclass == asisdlsep
2246
0
     || inst->opcode->iclass == asisdlso
2247
0
     || inst->opcode->iclass == asisdlsop)
2248
0
    fld_sz = FLD_vldst_size;
2249
0
  else
2250
0
    fld_sz = FLD_size;
2251
2252
0
  code = inst->value;
2253
0
  value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
2254
  /* Obtain the info that which bits of fields Q and size are actually
2255
     available for operand encoding.  Opcodes like FMAXNM and FMLA have
2256
     size[1] unavailable.  */
2257
0
  mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
2258
2259
  /* The index of the operand we are going to tag a qualifier and the qualifer
2260
     itself are reasoned from the value of the size and Q fields and the
2261
     possible valid qualifier lists.  */
2262
0
  idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
2263
0
  DEBUG_TRACE ("key idx: %d", idx);
2264
2265
  /* For most related instruciton, size:Q are fully available for operand
2266
     encoding.  */
2267
0
  if (mask == 0x7)
2268
0
    {
2269
0
      inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
2270
0
      return 1;
2271
0
    }
2272
2273
0
  get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2274
0
           candidates);
2275
#ifdef DEBUG_AARCH64
2276
  if (debug_dump)
2277
    {
2278
      int i;
2279
      for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
2280
     && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
2281
  DEBUG_TRACE ("qualifier %d: %s", i,
2282
         aarch64_get_qualifier_name(candidates[i]));
2283
      DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
2284
    }
2285
#endif /* DEBUG_AARCH64 */
2286
2287
0
  qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
2288
2289
0
  if (qualifier == AARCH64_OPND_QLF_NIL)
2290
0
    return 0;
2291
2292
0
  inst->operands[idx].qualifier = qualifier;
2293
0
  return 1;
2294
0
}
2295
2296
/* Decode size[0]:Q, i.e. bit 22 and bit 30, for
2297
     e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
2298
2299
static int
2300
decode_asimd_fcvt (aarch64_inst *inst)
2301
0
{
2302
0
  aarch64_field field = {0, 0};
2303
0
  aarch64_insn value;
2304
0
  enum aarch64_opnd_qualifier qualifier;
2305
2306
0
  gen_sub_field (FLD_size, 0, 1, &field);
2307
0
  value = extract_field_2 (&field, inst->value, 0);
2308
0
  qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
2309
0
    : AARCH64_OPND_QLF_V_2D;
2310
0
  switch (inst->opcode->op)
2311
0
    {
2312
0
    case OP_FCVTN:
2313
0
    case OP_FCVTN2:
2314
      /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
2315
0
      inst->operands[1].qualifier = qualifier;
2316
0
      break;
2317
0
    case OP_FCVTL:
2318
0
    case OP_FCVTL2:
2319
      /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>.  */
2320
0
      inst->operands[0].qualifier = qualifier;
2321
0
      break;
2322
0
    default:
2323
0
      return 0;
2324
0
    }
2325
2326
0
  return 1;
2327
0
}
2328
2329
/* Decode size[0], i.e. bit 22, for
2330
     e.g. FCVTXN <Vb><d>, <Va><n>.  */
2331
2332
static int
2333
decode_asisd_fcvtxn (aarch64_inst *inst)
2334
0
{
2335
0
  aarch64_field field = {0, 0};
2336
0
  gen_sub_field (FLD_size, 0, 1, &field);
2337
0
  if (!extract_field_2 (&field, inst->value, 0))
2338
0
    return 0;
2339
0
  inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
2340
0
  return 1;
2341
0
}
2342
2343
/* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>.  */
2344
static int
2345
decode_fcvt (aarch64_inst *inst)
2346
0
{
2347
0
  enum aarch64_opnd_qualifier qualifier;
2348
0
  aarch64_insn value;
2349
0
  const aarch64_field field = {15, 2};
2350
2351
  /* opc dstsize */
2352
0
  value = extract_field_2 (&field, inst->value, 0);
2353
0
  switch (value)
2354
0
    {
2355
0
    case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
2356
0
    case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
2357
0
    case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
2358
0
    default: return 0;
2359
0
    }
2360
0
  inst->operands[0].qualifier = qualifier;
2361
2362
0
  return 1;
2363
0
}
2364
2365
/* Do miscellaneous decodings that are not common enough to be driven by
2366
   flags.  */
2367
2368
static int
2369
do_misc_decoding (aarch64_inst *inst)
2370
0
{
2371
0
  unsigned int value;
2372
0
  switch (inst->opcode->op)
2373
0
    {
2374
0
    case OP_FCVT:
2375
0
      return decode_fcvt (inst);
2376
2377
0
    case OP_FCVTN:
2378
0
    case OP_FCVTN2:
2379
0
    case OP_FCVTL:
2380
0
    case OP_FCVTL2:
2381
0
      return decode_asimd_fcvt (inst);
2382
2383
0
    case OP_FCVTXN_S:
2384
0
      return decode_asisd_fcvtxn (inst);
2385
2386
0
    case OP_MOV_P_P:
2387
0
    case OP_MOVS_P_P:
2388
0
      value = extract_field (FLD_SVE_Pn, inst->value, 0);
2389
0
      return (value == extract_field (FLD_SVE_Pm, inst->value, 0)
2390
0
        && value == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2391
2392
0
    case OP_MOV_Z_P_Z:
2393
0
      return (extract_field (FLD_SVE_Zd, inst->value, 0)
2394
0
        == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2395
2396
0
    case OP_MOV_Z_V:
2397
      /* Index must be zero.  */
2398
0
      value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2399
0
      return value > 0 && value <= 16 && value == (value & -value);
2400
2401
0
    case OP_MOV_Z_Z:
2402
0
      return (extract_field (FLD_SVE_Zn, inst->value, 0)
2403
0
        == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2404
2405
0
    case OP_MOV_Z_Zi:
2406
      /* Index must be nonzero.  */
2407
0
      value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2408
0
      return value > 0 && value != (value & -value);
2409
2410
0
    case OP_MOVM_P_P_P:
2411
0
      return (extract_field (FLD_SVE_Pd, inst->value, 0)
2412
0
        == extract_field (FLD_SVE_Pm, inst->value, 0));
2413
2414
0
    case OP_MOVZS_P_P_P:
2415
0
    case OP_MOVZ_P_P_P:
2416
0
      return (extract_field (FLD_SVE_Pn, inst->value, 0)
2417
0
        == extract_field (FLD_SVE_Pm, inst->value, 0));
2418
2419
0
    case OP_NOTS_P_P_P_Z:
2420
0
    case OP_NOT_P_P_P_Z:
2421
0
      return (extract_field (FLD_SVE_Pm, inst->value, 0)
2422
0
        == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2423
2424
0
    default:
2425
0
      return 0;
2426
0
    }
2427
0
}
2428
2429
/* Opcodes that have fields shared by multiple operands are usually flagged
2430
   with flags.  In this function, we detect such flags, decode the related
2431
   field(s) and store the information in one of the related operands.  The
2432
   'one' operand is not any operand but one of the operands that can
2433
   accommadate all the information that has been decoded.  */
2434
2435
static int
2436
do_special_decoding (aarch64_inst *inst)
2437
0
{
2438
0
  int idx;
2439
0
  aarch64_insn value;
2440
  /* Condition for truly conditional executed instructions, e.g. b.cond.  */
2441
0
  if (inst->opcode->flags & F_COND)
2442
0
    {
2443
0
      value = extract_field (FLD_cond2, inst->value, 0);
2444
0
      inst->cond = get_cond_from_value (value);
2445
0
    }
2446
  /* 'sf' field.  */
2447
0
  if (inst->opcode->flags & F_SF)
2448
0
    {
2449
0
      idx = select_operand_for_sf_field_coding (inst->opcode);
2450
0
      value = extract_field (FLD_sf, inst->value, 0);
2451
0
      inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2452
0
      if ((inst->opcode->flags & F_N)
2453
0
    && extract_field (FLD_N, inst->value, 0) != value)
2454
0
  return 0;
2455
0
    }
2456
  /* 'sf' field.  */
2457
0
  if (inst->opcode->flags & F_LSE_SZ)
2458
0
    {
2459
0
      idx = select_operand_for_sf_field_coding (inst->opcode);
2460
0
      value = extract_field (FLD_lse_sz, inst->value, 0);
2461
0
      inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2462
0
    }
2463
  /* size:Q fields.  */
2464
0
  if (inst->opcode->flags & F_SIZEQ)
2465
0
    return decode_sizeq (inst);
2466
2467
0
  if (inst->opcode->flags & F_FPTYPE)
2468
0
    {
2469
0
      idx = select_operand_for_fptype_field_coding (inst->opcode);
2470
0
      value = extract_field (FLD_type, inst->value, 0);
2471
0
      switch (value)
2472
0
  {
2473
0
  case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
2474
0
  case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
2475
0
  case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
2476
0
  default: return 0;
2477
0
  }
2478
0
    }
2479
2480
0
  if (inst->opcode->flags & F_SSIZE)
2481
0
    {
2482
      /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2483
   of the base opcode.  */
2484
0
      aarch64_insn mask;
2485
0
      enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2486
0
      idx = select_operand_for_scalar_size_field_coding (inst->opcode);
2487
0
      value = extract_field (FLD_size, inst->value, inst->opcode->mask);
2488
0
      mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
2489
      /* For most related instruciton, the 'size' field is fully available for
2490
   operand encoding.  */
2491
0
      if (mask == 0x3)
2492
0
  inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
2493
0
      else
2494
0
  {
2495
0
    get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2496
0
             candidates);
2497
0
    inst->operands[idx].qualifier
2498
0
      = get_qualifier_from_partial_encoding (value, candidates, mask);
2499
0
  }
2500
0
    }
2501
2502
0
  if (inst->opcode->flags & F_T)
2503
0
    {
2504
      /* Num of consecutive '0's on the right side of imm5<3:0>.  */
2505
0
      int num = 0;
2506
0
      unsigned val, Q;
2507
0
      assert (aarch64_get_operand_class (inst->opcode->operands[0])
2508
0
        == AARCH64_OPND_CLASS_SIMD_REG);
2509
      /* imm5<3:0>  q <t>
2510
   0000   x reserved
2511
   xxx1   0 8b
2512
   xxx1   1 16b
2513
   xx10   0 4h
2514
   xx10   1 8h
2515
   x100   0 2s
2516
   x100   1 4s
2517
   1000   0 reserved
2518
   1000   1 2d  */
2519
0
      val = extract_field (FLD_imm5, inst->value, 0);
2520
0
      while ((val & 0x1) == 0 && ++num <= 3)
2521
0
  val >>= 1;
2522
0
      if (num > 3)
2523
0
  return 0;
2524
0
      Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
2525
0
      inst->operands[0].qualifier =
2526
0
  get_vreg_qualifier_from_value ((num << 1) | Q);
2527
0
    }
2528
2529
0
  if (inst->opcode->flags & F_GPRSIZE_IN_Q)
2530
0
    {
2531
      /* Use Rt to encode in the case of e.g.
2532
   STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}].  */
2533
0
      idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
2534
0
      if (idx == -1)
2535
0
  {
2536
    /* Otherwise use the result operand, which has to be a integer
2537
       register.  */
2538
0
    assert (aarch64_get_operand_class (inst->opcode->operands[0])
2539
0
      == AARCH64_OPND_CLASS_INT_REG);
2540
0
    idx = 0;
2541
0
  }
2542
0
      assert (idx == 0 || idx == 1);
2543
0
      value = extract_field (FLD_Q, inst->value, 0);
2544
0
      inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2545
0
    }
2546
2547
0
  if (inst->opcode->flags & F_LDS_SIZE)
2548
0
    {
2549
0
      aarch64_field field = {0, 0};
2550
0
      assert (aarch64_get_operand_class (inst->opcode->operands[0])
2551
0
        == AARCH64_OPND_CLASS_INT_REG);
2552
0
      gen_sub_field (FLD_opc, 0, 1, &field);
2553
0
      value = extract_field_2 (&field, inst->value, 0);
2554
0
      inst->operands[0].qualifier
2555
0
  = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
2556
0
    }
2557
2558
  /* Miscellaneous decoding; done as the last step.  */
2559
0
  if (inst->opcode->flags & F_MISC)
2560
0
    return do_misc_decoding (inst);
2561
2562
0
  return 1;
2563
0
}
2564
2565
/* Converters converting a real opcode instruction to its alias form.  */
2566
2567
/* ROR <Wd>, <Ws>, #<shift>
2568
     is equivalent to:
2569
   EXTR <Wd>, <Ws>, <Ws>, #<shift>.  */
2570
static int
2571
convert_extr_to_ror (aarch64_inst *inst)
2572
0
{
2573
0
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2574
0
    {
2575
0
      copy_operand_info (inst, 2, 3);
2576
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2577
0
      return 1;
2578
0
    }
2579
0
  return 0;
2580
0
}
2581
2582
/* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2583
     is equivalent to:
2584
   USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0.  */
2585
static int
2586
convert_shll_to_xtl (aarch64_inst *inst)
2587
0
{
2588
0
  if (inst->operands[2].imm.value == 0)
2589
0
    {
2590
0
      inst->operands[2].type = AARCH64_OPND_NIL;
2591
0
      return 1;
2592
0
    }
2593
0
  return 0;
2594
0
}
2595
2596
/* Convert
2597
     UBFM <Xd>, <Xn>, #<shift>, #63.
2598
   to
2599
     LSR <Xd>, <Xn>, #<shift>.  */
2600
static int
2601
convert_bfm_to_sr (aarch64_inst *inst)
2602
0
{
2603
0
  int64_t imms, val;
2604
2605
0
  imms = inst->operands[3].imm.value;
2606
0
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2607
0
  if (imms == val)
2608
0
    {
2609
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2610
0
      return 1;
2611
0
    }
2612
2613
0
  return 0;
2614
0
}
2615
2616
/* Convert MOV to ORR.  */
2617
static int
2618
convert_orr_to_mov (aarch64_inst *inst)
2619
0
{
2620
  /* MOV <Vd>.<T>, <Vn>.<T>
2621
     is equivalent to:
2622
     ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>.  */
2623
0
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2624
0
    {
2625
0
      inst->operands[2].type = AARCH64_OPND_NIL;
2626
0
      return 1;
2627
0
    }
2628
0
  return 0;
2629
0
}
2630
2631
/* When <imms> >= <immr>, the instruction written:
2632
     SBFX <Xd>, <Xn>, #<lsb>, #<width>
2633
   is equivalent to:
2634
     SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1).  */
2635
2636
static int
2637
convert_bfm_to_bfx (aarch64_inst *inst)
2638
0
{
2639
0
  int64_t immr, imms;
2640
2641
0
  immr = inst->operands[2].imm.value;
2642
0
  imms = inst->operands[3].imm.value;
2643
0
  if (imms >= immr)
2644
0
    {
2645
0
      int64_t lsb = immr;
2646
0
      inst->operands[2].imm.value = lsb;
2647
0
      inst->operands[3].imm.value = imms + 1 - lsb;
2648
      /* The two opcodes have different qualifiers for
2649
   the immediate operands; reset to help the checking.  */
2650
0
      reset_operand_qualifier (inst, 2);
2651
0
      reset_operand_qualifier (inst, 3);
2652
0
      return 1;
2653
0
    }
2654
2655
0
  return 0;
2656
0
}
2657
2658
/* When <imms> < <immr>, the instruction written:
2659
     SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2660
   is equivalent to:
2661
     SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1).  */
2662
2663
static int
2664
convert_bfm_to_bfi (aarch64_inst *inst)
2665
0
{
2666
0
  int64_t immr, imms, val;
2667
2668
0
  immr = inst->operands[2].imm.value;
2669
0
  imms = inst->operands[3].imm.value;
2670
0
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2671
0
  if (imms < immr)
2672
0
    {
2673
0
      inst->operands[2].imm.value = (val - immr) & (val - 1);
2674
0
      inst->operands[3].imm.value = imms + 1;
2675
      /* The two opcodes have different qualifiers for
2676
   the immediate operands; reset to help the checking.  */
2677
0
      reset_operand_qualifier (inst, 2);
2678
0
      reset_operand_qualifier (inst, 3);
2679
0
      return 1;
2680
0
    }
2681
2682
0
  return 0;
2683
0
}
2684
2685
/* The instruction written:
2686
     BFC <Xd>, #<lsb>, #<width>
2687
   is equivalent to:
2688
     BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1).  */
2689
2690
static int
2691
convert_bfm_to_bfc (aarch64_inst *inst)
2692
0
{
2693
0
  int64_t immr, imms, val;
2694
2695
  /* Should have been assured by the base opcode value.  */
2696
0
  assert (inst->operands[1].reg.regno == 0x1f);
2697
2698
0
  immr = inst->operands[2].imm.value;
2699
0
  imms = inst->operands[3].imm.value;
2700
0
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2701
0
  if (imms < immr)
2702
0
    {
2703
      /* Drop XZR from the second operand.  */
2704
0
      copy_operand_info (inst, 1, 2);
2705
0
      copy_operand_info (inst, 2, 3);
2706
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2707
2708
      /* Recalculate the immediates.  */
2709
0
      inst->operands[1].imm.value = (val - immr) & (val - 1);
2710
0
      inst->operands[2].imm.value = imms + 1;
2711
2712
      /* The two opcodes have different qualifiers for the operands; reset to
2713
   help the checking.  */
2714
0
      reset_operand_qualifier (inst, 1);
2715
0
      reset_operand_qualifier (inst, 2);
2716
0
      reset_operand_qualifier (inst, 3);
2717
2718
0
      return 1;
2719
0
    }
2720
2721
0
  return 0;
2722
0
}
2723
2724
/* The instruction written:
2725
     LSL <Xd>, <Xn>, #<shift>
2726
   is equivalent to:
2727
     UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>).  */
2728
2729
static int
2730
convert_ubfm_to_lsl (aarch64_inst *inst)
2731
0
{
2732
0
  int64_t immr = inst->operands[2].imm.value;
2733
0
  int64_t imms = inst->operands[3].imm.value;
2734
0
  int64_t val
2735
0
    = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2736
2737
0
  if ((immr == 0 && imms == val) || immr == imms + 1)
2738
0
    {
2739
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2740
0
      inst->operands[2].imm.value = val - imms;
2741
0
      return 1;
2742
0
    }
2743
2744
0
  return 0;
2745
0
}
2746
2747
/* CINC <Wd>, <Wn>, <cond>
2748
     is equivalent to:
2749
   CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2750
     where <cond> is not AL or NV.  */
2751
2752
static int
2753
convert_from_csel (aarch64_inst *inst)
2754
0
{
2755
0
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
2756
0
      && (inst->operands[3].cond->value & 0xe) != 0xe)
2757
0
    {
2758
0
      copy_operand_info (inst, 2, 3);
2759
0
      inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
2760
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2761
0
      return 1;
2762
0
    }
2763
0
  return 0;
2764
0
}
2765
2766
/* CSET <Wd>, <cond>
2767
     is equivalent to:
2768
   CSINC <Wd>, WZR, WZR, invert(<cond>)
2769
     where <cond> is not AL or NV.  */
2770
2771
static int
2772
convert_csinc_to_cset (aarch64_inst *inst)
2773
0
{
2774
0
  if (inst->operands[1].reg.regno == 0x1f
2775
0
      && inst->operands[2].reg.regno == 0x1f
2776
0
      && (inst->operands[3].cond->value & 0xe) != 0xe)
2777
0
    {
2778
0
      copy_operand_info (inst, 1, 3);
2779
0
      inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
2780
0
      inst->operands[3].type = AARCH64_OPND_NIL;
2781
0
      inst->operands[2].type = AARCH64_OPND_NIL;
2782
0
      return 1;
2783
0
    }
2784
0
  return 0;
2785
0
}
2786
2787
/* MOV <Wd>, #<imm>
2788
     is equivalent to:
2789
   MOVZ <Wd>, #<imm16_5>, LSL #<shift>.
2790
2791
   A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2792
   ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2793
   or where a MOVN has an immediate that could be encoded by MOVZ, or where
2794
   MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2795
   machine-instruction mnemonic must be used.  */
2796
2797
static int
2798
convert_movewide_to_mov (aarch64_inst *inst)
2799
0
{
2800
0
  uint64_t value = inst->operands[1].imm.value;
2801
  /* MOVZ/MOVN #0 have a shift amount other than LSL #0.  */
2802
0
  if (value == 0 && inst->operands[1].shifter.amount != 0)
2803
0
    return 0;
2804
0
  inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2805
0
  inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
2806
0
  value <<= inst->operands[1].shifter.amount;
2807
  /* As an alias convertor, it has to be clear that the INST->OPCODE
2808
     is the opcode of the real instruction.  */
2809
0
  if (inst->opcode->op == OP_MOVN)
2810
0
    {
2811
0
      int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2812
0
      value = ~value;
2813
      /* A MOVN has an immediate that could be encoded by MOVZ.  */
2814
0
      if (aarch64_wide_constant_p (value, is32, NULL))
2815
0
  return 0;
2816
0
    }
2817
0
  inst->operands[1].imm.value = value;
2818
0
  inst->operands[1].shifter.amount = 0;
2819
0
  return 1;
2820
0
}
2821
2822
/* MOV <Wd>, #<imm>
2823
     is equivalent to:
2824
   ORR <Wd>, WZR, #<imm>.
2825
2826
   A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2827
   ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2828
   or where a MOVN has an immediate that could be encoded by MOVZ, or where
2829
   MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2830
   machine-instruction mnemonic must be used.  */
2831
2832
static int
2833
convert_movebitmask_to_mov (aarch64_inst *inst)
2834
0
{
2835
0
  int is32;
2836
0
  uint64_t value;
2837
2838
  /* Should have been assured by the base opcode value.  */
2839
0
  assert (inst->operands[1].reg.regno == 0x1f);
2840
0
  copy_operand_info (inst, 1, 2);
2841
0
  is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2842
0
  inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2843
0
  value = inst->operands[1].imm.value;
2844
  /* ORR has an immediate that could be generated by a MOVZ or MOVN
2845
     instruction.  */
2846
0
  if (inst->operands[0].reg.regno != 0x1f
2847
0
      && (aarch64_wide_constant_p (value, is32, NULL)
2848
0
    || aarch64_wide_constant_p (~value, is32, NULL)))
2849
0
    return 0;
2850
2851
0
  inst->operands[2].type = AARCH64_OPND_NIL;
2852
0
  return 1;
2853
0
}
2854
2855
/* Some alias opcodes are disassembled by being converted from their real-form.
2856
   N.B. INST->OPCODE is the real opcode rather than the alias.  */
2857
2858
static int
2859
convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
2860
0
{
2861
0
  switch (alias->op)
2862
0
    {
2863
0
    case OP_ASR_IMM:
2864
0
    case OP_LSR_IMM:
2865
0
      return convert_bfm_to_sr (inst);
2866
0
    case OP_LSL_IMM:
2867
0
      return convert_ubfm_to_lsl (inst);
2868
0
    case OP_CINC:
2869
0
    case OP_CINV:
2870
0
    case OP_CNEG:
2871
0
      return convert_from_csel (inst);
2872
0
    case OP_CSET:
2873
0
    case OP_CSETM:
2874
0
      return convert_csinc_to_cset (inst);
2875
0
    case OP_UBFX:
2876
0
    case OP_BFXIL:
2877
0
    case OP_SBFX:
2878
0
      return convert_bfm_to_bfx (inst);
2879
0
    case OP_SBFIZ:
2880
0
    case OP_BFI:
2881
0
    case OP_UBFIZ:
2882
0
      return convert_bfm_to_bfi (inst);
2883
0
    case OP_BFC:
2884
0
      return convert_bfm_to_bfc (inst);
2885
0
    case OP_MOV_V:
2886
0
      return convert_orr_to_mov (inst);
2887
0
    case OP_MOV_IMM_WIDE:
2888
0
    case OP_MOV_IMM_WIDEN:
2889
0
      return convert_movewide_to_mov (inst);
2890
0
    case OP_MOV_IMM_LOG:
2891
0
      return convert_movebitmask_to_mov (inst);
2892
0
    case OP_ROR_IMM:
2893
0
      return convert_extr_to_ror (inst);
2894
0
    case OP_SXTL:
2895
0
    case OP_SXTL2:
2896
0
    case OP_UXTL:
2897
0
    case OP_UXTL2:
2898
0
      return convert_shll_to_xtl (inst);
2899
0
    default:
2900
0
      return 0;
2901
0
    }
2902
0
}
2903
2904
static bool
2905
aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
2906
           aarch64_inst *, int, aarch64_operand_error *errors);
2907
2908
/* Given the instruction information in *INST, check if the instruction has
2909
   any alias form that can be used to represent *INST.  If the answer is yes,
2910
   update *INST to be in the form of the determined alias.  */
2911
2912
/* In the opcode description table, the following flags are used in opcode
2913
   entries to help establish the relations between the real and alias opcodes:
2914
2915
  F_ALIAS:  opcode is an alias
2916
  F_HAS_ALIAS:  opcode has alias(es)
2917
  F_P1
2918
  F_P2
2919
  F_P3:   Disassembly preference priority 1-3 (the larger the
2920
      higher).  If nothing is specified, it is the priority
2921
      0 by default, i.e. the lowest priority.
2922
2923
   Although the relation between the machine and the alias instructions are not
2924
   explicitly described, it can be easily determined from the base opcode
2925
   values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2926
   description entries:
2927
2928
   The mask of an alias opcode must be equal to or a super-set (i.e. more
2929
   constrained) of that of the aliased opcode; so is the base opcode value.
2930
2931
   if (opcode_has_alias (real) && alias_opcode_p (opcode)
2932
       && (opcode->mask & real->mask) == real->mask
2933
       && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2934
   then OPCODE is an alias of, and only of, the REAL instruction
2935
2936
   The alias relationship is forced flat-structured to keep related algorithm
2937
   simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2938
2939
   During the disassembling, the decoding decision tree (in
2940
   opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2941
   if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2942
   not specified), the disassembler will check whether there is any alias
2943
   instruction exists for this real instruction.  If there is, the disassembler
2944
   will try to disassemble the 32-bit binary again using the alias's rule, or
2945
   try to convert the IR to the form of the alias.  In the case of the multiple
2946
   aliases, the aliases are tried one by one from the highest priority
2947
   (currently the flag F_P3) to the lowest priority (no priority flag), and the
2948
   first succeeds first adopted.
2949
2950
   You may ask why there is a need for the conversion of IR from one form to
2951
   another in handling certain aliases.  This is because on one hand it avoids
2952
   adding more operand code to handle unusual encoding/decoding; on other
2953
   hand, during the disassembling, the conversion is an effective approach to
2954
   check the condition of an alias (as an alias may be adopted only if certain
2955
   conditions are met).
2956
2957
   In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2958
   aarch64_opcode_table and generated aarch64_find_alias_opcode and
2959
   aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help.  */
2960
2961
static void
2962
determine_disassembling_preference (struct aarch64_inst *inst,
2963
            aarch64_operand_error *errors)
2964
0
{
2965
0
  const aarch64_opcode *opcode;
2966
0
  const aarch64_opcode *alias;
2967
2968
0
  opcode = inst->opcode;
2969
2970
  /* This opcode does not have an alias, so use itself.  */
2971
0
  if (!opcode_has_alias (opcode))
2972
0
    return;
2973
2974
0
  alias = aarch64_find_alias_opcode (opcode);
2975
0
  assert (alias);
2976
2977
#ifdef DEBUG_AARCH64
2978
  if (debug_dump)
2979
    {
2980
      const aarch64_opcode *tmp = alias;
2981
      printf ("####   LIST    orderd: ");
2982
      while (tmp)
2983
  {
2984
    printf ("%s, ", tmp->name);
2985
    tmp = aarch64_find_next_alias_opcode (tmp);
2986
  }
2987
      printf ("\n");
2988
    }
2989
#endif /* DEBUG_AARCH64 */
2990
2991
0
  for (; alias; alias = aarch64_find_next_alias_opcode (alias))
2992
0
    {
2993
0
      DEBUG_TRACE ("try %s", alias->name);
2994
0
      assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
2995
2996
      /* An alias can be a pseudo opcode which will never be used in the
2997
   disassembly, e.g. BIC logical immediate is such a pseudo opcode
2998
   aliasing AND.  */
2999
0
      if (pseudo_opcode_p (alias))
3000
0
  {
3001
0
    DEBUG_TRACE ("skip pseudo %s", alias->name);
3002
0
    continue;
3003
0
  }
3004
3005
0
      if ((inst->value & alias->mask) != alias->opcode)
3006
0
  {
3007
0
    DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
3008
0
    continue;
3009
0
  }
3010
3011
0
      if (!AARCH64_CPU_HAS_FEATURE (arch_variant, *alias->avariant))
3012
0
  {
3013
0
    DEBUG_TRACE ("skip %s: we're missing features", alias->name);
3014
0
    continue;
3015
0
  }
3016
3017
      /* No need to do any complicated transformation on operands, if the alias
3018
   opcode does not have any operand.  */
3019
0
      if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
3020
0
  {
3021
0
    DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
3022
0
    aarch64_replace_opcode (inst, alias);
3023
0
    return;
3024
0
  }
3025
0
      if (alias->flags & F_CONV)
3026
0
  {
3027
0
    aarch64_inst copy;
3028
0
    memcpy (&copy, inst, sizeof (aarch64_inst));
3029
    /* ALIAS is the preference as long as the instruction can be
3030
       successfully converted to the form of ALIAS.  */
3031
0
    if (convert_to_alias (&copy, alias) == 1)
3032
0
      {
3033
0
        aarch64_replace_opcode (&copy, alias);
3034
0
        if (aarch64_match_operands_constraint (&copy, NULL) != 1)
3035
0
    {
3036
0
      DEBUG_TRACE ("FAILED with alias %s ", alias->name);
3037
0
    }
3038
0
        else
3039
0
    {
3040
0
      DEBUG_TRACE ("succeed with %s via conversion", alias->name);
3041
0
      memcpy (inst, &copy, sizeof (aarch64_inst));
3042
0
    }
3043
0
        return;
3044
0
      }
3045
0
  }
3046
0
      else
3047
0
  {
3048
    /* Directly decode the alias opcode.  */
3049
0
    aarch64_inst temp;
3050
0
    memset (&temp, '\0', sizeof (aarch64_inst));
3051
0
    if (aarch64_opcode_decode (alias, inst->value, &temp, 1, errors) == 1)
3052
0
      {
3053
0
        DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
3054
0
        memcpy (inst, &temp, sizeof (aarch64_inst));
3055
0
        return;
3056
0
      }
3057
0
  }
3058
0
    }
3059
0
}
3060
3061
/* Some instructions (including all SVE ones) use the instruction class
3062
   to describe how a qualifiers_list index is represented in the instruction
3063
   encoding.  If INST is such an instruction, decode the appropriate fields
3064
   and fill in the operand qualifiers accordingly.  Return true if no
3065
   problems are found.  */
3066
3067
static bool
3068
aarch64_decode_variant_using_iclass (aarch64_inst *inst)
3069
0
{
3070
0
  int i, variant;
3071
3072
0
  variant = 0;
3073
0
  switch (inst->opcode->iclass)
3074
0
    {
3075
0
    case sme_mov:
3076
0
      variant = extract_fields (inst->value, 0, 2, FLD_SME_Q, FLD_SME_size_22);
3077
0
      if (variant >= 4 && variant < 7)
3078
0
  return false;
3079
0
      if (variant == 7)
3080
0
  variant = 4;
3081
0
      break;
3082
3083
0
    case sme_psel:
3084
0
      i = extract_fields (inst->value, 0, 2, FLD_SME_tszh, FLD_SME_tszl);
3085
0
      if (i == 0)
3086
0
  return false;
3087
0
      while ((i & 1) == 0)
3088
0
  {
3089
0
    i >>= 1;
3090
0
    variant += 1;
3091
0
  }
3092
0
      break;
3093
3094
0
    case sme_shift:
3095
0
      i = extract_field (FLD_SVE_tszh, inst->value, 0);
3096
0
      goto sve_shift;
3097
3098
0
    case sme_size_12_bhs:
3099
0
      variant = extract_field (FLD_SME_size_12, inst->value, 0);
3100
0
      if (variant >= 3)
3101
0
  return false;
3102
0
      break;
3103
3104
0
    case sme_size_12_hs:
3105
0
      variant = extract_field (FLD_SME_size_12, inst->value, 0);
3106
0
      if (variant != 1 && variant != 2)
3107
0
  return false;
3108
0
      variant -= 1;
3109
0
      break;
3110
3111
0
    case sme_size_22:
3112
0
      variant = extract_field (FLD_SME_size_22, inst->value, 0);
3113
0
      break;
3114
3115
0
    case sme_size_22_hsd:
3116
0
      variant = extract_field (FLD_SME_size_22, inst->value, 0);
3117
0
      if (variant < 1)
3118
0
  return false;
3119
0
      variant -= 1;
3120
0
      break;
3121
3122
0
    case sme_sz_23:
3123
0
      variant = extract_field (FLD_SME_sz_23, inst->value, 0);
3124
0
      break;
3125
3126
0
    case sve_cpy:
3127
0
      variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_14);
3128
0
      break;
3129
3130
0
    case sve_index:
3131
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
3132
0
      if ((i & 31) == 0)
3133
0
  return false;
3134
0
      while ((i & 1) == 0)
3135
0
  {
3136
0
    i >>= 1;
3137
0
    variant += 1;
3138
0
  }
3139
0
      break;
3140
3141
0
    case sve_limm:
3142
      /* Pick the smallest applicable element size.  */
3143
0
      if ((inst->value & 0x20600) == 0x600)
3144
0
  variant = 0;
3145
0
      else if ((inst->value & 0x20400) == 0x400)
3146
0
  variant = 1;
3147
0
      else if ((inst->value & 0x20000) == 0)
3148
0
  variant = 2;
3149
0
      else
3150
0
  variant = 3;
3151
0
      break;
3152
3153
0
    case sme2_mov:
3154
      /* .D is preferred over the other sizes in disassembly.  */
3155
0
      variant = 3;
3156
0
      break;
3157
3158
0
    case sme_misc:
3159
0
    case sve_misc:
3160
      /* These instructions have only a single variant.  */
3161
0
      break;
3162
3163
0
    case sve_movprfx:
3164
0
      variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_16);
3165
0
      break;
3166
3167
0
    case sve_pred_zm:
3168
0
      variant = extract_field (FLD_SVE_M_4, inst->value, 0);
3169
0
      break;
3170
3171
0
    case sve_shift_pred:
3172
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_8);
3173
0
    sve_shift:
3174
0
      if (i == 0)
3175
0
  return false;
3176
0
      while (i != 1)
3177
0
  {
3178
0
    i >>= 1;
3179
0
    variant += 1;
3180
0
  }
3181
0
      break;
3182
3183
0
    case sve_shift_unpred:
3184
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
3185
0
      goto sve_shift;
3186
3187
0
    case sve_size_bhs:
3188
0
      variant = extract_field (FLD_size, inst->value, 0);
3189
0
      if (variant >= 3)
3190
0
  return false;
3191
0
      break;
3192
3193
0
    case sve_size_bhsd:
3194
0
      variant = extract_field (FLD_size, inst->value, 0);
3195
0
      break;
3196
3197
0
    case sve_size_hsd:
3198
0
      i = extract_field (FLD_size, inst->value, 0);
3199
0
      if (i < 1)
3200
0
  return false;
3201
0
      variant = i - 1;
3202
0
      break;
3203
3204
0
    case sme_fp_sd:
3205
0
    case sme_int_sd:
3206
0
    case sve_size_bh:
3207
0
    case sve_size_sd:
3208
0
      variant = extract_field (FLD_SVE_sz, inst->value, 0);
3209
0
      break;
3210
3211
0
    case sve_size_sd2:
3212
0
      variant = extract_field (FLD_SVE_sz2, inst->value, 0);
3213
0
      break;
3214
3215
0
    case sve_size_hsd2:
3216
0
      i = extract_field (FLD_SVE_size, inst->value, 0);
3217
0
      if (i < 1)
3218
0
  return false;
3219
0
      variant = i - 1;
3220
0
      break;
3221
3222
0
    case sve_size_13:
3223
      /* Ignore low bit of this field since that is set in the opcode for
3224
   instructions of this iclass.  */
3225
0
      i = (extract_field (FLD_size, inst->value, 0) & 2);
3226
0
      variant = (i >> 1);
3227
0
      break;
3228
3229
0
    case sve_shift_tsz_bhsd:
3230
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
3231
0
      if (i == 0)
3232
0
  return false;
3233
0
      while (i != 1)
3234
0
  {
3235
0
    i >>= 1;
3236
0
    variant += 1;
3237
0
  }
3238
0
      break;
3239
3240
0
    case sve_size_tsz_bhs:
3241
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
3242
0
      if (i == 0)
3243
0
  return false;
3244
0
      while (i != 1)
3245
0
  {
3246
0
    if (i & 1)
3247
0
      return false;
3248
0
    i >>= 1;
3249
0
    variant += 1;
3250
0
  }
3251
0
      break;
3252
3253
0
    case sve_shift_tsz_hsd:
3254
0
      i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
3255
0
      if (i == 0)
3256
0
  return false;
3257
0
      while (i != 1)
3258
0
  {
3259
0
    i >>= 1;
3260
0
    variant += 1;
3261
0
  }
3262
0
      break;
3263
3264
0
    default:
3265
      /* No mapping between instruction class and qualifiers.  */
3266
0
      return true;
3267
0
    }
3268
3269
0
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3270
0
    inst->operands[i].qualifier = inst->opcode->qualifiers_list[variant][i];
3271
0
  return true;
3272
0
}
3273
/* Decode the CODE according to OPCODE; fill INST.  Return 0 if the decoding
3274
   fails, which meanes that CODE is not an instruction of OPCODE; otherwise
3275
   return 1.
3276
3277
   If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
3278
   determined and used to disassemble CODE; this is done just before the
3279
   return.  */
3280
3281
static bool
3282
aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
3283
           aarch64_inst *inst, int noaliases_p,
3284
           aarch64_operand_error *errors)
3285
0
{
3286
0
  int i;
3287
3288
0
  DEBUG_TRACE ("enter with %s", opcode->name);
3289
3290
0
  assert (opcode && inst);
3291
3292
  /* Clear inst.  */
3293
0
  memset (inst, '\0', sizeof (aarch64_inst));
3294
3295
  /* Check the base opcode.  */
3296
0
  if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
3297
0
    {
3298
0
      DEBUG_TRACE ("base opcode match FAIL");
3299
0
      goto decode_fail;
3300
0
    }
3301
3302
0
  inst->opcode = opcode;
3303
0
  inst->value = code;
3304
3305
  /* Assign operand codes and indexes.  */
3306
0
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3307
0
    {
3308
0
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3309
0
  break;
3310
0
      inst->operands[i].type = opcode->operands[i];
3311
0
      inst->operands[i].idx = i;
3312
0
    }
3313
3314
  /* Call the opcode decoder indicated by flags.  */
3315
0
  if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
3316
0
    {
3317
0
      DEBUG_TRACE ("opcode flag-based decoder FAIL");
3318
0
      goto decode_fail;
3319
0
    }
3320
3321
  /* Possibly use the instruction class to determine the correct
3322
     qualifier.  */
3323
0
  if (!aarch64_decode_variant_using_iclass (inst))
3324
0
    {
3325
0
      DEBUG_TRACE ("iclass-based decoder FAIL");
3326
0
      goto decode_fail;
3327
0
    }
3328
3329
  /* Call operand decoders.  */
3330
0
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3331
0
    {
3332
0
      const aarch64_operand *opnd;
3333
0
      enum aarch64_opnd type;
3334
3335
0
      type = opcode->operands[i];
3336
0
      if (type == AARCH64_OPND_NIL)
3337
0
  break;
3338
0
      opnd = &aarch64_operands[type];
3339
0
      if (operand_has_extractor (opnd)
3340
0
    && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst,
3341
0
           errors)))
3342
0
  {
3343
0
    DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
3344
0
    goto decode_fail;
3345
0
  }
3346
0
    }
3347
3348
  /* If the opcode has a verifier, then check it now.  */
3349
0
  if (opcode->verifier
3350
0
      && opcode->verifier (inst, code, 0, false, errors, NULL) != ERR_OK)
3351
0
    {
3352
0
      DEBUG_TRACE ("operand verifier FAIL");
3353
0
      goto decode_fail;
3354
0
    }
3355
3356
  /* Match the qualifiers.  */
3357
0
  if (aarch64_match_operands_constraint (inst, NULL) == 1)
3358
0
    {
3359
      /* Arriving here, the CODE has been determined as a valid instruction
3360
   of OPCODE and *INST has been filled with information of this OPCODE
3361
   instruction.  Before the return, check if the instruction has any
3362
   alias and should be disassembled in the form of its alias instead.
3363
   If the answer is yes, *INST will be updated.  */
3364
0
      if (!noaliases_p)
3365
0
  determine_disassembling_preference (inst, errors);
3366
0
      DEBUG_TRACE ("SUCCESS");
3367
0
      return true;
3368
0
    }
3369
0
  else
3370
0
    {
3371
0
      DEBUG_TRACE ("constraint matching FAIL");
3372
0
    }
3373
3374
0
 decode_fail:
3375
0
  return false;
3376
0
}
3377

3378
/* This does some user-friendly fix-up to *INST.  It is currently focus on
3379
   the adjustment of qualifiers to help the printed instruction
3380
   recognized/understood more easily.  */
3381
3382
static void
3383
user_friendly_fixup (aarch64_inst *inst)
3384
0
{
3385
0
  switch (inst->opcode->iclass)
3386
0
    {
3387
0
    case testbranch:
3388
      /* TBNZ Xn|Wn, #uimm6, label
3389
   Test and Branch Not Zero: conditionally jumps to label if bit number
3390
   uimm6 in register Xn is not zero.  The bit number implies the width of
3391
   the register, which may be written and should be disassembled as Wn if
3392
   uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
3393
   */
3394
0
      if (inst->operands[1].imm.value < 32)
3395
0
  inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
3396
0
      break;
3397
0
    default: break;
3398
0
    }
3399
0
}
3400
3401
/* Decode INSN and fill in *INST the instruction information.  An alias
3402
   opcode may be filled in *INSN if NOALIASES_P is FALSE.  Return zero on
3403
   success.  */
3404
3405
enum err_type
3406
aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
3407
         bool noaliases_p,
3408
         aarch64_operand_error *errors)
3409
0
{
3410
0
  const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
3411
3412
#ifdef DEBUG_AARCH64
3413
  if (debug_dump)
3414
    {
3415
      const aarch64_opcode *tmp = opcode;
3416
      printf ("\n");
3417
      DEBUG_TRACE ("opcode lookup:");
3418
      while (tmp != NULL)
3419
  {
3420
    aarch64_verbose ("  %s", tmp->name);
3421
    tmp = aarch64_find_next_opcode (tmp);
3422
  }
3423
    }
3424
#endif /* DEBUG_AARCH64 */
3425
3426
  /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
3427
     distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
3428
     opcode field and value, apart from the difference that one of them has an
3429
     extra field as part of the opcode, but such a field is used for operand
3430
     encoding in other opcode(s) ('immh' in the case of the example).  */
3431
0
  while (opcode != NULL)
3432
0
    {
3433
      /* But only one opcode can be decoded successfully for, as the
3434
   decoding routine will check the constraint carefully.  */
3435
0
      if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p, errors) == 1)
3436
0
  return ERR_OK;
3437
0
      opcode = aarch64_find_next_opcode (opcode);
3438
0
    }
3439
3440
0
  return ERR_UND;
3441
0
}
3442
3443
/* Return a short string to indicate a switch to STYLE.  These strings
3444
   will be embedded into the disassembled operand text (as produced by
3445
   aarch64_print_operand), and then spotted in the print_operands function
3446
   so that the disassembler output can be split by style.  */
3447
3448
static const char *
3449
get_style_text (enum disassembler_style style)
3450
0
{
3451
0
  static bool init = false;
3452
0
  static char formats[16][4];
3453
0
  unsigned num;
3454
3455
  /* First time through we build a string for every possible format.  This
3456
     code relies on there being no more than 16 different styles (there's
3457
     an assert below for this).  */
3458
0
  if (!init)
3459
0
    {
3460
0
      int i;
3461
3462
0
      for (i = 0; i <= 0xf; ++i)
3463
0
  {
3464
0
    int res = snprintf (&formats[i][0], sizeof (formats[i]), "%c%x%c",
3465
0
            STYLE_MARKER_CHAR, i, STYLE_MARKER_CHAR);
3466
0
    assert (res == 3);
3467
0
  }
3468
3469
0
      init = true;
3470
0
    }
3471
3472
  /* Return the string that marks switching to STYLE.  */
3473
0
  num = (unsigned) style;
3474
0
  assert (style <= 0xf);
3475
0
  return formats[num];
3476
0
}
3477
3478
/* Callback used by aarch64_print_operand to apply STYLE to the
3479
   disassembler output created from FMT and ARGS.  The STYLER object holds
3480
   any required state.  Must return a pointer to a string (created from FMT
3481
   and ARGS) that will continue to be valid until the complete disassembled
3482
   instruction has been printed.
3483
3484
   We return a string that includes two embedded style markers, the first,
3485
   places at the start of the string, indicates a switch to STYLE, and the
3486
   second, placed at the end of the string, indicates a switch back to the
3487
   default text style.
3488
3489
   Later, when we print the operand text we take care to collapse any
3490
   adjacent style markers, and to ignore any style markers that appear at
3491
   the very end of a complete operand string.  */
3492
3493
static const char *aarch64_apply_style (struct aarch64_styler *styler,
3494
          enum disassembler_style style,
3495
          const char *fmt,
3496
          va_list args)
3497
0
{
3498
0
  int res;
3499
0
  char *ptr, *tmp;
3500
0
  struct obstack *stack = (struct obstack *) styler->state;
3501
0
  va_list ap;
3502
3503
  /* These are the two strings for switching styles.  */
3504
0
  const char *style_on = get_style_text (style);
3505
0
  const char *style_off = get_style_text (dis_style_text);
3506
3507
  /* Calculate space needed once FMT and ARGS are expanded.  */
3508
0
  va_copy (ap, args);
3509
0
  res = vsnprintf (NULL, 0, fmt, ap);
3510
0
  va_end (ap);
3511
0
  assert (res >= 0);
3512
3513
  /* Allocate space on the obstack for the expanded FMT and ARGS, as well
3514
     as the two strings for switching styles, then write all of these
3515
     strings onto the obstack.  */
3516
0
  ptr = (char *) obstack_alloc (stack, res + strlen (style_on)
3517
0
        + strlen (style_off) + 1);
3518
0
  tmp = stpcpy (ptr, style_on);
3519
0
  res = vsnprintf (tmp, (res + 1), fmt, args);
3520
0
  assert (res >= 0);
3521
0
  tmp += res;
3522
0
  strcpy (tmp, style_off);
3523
3524
0
  return ptr;
3525
0
}
3526
3527
/* Print operands.  */
3528
3529
static void
3530
print_operands (bfd_vma pc, const aarch64_opcode *opcode,
3531
    const aarch64_opnd_info *opnds, struct disassemble_info *info,
3532
    bool *has_notes)
3533
0
{
3534
0
  char *notes = NULL;
3535
0
  int i, pcrel_p, num_printed;
3536
0
  struct aarch64_styler styler;
3537
0
  struct obstack content;
3538
0
  obstack_init (&content);
3539
3540
0
  styler.apply_style = aarch64_apply_style;
3541
0
  styler.state = (void *) &content;
3542
3543
0
  for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3544
0
    {
3545
0
      char str[128];
3546
0
      char cmt[128];
3547
3548
      /* We regard the opcode operand info more, however we also look into
3549
   the inst->operands to support the disassembling of the optional
3550
   operand.
3551
   The two operand code should be the same in all cases, apart from
3552
   when the operand can be optional.  */
3553
0
      if (opcode->operands[i] == AARCH64_OPND_NIL
3554
0
    || opnds[i].type == AARCH64_OPND_NIL)
3555
0
  break;
3556
3557
      /* Generate the operand string in STR.  */
3558
0
      aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
3559
0
           &info->target, &notes, cmt, sizeof (cmt),
3560
0
           arch_variant, &styler);
3561
3562
      /* Print the delimiter (taking account of omitted operand(s)).  */
3563
0
      if (str[0] != '\0')
3564
0
  (*info->fprintf_styled_func) (info->stream, dis_style_text, "%s",
3565
0
              num_printed++ == 0 ? "\t" : ", ");
3566
3567
      /* Print the operand.  */
3568
0
      if (pcrel_p)
3569
0
  (*info->print_address_func) (info->target, info);
3570
0
      else
3571
0
  {
3572
    /* This operand came from aarch64_print_operand, and will include
3573
       embedded strings indicating which style each character should
3574
       have.  In the following code we split the text based on
3575
       CURR_STYLE, and call the styled print callback to print each
3576
       block of text in the appropriate style.  */
3577
0
    char *start, *curr;
3578
0
    enum disassembler_style curr_style = dis_style_text;
3579
3580
0
    start = curr = str;
3581
0
    do
3582
0
      {
3583
0
        if (*curr == '\0'
3584
0
      || (*curr == STYLE_MARKER_CHAR
3585
0
          && ISXDIGIT (*(curr + 1))
3586
0
          && *(curr + 2) == STYLE_MARKER_CHAR))
3587
0
    {
3588
      /* Output content between our START position and CURR.  */
3589
0
      int len = curr - start;
3590
0
      if (len > 0)
3591
0
        {
3592
0
          if ((*info->fprintf_styled_func) (info->stream,
3593
0
              curr_style,
3594
0
              "%.*s",
3595
0
              len, start) < 0)
3596
0
      break;
3597
0
        }
3598
3599
0
      if (*curr == '\0')
3600
0
        break;
3601
3602
      /* Skip over the initial STYLE_MARKER_CHAR.  */
3603
0
      ++curr;
3604
3605
      /* Update the CURR_STYLE.  As there are less than 16
3606
         styles, it is possible, that if the input is corrupted
3607
         in some way, that we might set CURR_STYLE to an
3608
         invalid value.  Don't worry though, we check for this
3609
         situation.  */
3610
0
      if (*curr >= '0' && *curr <= '9')
3611
0
        curr_style = (enum disassembler_style) (*curr - '0');
3612
0
      else if (*curr >= 'a' && *curr <= 'f')
3613
0
        curr_style = (enum disassembler_style) (*curr - 'a' + 10);
3614
0
      else
3615
0
        curr_style = dis_style_text;
3616
3617
      /* Check for an invalid style having been selected.  This
3618
         should never happen, but it doesn't hurt to be a
3619
         little paranoid.  */
3620
0
      if (curr_style > dis_style_comment_start)
3621
0
        curr_style = dis_style_text;
3622
3623
      /* Skip the hex character, and the closing STYLE_MARKER_CHAR.  */
3624
0
      curr += 2;
3625
3626
      /* Reset the START to after the style marker.  */
3627
0
      start = curr;
3628
0
    }
3629
0
        else
3630
0
    ++curr;
3631
0
      }
3632
0
    while (true);
3633
0
  }
3634
3635
      /* Print the comment.  This works because only the last operand ever
3636
   adds a comment.  If that ever changes then we'll need to be
3637
   smarter here.  */
3638
0
      if (cmt[0] != '\0')
3639
0
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
3640
0
              "\t// %s", cmt);
3641
0
    }
3642
3643
0
    if (notes && !no_notes)
3644
0
      {
3645
0
  *has_notes = true;
3646
0
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
3647
0
              "  // note: %s", notes);
3648
0
      }
3649
3650
0
    obstack_free (&content, NULL);
3651
0
}
3652
3653
/* Set NAME to a copy of INST's mnemonic with the "." suffix removed.  */
3654
3655
static void
3656
remove_dot_suffix (char *name, const aarch64_inst *inst)
3657
0
{
3658
0
  char *ptr;
3659
0
  size_t len;
3660
3661
0
  ptr = strchr (inst->opcode->name, '.');
3662
0
  assert (ptr && inst->cond);
3663
0
  len = ptr - inst->opcode->name;
3664
0
  assert (len < 8);
3665
0
  strncpy (name, inst->opcode->name, len);
3666
0
  name[len] = '\0';
3667
0
}
3668
3669
/* Print the instruction mnemonic name.  */
3670
3671
static void
3672
print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
3673
0
{
3674
0
  if (inst->opcode->flags & F_COND)
3675
0
    {
3676
      /* For instructions that are truly conditionally executed, e.g. b.cond,
3677
   prepare the full mnemonic name with the corresponding condition
3678
   suffix.  */
3679
0
      char name[8];
3680
3681
0
      remove_dot_suffix (name, inst);
3682
0
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
3683
0
            "%s.%s", name, inst->cond->names[0]);
3684
0
    }
3685
0
  else
3686
0
    (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
3687
0
          "%s", inst->opcode->name);
3688
0
}
3689
3690
/* Decide whether we need to print a comment after the operands of
3691
   instruction INST.  */
3692
3693
static void
3694
print_comment (const aarch64_inst *inst, struct disassemble_info *info)
3695
0
{
3696
0
  if (inst->opcode->flags & F_COND)
3697
0
    {
3698
0
      char name[8];
3699
0
      unsigned int i, num_conds;
3700
3701
0
      remove_dot_suffix (name, inst);
3702
0
      num_conds = ARRAY_SIZE (inst->cond->names);
3703
0
      for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
3704
0
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
3705
0
              "%s %s.%s",
3706
0
              i == 1 ? "  //" : ",",
3707
0
              name, inst->cond->names[i]);
3708
0
    }
3709
0
}
3710
3711
/* Build notes from verifiers into a string for printing.  */
3712
3713
static void
3714
print_verifier_notes (aarch64_operand_error *detail,
3715
          struct disassemble_info *info)
3716
0
{
3717
0
  if (no_notes)
3718
0
    return;
3719
3720
  /* The output of the verifier cannot be a fatal error, otherwise the assembly
3721
     would not have succeeded.  We can safely ignore these.  */
3722
0
  assert (detail->non_fatal);
3723
3724
0
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
3725
0
        "  // note: ");
3726
0
  switch (detail->kind)
3727
0
    {
3728
0
    case AARCH64_OPDE_A_SHOULD_FOLLOW_B:
3729
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
3730
0
            _("this `%s' should have an immediately"
3731
0
              " preceding `%s'"),
3732
0
            detail->data[0].s, detail->data[1].s);
3733
0
      break;
3734
3735
0
    case AARCH64_OPDE_EXPECTED_A_AFTER_B:
3736
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
3737
0
            _("expected `%s' after previous `%s'"),
3738
0
            detail->data[0].s, detail->data[1].s);
3739
0
      break;
3740
3741
0
    default:
3742
0
      assert (detail->error);
3743
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
3744
0
            "%s", detail->error);
3745
0
      if (detail->index >= 0)
3746
0
  (*info->fprintf_styled_func) (info->stream, dis_style_text,
3747
0
              " at operand %d", detail->index + 1);
3748
0
      break;
3749
0
    }
3750
0
}
3751
3752
/* Print the instruction according to *INST.  */
3753
3754
static void
3755
print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
3756
        const aarch64_insn code,
3757
        struct disassemble_info *info,
3758
        aarch64_operand_error *mismatch_details)
3759
0
{
3760
0
  bool has_notes = false;
3761
3762
0
  print_mnemonic_name (inst, info);
3763
0
  print_operands (pc, inst->opcode, inst->operands, info, &has_notes);
3764
0
  print_comment (inst, info);
3765
3766
  /* We've already printed a note, not enough space to print more so exit.
3767
     Usually notes shouldn't overlap so it shouldn't happen that we have a note
3768
     from a register and instruction at the same time.  */
3769
0
  if (has_notes)
3770
0
    return;
3771
3772
  /* Always run constraint verifiers, this is needed because constraints need to
3773
     maintain a global state regardless of whether the instruction has the flag
3774
     set or not.  */
3775
0
  enum err_type result = verify_constraints (inst, code, pc, false,
3776
0
               mismatch_details, &insn_sequence);
3777
0
  switch (result)
3778
0
    {
3779
0
    case ERR_VFI:
3780
0
      print_verifier_notes (mismatch_details, info);
3781
0
      break;
3782
0
    case ERR_UND:
3783
0
    case ERR_UNP:
3784
0
    case ERR_NYI:
3785
0
    default:
3786
0
      break;
3787
0
    }
3788
0
}
3789
3790
/* Entry-point of the instruction disassembler and printer.  */
3791
3792
static void
3793
print_insn_aarch64_word (bfd_vma pc,
3794
       uint32_t word,
3795
       struct disassemble_info *info,
3796
       aarch64_operand_error *errors)
3797
0
{
3798
0
  static const char *err_msg[ERR_NR_ENTRIES+1] =
3799
0
    {
3800
0
      [ERR_OK]  = "_",
3801
0
      [ERR_UND] = "undefined",
3802
0
      [ERR_UNP] = "unpredictable",
3803
0
      [ERR_NYI] = "NYI"
3804
0
    };
3805
3806
0
  enum err_type ret;
3807
0
  aarch64_inst inst;
3808
3809
0
  info->insn_info_valid = 1;
3810
0
  info->branch_delay_insns = 0;
3811
0
  info->data_size = 0;
3812
0
  info->target = 0;
3813
0
  info->target2 = 0;
3814
3815
0
  if (info->flags & INSN_HAS_RELOC)
3816
    /* If the instruction has a reloc associated with it, then
3817
       the offset field in the instruction will actually be the
3818
       addend for the reloc.  (If we are using REL type relocs).
3819
       In such cases, we can ignore the pc when computing
3820
       addresses, since the addend is not currently pc-relative.  */
3821
0
    pc = 0;
3822
3823
0
  ret = aarch64_decode_insn (word, &inst, no_aliases, errors);
3824
3825
0
  if (((word >> 21) & 0x3ff) == 1)
3826
0
    {
3827
      /* RESERVED for ALES.  */
3828
0
      assert (ret != ERR_OK);
3829
0
      ret = ERR_NYI;
3830
0
    }
3831
3832
0
  switch (ret)
3833
0
    {
3834
0
    case ERR_UND:
3835
0
    case ERR_UNP:
3836
0
    case ERR_NYI:
3837
      /* Handle undefined instructions.  */
3838
0
      info->insn_type = dis_noninsn;
3839
0
      (*info->fprintf_styled_func) (info->stream,
3840
0
            dis_style_assembler_directive,
3841
0
            ".inst\t");
3842
0
      (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
3843
0
            "0x%08x", word);
3844
0
      (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
3845
0
            " ; %s", err_msg[ret]);
3846
0
      break;
3847
0
    case ERR_OK:
3848
0
      user_friendly_fixup (&inst);
3849
0
      print_aarch64_insn (pc, &inst, word, info, errors);
3850
0
      break;
3851
0
    default:
3852
0
      abort ();
3853
0
    }
3854
0
}
3855
3856
/* Disallow mapping symbols ($x, $d etc) from
3857
   being displayed in symbol relative addresses.  */
3858
3859
bool
3860
aarch64_symbol_is_valid (asymbol * sym,
3861
       struct disassemble_info * info ATTRIBUTE_UNUSED)
3862
0
{
3863
0
  const char * name;
3864
3865
0
  if (sym == NULL)
3866
0
    return false;
3867
3868
0
  name = bfd_asymbol_name (sym);
3869
3870
0
  return name
3871
0
    && (name[0] != '$'
3872
0
  || (name[1] != 'x' && name[1] != 'd')
3873
0
  || (name[2] != '\0' && name[2] != '.'));
3874
0
}
3875
3876
/* Print data bytes on INFO->STREAM.  */
3877
3878
static void
3879
print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3880
     uint32_t word,
3881
     struct disassemble_info *info,
3882
     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
3883
0
{
3884
0
  switch (info->bytes_per_chunk)
3885
0
    {
3886
0
    case 1:
3887
0
      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
3888
0
         ".byte\t");
3889
0
      info->fprintf_styled_func (info->stream, dis_style_immediate,
3890
0
         "0x%02x", word);
3891
0
      break;
3892
0
    case 2:
3893
0
      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
3894
0
         ".short\t");
3895
0
      info->fprintf_styled_func (info->stream, dis_style_immediate,
3896
0
         "0x%04x", word);
3897
0
      break;
3898
0
    case 4:
3899
0
      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
3900
0
         ".word\t");
3901
0
      info->fprintf_styled_func (info->stream, dis_style_immediate,
3902
0
         "0x%08x", word);
3903
0
      break;
3904
0
    default:
3905
0
      abort ();
3906
0
    }
3907
0
}
3908
3909
/* Try to infer the code or data type from a symbol.
3910
   Returns nonzero if *MAP_TYPE was set.  */
3911
3912
static int
3913
get_sym_code_type (struct disassemble_info *info, int n,
3914
       enum map_type *map_type)
3915
0
{
3916
0
  asymbol * as;
3917
0
  elf_symbol_type *es;
3918
0
  unsigned int type;
3919
0
  const char *name;
3920
3921
  /* If the symbol is in a different section, ignore it.  */
3922
0
  if (info->section != NULL && info->section != info->symtab[n]->section)
3923
0
    return false;
3924
3925
0
  if (n >= info->symtab_size)
3926
0
    return false;
3927
3928
0
  as = info->symtab[n];
3929
0
  if (bfd_asymbol_flavour (as) != bfd_target_elf_flavour)
3930
0
    return false;
3931
0
  es = (elf_symbol_type *) as;
3932
3933
0
  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3934
3935
  /* If the symbol has function type then use that.  */
3936
0
  if (type == STT_FUNC)
3937
0
    {
3938
0
      *map_type = MAP_INSN;
3939
0
      return true;
3940
0
    }
3941
3942
  /* Check for mapping symbols.  */
3943
0
  name = bfd_asymbol_name(info->symtab[n]);
3944
0
  if (name[0] == '$'
3945
0
      && (name[1] == 'x' || name[1] == 'd')
3946
0
      && (name[2] == '\0' || name[2] == '.'))
3947
0
    {
3948
0
      *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
3949
0
      return true;
3950
0
    }
3951
3952
0
  return false;
3953
0
}
3954
3955
/* Set the feature bits in arch_variant in order to get the correct disassembly
3956
   for the chosen architecture variant.
3957
3958
   Currently we only restrict disassembly for Armv8-R and otherwise enable all
3959
   non-R-profile features.  */
3960
static void
3961
select_aarch64_variant (unsigned mach)
3962
0
{
3963
0
  switch (mach)
3964
0
    {
3965
0
    case bfd_mach_aarch64_8R:
3966
0
      arch_variant = AARCH64_ARCH_V8R;
3967
0
      break;
3968
0
    default:
3969
0
      arch_variant = AARCH64_ANY & ~(AARCH64_FEATURE_V8R);
3970
0
    }
3971
0
}
3972
3973
/* Entry-point of the AArch64 disassembler.  */
3974
3975
int
3976
print_insn_aarch64 (bfd_vma pc,
3977
        struct disassemble_info *info)
3978
0
{
3979
0
  bfd_byte  buffer[INSNLEN];
3980
0
  int   status;
3981
0
  void    (*printer) (bfd_vma, uint32_t, struct disassemble_info *,
3982
0
          aarch64_operand_error *);
3983
0
  bool   found = false;
3984
0
  unsigned int  size = 4;
3985
0
  unsigned long data;
3986
0
  aarch64_operand_error errors;
3987
0
  static bool set_features;
3988
3989
0
  if (info->disassembler_options)
3990
0
    {
3991
0
      set_default_aarch64_dis_options (info);
3992
3993
0
      parse_aarch64_dis_options (info->disassembler_options);
3994
3995
      /* To avoid repeated parsing of these options, we remove them here.  */
3996
0
      info->disassembler_options = NULL;
3997
0
    }
3998
3999
0
  if (!set_features)
4000
0
    {
4001
0
      select_aarch64_variant (info->mach);
4002
0
      set_features = true;
4003
0
    }
4004
4005
  /* Aarch64 instructions are always little-endian */
4006
0
  info->endian_code = BFD_ENDIAN_LITTLE;
4007
4008
  /* Default to DATA.  A text section is required by the ABI to contain an
4009
     INSN mapping symbol at the start.  A data section has no such
4010
     requirement, hence if no mapping symbol is found the section must
4011
     contain only data.  This however isn't very useful if the user has
4012
     fully stripped the binaries.  If this is the case use the section
4013
     attributes to determine the default.  If we have no section default to
4014
     INSN as well, as we may be disassembling some raw bytes on a baremetal
4015
     HEX file or similar.  */
4016
0
  enum map_type type = MAP_DATA;
4017
0
  if ((info->section && info->section->flags & SEC_CODE) || !info->section)
4018
0
    type = MAP_INSN;
4019
4020
  /* First check the full symtab for a mapping symbol, even if there
4021
     are no usable non-mapping symbols for this address.  */
4022
0
  if (info->symtab_size != 0
4023
0
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4024
0
    {
4025
0
      int last_sym = -1;
4026
0
      bfd_vma addr, section_vma = 0;
4027
0
      bool can_use_search_opt_p;
4028
0
      int n;
4029
4030
0
      if (pc <= last_mapping_addr)
4031
0
  last_mapping_sym = -1;
4032
4033
      /* Start scanning at the start of the function, or wherever
4034
   we finished last time.  */
4035
0
      n = info->symtab_pos + 1;
4036
4037
      /* If the last stop offset is different from the current one it means we
4038
   are disassembling a different glob of bytes.  As such the optimization
4039
   would not be safe and we should start over.  */
4040
0
      can_use_search_opt_p = last_mapping_sym >= 0
4041
0
           && info->stop_offset == last_stop_offset;
4042
4043
0
      if (n >= last_mapping_sym && can_use_search_opt_p)
4044
0
  n = last_mapping_sym;
4045
4046
      /* Look down while we haven't passed the location being disassembled.
4047
   The reason for this is that there's no defined order between a symbol
4048
   and an mapping symbol that may be at the same address.  We may have to
4049
   look at least one position ahead.  */
4050
0
      for (; n < info->symtab_size; n++)
4051
0
  {
4052
0
    addr = bfd_asymbol_value (info->symtab[n]);
4053
0
    if (addr > pc)
4054
0
      break;
4055
0
    if (get_sym_code_type (info, n, &type))
4056
0
      {
4057
0
        last_sym = n;
4058
0
        found = true;
4059
0
      }
4060
0
  }
4061
4062
0
      if (!found)
4063
0
  {
4064
0
    n = info->symtab_pos;
4065
0
    if (n >= last_mapping_sym && can_use_search_opt_p)
4066
0
      n = last_mapping_sym;
4067
4068
    /* No mapping symbol found at this address.  Look backwards
4069
       for a preceeding one, but don't go pass the section start
4070
       otherwise a data section with no mapping symbol can pick up
4071
       a text mapping symbol of a preceeding section.  The documentation
4072
       says section can be NULL, in which case we will seek up all the
4073
       way to the top.  */
4074
0
    if (info->section)
4075
0
      section_vma = info->section->vma;
4076
4077
0
    for (; n >= 0; n--)
4078
0
      {
4079
0
        addr = bfd_asymbol_value (info->symtab[n]);
4080
0
        if (addr < section_vma)
4081
0
    break;
4082
4083
0
        if (get_sym_code_type (info, n, &type))
4084
0
    {
4085
0
      last_sym = n;
4086
0
      found = true;
4087
0
      break;
4088
0
    }
4089
0
      }
4090
0
  }
4091
4092
0
      last_mapping_sym = last_sym;
4093
0
      last_type = type;
4094
0
      last_stop_offset = info->stop_offset;
4095
4096
      /* Look a little bit ahead to see if we should print out
4097
   less than four bytes of data.  If there's a symbol,
4098
   mapping or otherwise, after two bytes then don't
4099
   print more.  */
4100
0
      if (last_type == MAP_DATA)
4101
0
  {
4102
0
    size = 4 - (pc & 3);
4103
0
    for (n = last_sym + 1; n < info->symtab_size; n++)
4104
0
      {
4105
0
        addr = bfd_asymbol_value (info->symtab[n]);
4106
0
        if (addr > pc)
4107
0
    {
4108
0
      if (addr - pc < size)
4109
0
        size = addr - pc;
4110
0
      break;
4111
0
    }
4112
0
      }
4113
    /* If the next symbol is after three bytes, we need to
4114
       print only part of the data, so that we can use either
4115
       .byte or .short.  */
4116
0
    if (size == 3)
4117
0
      size = (pc & 1) ? 1 : 2;
4118
0
  }
4119
0
    }
4120
0
  else
4121
0
    last_type = type;
4122
4123
  /* PR 10263: Disassemble data if requested to do so by the user.  */
4124
0
  if (last_type == MAP_DATA && ((info->flags & DISASSEMBLE_DATA) == 0))
4125
0
    {
4126
      /* size was set above.  */
4127
0
      info->bytes_per_chunk = size;
4128
0
      info->display_endian = info->endian;
4129
0
      printer = print_insn_data;
4130
0
    }
4131
0
  else
4132
0
    {
4133
0
      info->bytes_per_chunk = size = INSNLEN;
4134
0
      info->display_endian = info->endian_code;
4135
0
      printer = print_insn_aarch64_word;
4136
0
    }
4137
4138
0
  status = (*info->read_memory_func) (pc, buffer, size, info);
4139
0
  if (status != 0)
4140
0
    {
4141
0
      (*info->memory_error_func) (status, pc, info);
4142
0
      return -1;
4143
0
    }
4144
4145
0
  data = bfd_get_bits (buffer, size * 8,
4146
0
           info->display_endian == BFD_ENDIAN_BIG);
4147
4148
0
  (*printer) (pc, data, info, &errors);
4149
4150
0
  return size;
4151
0
}
4152

4153
void
4154
print_aarch64_disassembler_options (FILE *stream)
4155
0
{
4156
0
  fprintf (stream, _("\n\
4157
0
The following AARCH64 specific disassembler options are supported for use\n\
4158
0
with the -M switch (multiple options should be separated by commas):\n"));
4159
4160
0
  fprintf (stream, _("\n\
4161
0
  no-aliases         Don't print instruction aliases.\n"));
4162
4163
0
  fprintf (stream, _("\n\
4164
0
  aliases            Do print instruction aliases.\n"));
4165
4166
0
  fprintf (stream, _("\n\
4167
0
  no-notes         Don't print instruction notes.\n"));
4168
4169
0
  fprintf (stream, _("\n\
4170
0
  notes            Do print instruction notes.\n"));
4171
4172
#ifdef DEBUG_AARCH64
4173
  fprintf (stream, _("\n\
4174
  debug_dump         Temp switch for debug trace.\n"));
4175
#endif /* DEBUG_AARCH64 */
4176
4177
0
  fprintf (stream, _("\n"));
4178
0
}