Coverage Report

Created: 2026-10-02 09:53

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