Coverage Report

Created: 2026-09-14 08:07

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
16.7M
#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
248M
#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.77M
{
164
1.77M
  uint32_t num;
165
1.77M
  va_list va;
166
167
1.77M
  va_start (va, mask);
168
1.77M
  num = va_arg (va, uint32_t);
169
1.77M
  assert (num <= 5);
170
1.77M
  aarch64_insn value = 0x0;
171
5.92M
  while (num--)
172
4.14M
    {
173
4.14M
      aarch64_field field = va_arg (va, aarch64_field);
174
4.14M
      value <<= field.width;
175
4.14M
      value |= extract_field (field, code, mask);
176
4.14M
    }
177
1.77M
  va_end (va);
178
1.77M
  return value;
179
1.77M
}
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
14.8M
{
188
14.8M
  aarch64_insn value;
189
14.8M
  unsigned int i;
190
191
14.8M
  value = 0;
192
14.8M
  for (i = start;
193
30.8M
       i < ARRAY_SIZE (self->fields) && self->fields[i].width != 0; ++i)
194
15.9M
    {
195
15.9M
      aarch64_field field = self->fields[i];
196
15.9M
      value <<= field.width;
197
15.9M
      value |= extract_field (field, code, 0);
198
15.9M
    }
199
14.8M
  return value;
200
14.8M
}
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
14.8M
{
208
14.8M
  return extract_all_fields_after (self, 0, code);
209
14.8M
}
210
211
/* Sign-extend bit I of VALUE.  */
212
static inline uint64_t
213
sign_extend (aarch64_insn value, unsigned i)
214
2.28M
{
215
2.28M
  uint64_t ret, sign;
216
217
2.28M
  assert (i < 32);
218
2.28M
  ret = value;
219
2.28M
  sign = (uint64_t) 1 << i;
220
2.28M
  return ((ret & (sign + sign - 1)) ^ sign) - sign;
221
2.28M
}
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.66M
{
230
2.66M
  enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
231
2.66M
  if (value <= 0x1
232
2.66M
      && aarch64_get_qualifier_standard_value (qualifier) == value)
233
2.66M
    return qualifier;
234
0
  return AARCH64_OPND_QLF_ERR;
235
2.66M
}
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
227k
{
243
227k
  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
227k
  if (qualifier >= AARCH64_OPND_QLF_V_2H)
248
157k
    qualifier += 1;
249
250
227k
  if (value <= 0x8
251
227k
      && aarch64_get_qualifier_standard_value (qualifier) == value)
252
227k
    return qualifier;
253
0
  return AARCH64_OPND_QLF_ERR;
254
227k
}
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
242k
{
260
242k
  enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
261
262
242k
  if (value <= 0x4
263
237k
      && aarch64_get_qualifier_standard_value (qualifier) == value)
264
237k
    return qualifier;
265
4.56k
  return AARCH64_OPND_QLF_ERR;
266
242k
}
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.17M
{
276
1.17M
  aarch64_opnd_qualifier_seq_t qualifiers;
277
  /* Should not be called if the qualifier is known.  */
278
1.17M
  if (inst->operands[i].qualifier == AARCH64_OPND_QLF_UNKNOWN)
279
1.17M
    {
280
1.17M
      int invalid_count;
281
1.17M
      if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
282
1.17M
           i, qualifiers, &invalid_count))
283
1.14M
  return qualifiers[i];
284
27.5k
      else
285
27.5k
  return AARCH64_OPND_QLF_UNKNOWN;
286
1.17M
    }
287
0
  else
288
0
    return AARCH64_OPND_QLF_ERR;
289
1.17M
}
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.06k
{
300
2.06k
  return true;
301
2.06k
}
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.6M
{
309
10.6M
  info->reg.regno = extract_all_fields (self, code);
310
10.6M
  return true;
311
10.6M
}
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
12.3k
{
319
12.3k
  assert (info->idx == 1
320
12.3k
    || info->idx == 2
321
12.3k
    || info->idx == 3
322
12.3k
    || info->idx == 5);
323
324
12.3k
  unsigned prev_regno = inst->operands[info->idx - 1].reg.regno;
325
12.3k
  info->reg.regno = (prev_regno == 0x1f) ? 0x1f
326
12.3k
           : prev_regno + 1;
327
12.3k
  return true;
328
12.3k
}
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
1.04k
{
337
1.04k
  info->reg.regno = extract_field (self->fields[0], code, 0);
338
1.04k
  assert (info->idx == 1
339
1.04k
    && (aarch64_get_operand_class (inst->operands[0].type)
340
1.04k
        == 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
1.04k
  info->present
346
1.04k
    = (info->reg.regno != 31
347
331
       || aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op));
348
1.04k
  return true;
349
1.04k
}
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
130k
{
358
  /* regno */
359
130k
  info->reglane.regno = extract_field (self->fields[0], code,
360
130k
               inst->opcode->mask);
361
362
  /* Index and/or type.  */
363
130k
  if (inst->opcode->iclass == asisdone
364
129k
    || inst->opcode->iclass == asimdins)
365
15.4k
    {
366
15.4k
      if (info->type == AARCH64_OPND_En
367
10.9k
    && inst->opcode->operands[0] == AARCH64_OPND_Ed)
368
3.81k
  {
369
3.81k
    unsigned shift;
370
    /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>].  */
371
3.81k
    assert (info->idx == 1);  /* Vn */
372
3.81k
    aarch64_insn value = extract_field (FLD_imm4_11, code, 0);
373
    /* Depend on AARCH64_OPND_Ed to determine the qualifier.  */
374
3.81k
    info->qualifier = get_expected_qualifier (inst, info->idx);
375
3.81k
    if (info->qualifier == AARCH64_OPND_QLF_ERR)
376
0
      return 0;
377
3.81k
    shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
378
3.81k
    info->reglane.index = value >> shift;
379
3.81k
  }
380
11.6k
      else
381
11.6k
  {
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
11.6k
    int pos = -1;
390
11.6k
    aarch64_insn value = extract_field (FLD_imm5, code, 0);
391
27.4k
    while (++pos <= 3 && (value & 0x1) == 0)
392
15.8k
      value >>= 1;
393
11.6k
    if (pos > 3)
394
1.35k
      return false;
395
10.3k
    info->qualifier = get_sreg_qualifier_from_value (pos);
396
10.3k
    if (info->qualifier == AARCH64_OPND_QLF_ERR)
397
0
      return 0;
398
10.3k
    info->reglane.index = (unsigned) (value >> 1);
399
10.3k
  }
400
15.4k
    }
401
114k
  else if (inst->opcode->iclass == dotproduct)
402
31.8k
    {
403
      /* Need information in other operand(s) to help decoding.  */
404
31.8k
      info->qualifier = get_expected_qualifier (inst, info->idx);
405
31.8k
      if (info->qualifier == AARCH64_OPND_QLF_ERR)
406
0
  return 0;
407
31.8k
      switch (info->qualifier)
408
31.8k
  {
409
24.4k
  case AARCH64_OPND_QLF_S_4B:
410
25.6k
  case AARCH64_OPND_QLF_S_2H:
411
    /* L:H */
412
25.6k
    info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
413
25.6k
    info->reglane.regno &= 0x1f;
414
25.6k
    break;
415
2.84k
  case AARCH64_OPND_QLF_S_2B:
416
    /* h:l:m */
417
2.84k
    info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
418
2.84k
            FLD_M);
419
2.84k
    info->reglane.regno &= 0xf;
420
2.84k
    break;
421
3.33k
  default:
422
3.33k
    return false;
423
31.8k
  }
424
31.8k
    }
425
82.8k
  else if (inst->opcode->iclass == cryptosm3)
426
868
    {
427
      /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>].  */
428
868
      info->reglane.index = extract_field (FLD_SM3_imm2, code, 0);
429
868
    }
430
82.0k
  else
431
82.0k
    {
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
82.0k
      info->qualifier = get_expected_qualifier (inst, info->idx);
437
82.0k
      if (info->qualifier == AARCH64_OPND_QLF_ERR)
438
0
  return 0;
439
82.0k
      switch (info->qualifier)
440
82.0k
  {
441
3.80k
  case AARCH64_OPND_QLF_S_B:
442
    /* H:imm3 */
443
3.80k
    info->reglane.index = extract_fields (code, 0, 2, FLD_H,
444
3.80k
            FLD_imm3_19);
445
3.80k
    info->reglane.regno &= 0x7;
446
3.80k
    break;
447
448
43.3k
  case AARCH64_OPND_QLF_S_H:
449
43.3k
  case AARCH64_OPND_QLF_S_2B:
450
43.3k
    if (info->type == AARCH64_OPND_Em16)
451
36.6k
      {
452
        /* h:l:m */
453
36.6k
        info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
454
36.6k
                FLD_M);
455
36.6k
        info->reglane.regno &= 0xf;
456
36.6k
      }
457
6.69k
    else
458
6.69k
      {
459
        /* h:l */
460
6.69k
        info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
461
6.69k
      }
462
43.3k
    break;
463
9.34k
  case AARCH64_OPND_QLF_S_S:
464
9.34k
  case AARCH64_OPND_QLF_S_4B:
465
    /* h:l */
466
9.34k
    info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
467
9.34k
    break;
468
1.33k
  case AARCH64_OPND_QLF_S_D:
469
    /* H */
470
1.33k
    info->reglane.index = extract_field (FLD_H, code, 0);
471
1.33k
    break;
472
24.2k
  default:
473
24.2k
    return false;
474
82.0k
  }
475
476
57.8k
      if (inst->opcode->op == OP_FCMLA_ELEM
477
7.79k
    && info->qualifier != AARCH64_OPND_QLF_S_H)
478
1.09k
  {
479
    /* Complex operand takes two elements.  */
480
1.09k
    if (info->reglane.index & 1)
481
467
      return false;
482
630
    info->reglane.index /= 2;
483
630
  }
484
57.8k
    }
485
486
100k
  return true;
487
130k
}
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
16.7k
{
495
  /* R */
496
16.7k
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
497
  /* len */
498
16.7k
  info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
499
16.7k
  info->reglist.stride = 1;
500
16.7k
  return true;
501
16.7k
}
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
60.9k
{
510
60.9k
  aarch64_insn value;
511
  /* Number of elements in each structure to be loaded/stored.  */
512
60.9k
  unsigned expected_num = get_opcode_dependent_value (inst->opcode);
513
514
60.9k
  static const struct
515
60.9k
    {
516
60.9k
      unsigned num_regs:8;
517
60.9k
      unsigned num_elements:8;
518
60.9k
      bool is_reserved:1;
519
60.9k
    } data [] =
520
60.9k
  {   {4, 4, false},
521
60.9k
      {4, 4, true},
522
60.9k
      {4, 1, false},
523
60.9k
      {4, 2, false},
524
60.9k
      {3, 3, false},
525
60.9k
      {3, 3, true},
526
60.9k
      {3, 1, false},
527
60.9k
      {1, 1, false},
528
60.9k
      {2, 2, false},
529
60.9k
      {2, 2, true},
530
60.9k
      {2, 1, false},
531
60.9k
  };
532
533
  /* Rt */
534
60.9k
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
535
  /* opcode */
536
60.9k
  value = extract_field (FLD_opcode, code, 0);
537
  /* PR 21595: Check for a bogus value.  */
538
60.9k
  if (value >= ARRAY_SIZE (data))
539
21.9k
    return false;
540
39.0k
  if (expected_num != data[value].num_elements || data[value].is_reserved)
541
23.6k
    return false;
542
15.4k
  info->reglist.num_regs = data[value].num_regs;
543
15.4k
  info->reglist.stride = 1;
544
545
15.4k
  return true;
546
39.0k
}
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
1.97k
{
556
1.97k
  aarch64_insn value;
557
558
  /* Rt */
559
1.97k
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
560
  /* S */
561
1.97k
  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
1.97k
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
566
1.97k
  assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
567
568
  /* Except when it is LD1R.  */
569
1.97k
  if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
570
0
    info->reglist.num_regs = 2;
571
572
1.97k
  info->reglist.stride = 1;
573
1.97k
  return true;
574
1.97k
}
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.35k
{
585
4.35k
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
586
4.35k
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
587
4.35k
  info->reglist.stride = 1;
588
4.35k
  return true;
589
4.35k
}
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
32.3k
{
599
32.3k
  aarch64_field field = AARCH64_FIELD_NIL;
600
32.3k
  aarch64_insn QSsize;    /* fields Q:S:size.  */
601
32.3k
  aarch64_insn opcodeh2;  /* opcode<2:1> */
602
603
  /* Rt */
604
32.3k
  info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
605
606
  /* Decode the index, opcode<2:1> and size.  */
607
32.3k
  gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
608
32.3k
  opcodeh2 = extract_field (field, code, 0);
609
32.3k
  QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
610
32.3k
  switch (opcodeh2)
611
32.3k
    {
612
15.2k
    case 0x0:
613
15.2k
      info->qualifier = AARCH64_OPND_QLF_S_B;
614
      /* Index encoded in "Q:S:size".  */
615
15.2k
      info->reglist.index = QSsize;
616
15.2k
      break;
617
5.83k
    case 0x1:
618
5.83k
      if (QSsize & 0x1)
619
  /* UND.  */
620
2.59k
  return false;
621
3.24k
      info->qualifier = AARCH64_OPND_QLF_S_H;
622
      /* Index encoded in "Q:S:size<1>".  */
623
3.24k
      info->reglist.index = QSsize >> 1;
624
3.24k
      break;
625
4.78k
    case 0x2:
626
4.78k
      if ((QSsize >> 1) & 0x1)
627
  /* UND.  */
628
2.33k
  return false;
629
2.44k
      if ((QSsize & 0x1) == 0)
630
1.09k
  {
631
1.09k
    info->qualifier = AARCH64_OPND_QLF_S_S;
632
    /* Index encoded in "Q:S".  */
633
1.09k
    info->reglist.index = QSsize >> 2;
634
1.09k
  }
635
1.35k
      else
636
1.35k
  {
637
1.35k
    if (extract_field (FLD_S, code, 0))
638
      /* UND */
639
547
      return false;
640
803
    info->qualifier = AARCH64_OPND_QLF_S_D;
641
    /* Index encoded in "Q".  */
642
803
    info->reglist.index = QSsize >> 3;
643
803
  }
644
1.90k
      break;
645
6.41k
    default:
646
6.41k
      return false;
647
32.3k
    }
648
649
20.4k
  info->reglist.has_index = 1;
650
20.4k
  info->reglist.num_regs = 0;
651
20.4k
  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.4k
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
655
20.4k
  assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
656
657
20.4k
  return true;
658
20.4k
}
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.5k
{
670
39.5k
  int pos;
671
39.5k
  aarch64_insn Q, imm, immh;
672
39.5k
  enum aarch64_insn_class iclass = inst->opcode->iclass;
673
674
39.5k
  immh = extract_field (FLD_immh, code, 0);
675
39.5k
  if (immh == 0)
676
5.20k
    return false;
677
34.3k
  imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
678
34.3k
  pos = 4;
679
  /* Get highest set bit in immh.  */
680
56.0k
  while (--pos >= 0 && (immh & 0x8) == 0)
681
21.6k
    immh <<= 1;
682
683
34.3k
  assert ((iclass == asimdshf || iclass == asisdshf)
684
34.3k
    && (info->type == AARCH64_OPND_IMM_VLSR
685
34.3k
        || info->type == AARCH64_OPND_IMM_VLSL));
686
687
34.3k
  if (iclass == asimdshf)
688
23.4k
    {
689
23.4k
      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.4k
      info->qualifier =
701
23.4k
  get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
702
23.4k
      if (info->qualifier == AARCH64_OPND_QLF_ERR)
703
0
  return false;
704
23.4k
    }
705
10.9k
  else
706
10.9k
    {
707
10.9k
      info->qualifier = get_sreg_qualifier_from_value (pos);
708
10.9k
      if (info->qualifier == AARCH64_OPND_QLF_ERR)
709
0
  return 0;
710
10.9k
    }
711
712
34.3k
  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.2k
    info->imm.value = (16 << pos) - imm;
720
10.1k
  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.1k
    info->imm.value = imm - (8 << pos);
729
730
34.3k
  return true;
731
34.3k
}
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
251
{
740
251
  int64_t imm;
741
251
  aarch64_insn val;
742
251
  val = extract_field (FLD_size, code, 0);
743
251
  switch (val)
744
251
    {
745
84
    case 0: imm = 8; break;
746
113
    case 1: imm = 16; break;
747
54
    case 2: imm = 32; break;
748
0
    default: return false;
749
251
    }
750
251
  info->imm.value = imm;
751
251
  return true;
752
251
}
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.04M
{
762
4.04M
  uint64_t imm;
763
764
4.04M
  imm = extract_all_fields (self, code);
765
766
4.04M
  if (operand_need_sign_extension (self))
767
1.52M
    imm = sign_extend (imm, get_operand_fields_width (self) - 1);
768
769
4.04M
  if (operand_need_shift_by_two (self))
770
1.00M
    imm <<= 2;
771
3.03M
  else if (operand_need_shift_by_three (self))
772
120
    imm <<= 3;
773
3.03M
  else if (operand_need_shift_by_four (self))
774
4.57k
    imm <<= 4;
775
776
4.04M
  if (info->type == AARCH64_OPND_ADDR_ADRP)
777
157k
    imm <<= 12;
778
779
4.04M
  if (inst->operands[0].type == AARCH64_OPND_PSTATEFIELD
780
261
      && inst->operands[0].sysreg.flags & F_IMM_IN_CRM)
781
0
    imm &= PSTATE_DECODE_CRM_IMM (inst->operands[0].sysreg.flags);
782
783
4.04M
  info->imm.value = imm;
784
4.04M
  return true;
785
4.04M
}
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.47k
{
809
6.47k
  uint64_t imm;
810
6.47k
  enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
811
6.47k
  aarch64_field field = AARCH64_FIELD_NIL;
812
813
6.47k
  assert (info->idx == 1);
814
815
6.47k
  if (info->type == AARCH64_OPND_SIMD_FPIMM)
816
2.35k
    info->imm.is_fp = 1;
817
818
  /* a:b:c:d:e:f:g:h */
819
6.47k
  imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
820
6.47k
  if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
821
674
    {
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
674
      int i;
828
674
      unsigned abcdefgh = imm;
829
6.06k
      for (imm = 0ull, i = 0; i < 8; i++)
830
5.39k
  if (((abcdefgh >> i) & 0x1) != 0)
831
2.86k
    imm |= 0xffull << (8 * i);
832
674
    }
833
6.47k
  info->imm.value = imm;
834
835
  /* cmode */
836
6.47k
  info->qualifier = get_expected_qualifier (inst, info->idx);
837
6.47k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
838
0
    return 0;
839
6.47k
  switch (info->qualifier)
840
6.47k
    {
841
3.02k
    case AARCH64_OPND_QLF_NIL:
842
      /* no shift */
843
3.02k
      info->shifter.kind = AARCH64_MOD_NONE;
844
3.02k
      return 1;
845
3.05k
    case AARCH64_OPND_QLF_LSL:
846
      /* shift zeros */
847
3.05k
      info->shifter.kind = AARCH64_MOD_LSL;
848
3.05k
      switch (aarch64_get_qualifier_esize (opnd0_qualifier))
849
3.05k
  {
850
2.51k
  case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
851
406
  case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
852
133
  case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
853
0
  default: return false;
854
3.05k
  }
855
      /* 00: 0; 01: 8; 10:16; 11:24.  */
856
3.05k
      info->shifter.amount = extract_field (field, code, 0) << 3;
857
3.05k
      break;
858
391
    case AARCH64_OPND_QLF_MSL:
859
      /* shift ones */
860
391
      info->shifter.kind = AARCH64_MOD_MSL;
861
391
      gen_sub_field (FLD_cmode, 0, 1, &field);    /* per word */
862
391
      info->shifter.amount = extract_field (field, code, 0) ? 16 : 8;
863
391
      break;
864
0
    default:
865
0
      return false;
866
6.47k
    }
867
868
3.44k
  return true;
869
6.47k
}
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.08k
{
878
2.08k
  info->imm.value = extract_all_fields (self, code);
879
2.08k
  info->imm.is_fp = 1;
880
2.08k
  return true;
881
2.08k
}
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.98k
{
890
1.98k
  uint64_t rot = extract_field (self->fields[0], code, 0);
891
1.98k
  assert (rot < 2U);
892
1.98k
  info->imm.value = rot * 180 + 90;
893
1.98k
  return true;
894
1.98k
}
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
28.2k
{
903
28.2k
  uint64_t rot = extract_field (self->fields[0], code, 0);
904
28.2k
  assert (rot < 4U);
905
28.2k
  info->imm.value = rot * 90;
906
28.2k
  return true;
907
28.2k
}
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.79k
{
916
2.79k
  info->imm.value = 64- extract_field (FLD_scale, code, 0);
917
2.79k
  return true;
918
2.79k
}
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
590k
{
928
590k
  aarch64_insn value;
929
930
590k
  info->shifter.kind = AARCH64_MOD_LSL;
931
  /* shift */
932
590k
  value = extract_field (FLD_shift, code, 0);
933
590k
  if (value >= 2)
934
151k
    return false;
935
438k
  info->shifter.amount = value ? 12 : 0;
936
  /* imm12 (unsigned) */
937
438k
  info->imm.value = extract_field (FLD_imm12, code, 0);
938
939
438k
  return true;
940
590k
}
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
436k
{
948
436k
  uint64_t imm, mask;
949
436k
  uint32_t N, R, S;
950
436k
  unsigned simd_size;
951
952
  /* value is N:immr:imms.  */
953
436k
  S = value & 0x3f;
954
436k
  R = (value >> 6) & 0x3f;
955
436k
  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
436k
  if (N != 0)
960
126k
    {
961
126k
      simd_size = 64;
962
126k
      mask = 0xffffffffffffffffull;
963
126k
    }
964
309k
  else
965
309k
    {
966
309k
      switch (S)
967
309k
  {
968
240k
  case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32;           break;
969
32.4k
  case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
970
17.8k
  case 0x30 ... 0x37: /* 110xxx */ simd_size =  8; S &= 0x7; break;
971
9.55k
  case 0x38 ... 0x3b: /* 1110xx */ simd_size =  4; S &= 0x3; break;
972
3.36k
  case 0x3c ... 0x3d: /* 11110x */ simd_size =  2; S &= 0x1; break;
973
5.75k
  default: return false;
974
309k
  }
975
304k
      mask = (1ull << simd_size) - 1;
976
      /* Top bits are IGNORED.  */
977
304k
      R &= simd_size - 1;
978
304k
    }
979
980
430k
  if (simd_size > esize * 8)
981
76.7k
    return false;
982
983
  /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
984
353k
  if (S == simd_size - 1)
985
5.79k
    return false;
986
  /* S+1 consecutive bits to 1.  */
987
  /* NOTE: S can't be 63 due to detection above.  */
988
347k
  imm = (1ull << (S + 1)) - 1;
989
  /* Rotate to the left by simd_size - R.  */
990
347k
  if (R != 0)
991
271k
    imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
992
  /* Replicate the value according to SIMD size.  */
993
347k
  switch (simd_size)
994
347k
    {
995
2.32k
    case  2: imm = (imm <<  2) | imm;
996
      /* Fall through.  */
997
10.2k
    case  4: imm = (imm <<  4) | imm;
998
      /* Fall through.  */
999
27.1k
    case  8: imm = (imm <<  8) | imm;
1000
      /* Fall through.  */
1001
59.1k
    case 16: imm = (imm << 16) | imm;
1002
      /* Fall through.  */
1003
299k
    case 32: imm = (imm << 32) | imm;
1004
      /* Fall through.  */
1005
347k
    case 64: break;
1006
0
    default: return 0;
1007
347k
    }
1008
1009
347k
  *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
1010
1011
347k
  return true;
1012
347k
}
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
436k
{
1021
436k
  uint32_t esize;
1022
436k
  aarch64_insn value;
1023
1024
436k
  value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
1025
436k
        self->fields[2]);
1026
436k
  esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1027
436k
  return decode_limm (esize, value, &info->imm.value);
1028
436k
}
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
655k
{
1051
655k
  aarch64_insn value;
1052
1053
  /* Rt */
1054
655k
  info->reg.regno = extract_field (FLD_Rt, code, 0);
1055
1056
  /* size */
1057
655k
  value = extract_field (FLD_ldst_size, code, 0);
1058
655k
  if (inst->opcode->iclass == ldstpair_indexed
1059
535k
      || inst->opcode->iclass == ldstnapair_offs
1060
444k
      || inst->opcode->iclass == ldstpair_off
1061
360k
      || inst->opcode->iclass == loadlit)
1062
409k
    {
1063
409k
      switch (value)
1064
409k
  {
1065
112k
  case 0: info->qualifier = AARCH64_OPND_QLF_S_S; break;
1066
124k
  case 1: info->qualifier = AARCH64_OPND_QLF_S_D; break;
1067
80.1k
  case 2: info->qualifier = AARCH64_OPND_QLF_S_Q; break;
1068
92.3k
  default: return false;
1069
409k
  }
1070
409k
    }
1071
246k
  else
1072
246k
    {
1073
      /* opc1:size */
1074
246k
      value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
1075
246k
      if (value > 0x4)
1076
79.0k
  return false;
1077
167k
      info->qualifier = get_sreg_qualifier_from_value (value);
1078
167k
      if (info->qualifier == AARCH64_OPND_QLF_ERR)
1079
0
  return false;
1080
167k
    }
1081
1082
484k
  return true;
1083
655k
}
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
281k
{
1093
  /* Rn */
1094
281k
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1095
281k
  return true;
1096
281k
}
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
16.9k
{
1108
16.9k
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1109
16.9k
  if (!extract_field (FLD_opc2, code, 0))
1110
1.73k
    {
1111
1.73k
      info->addr.writeback = 1;
1112
1113
1.73k
      enum aarch64_opnd type;
1114
1.73k
      for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
1115
1.73k
  {
1116
1.73k
    type = info[i].type;
1117
1.73k
    if (aarch64_operands[type].op_class == AARCH64_OPND_CLASS_ADDRESS)
1118
1.73k
      break;
1119
1.73k
  }
1120
1121
1.73k
      assert (aarch64_operands[type].op_class == AARCH64_OPND_CLASS_ADDRESS);
1122
1.73k
      int offset = calc_ldst_datasize (inst->operands);
1123
1124
1.73k
      switch (type)
1125
1.73k
  {
1126
677
  case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
1127
964
  case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
1128
964
    info->addr.offset.imm = -offset;
1129
964
    info->addr.preind = 1;
1130
964
    break;
1131
699
  case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
1132
769
  case AARCH64_OPND_RCPC3_ADDR_POSTIND:
1133
769
    info->addr.offset.imm = offset;
1134
769
    info->addr.postind = 1;
1135
769
    break;
1136
0
  default:
1137
0
    return false;
1138
1.73k
  }
1139
1.73k
    }
1140
16.9k
  return true;
1141
16.9k
}
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.31k
{
1150
7.31k
  info->qualifier = get_expected_qualifier (inst, info->idx);
1151
7.31k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
1152
0
    return 0;
1153
1154
  /* Rn */
1155
7.31k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1156
1157
  /* simm9 */
1158
7.31k
  aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
1159
7.31k
  info->addr.offset.imm = sign_extend (imm, 8);
1160
7.31k
  return true;
1161
7.31k
}
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.3k
{
1171
23.3k
  info->qualifier = get_expected_qualifier (inst, info->idx);
1172
23.3k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
1173
0
    return 0;
1174
1175
  /* Rn */
1176
23.3k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1177
1178
  /* simm9 */
1179
23.3k
  aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
1180
23.3k
  info->addr.offset.imm = sign_extend (imm, 8);
1181
23.3k
  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.3k
  return true;
1186
23.3k
}
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
62.6k
{
1196
62.6k
  aarch64_insn S, value;
1197
1198
  /* Rn */
1199
62.6k
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1200
  /* Rm */
1201
62.6k
  info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1202
  /* option */
1203
62.6k
  value = extract_field (FLD_option, code, 0);
1204
62.6k
  info->shifter.kind =
1205
62.6k
    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
62.6k
  if (info->shifter.kind == AARCH64_MOD_UXTX)
1209
16.9k
    info->shifter.kind = AARCH64_MOD_LSL;
1210
  /* S */
1211
62.6k
  S = extract_field (FLD_S, code, 0);
1212
62.6k
  if (S == 0)
1213
13.5k
    {
1214
13.5k
      info->shifter.amount = 0;
1215
13.5k
      info->shifter.amount_present = 0;
1216
13.5k
    }
1217
49.0k
  else
1218
49.0k
    {
1219
49.0k
      int size;
1220
      /* Need information in other operand(s) to help achieve the decoding
1221
   from 'S' field.  */
1222
49.0k
      info->qualifier = get_expected_qualifier (inst, info->idx);
1223
49.0k
      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
49.0k
      size = aarch64_get_qualifier_esize (info->qualifier);
1228
49.0k
      info->shifter.amount = get_logsz (size);
1229
49.0k
      info->shifter.amount_present = 1;
1230
49.0k
    }
1231
1232
62.6k
  return true;
1233
62.6k
}
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
712k
{
1241
712k
  aarch64_insn imm;
1242
712k
  info->qualifier = get_expected_qualifier (inst, info->idx);
1243
712k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
1244
0
    return 0;
1245
1246
  /* Rn */
1247
712k
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1248
  /* simm (imm9 or imm7)  */
1249
712k
  imm = extract_field (self->fields[0], code, 0);
1250
712k
  info->addr.offset.imm
1251
712k
    = sign_extend (imm, self->fields[0].width - 1);
1252
712k
  if (self->fields[0].width == 7
1253
125k
      || info->qualifier == AARCH64_OPND_QLF_imm_tag)
1254
    /* scaled immediate in ld/st pair instructions.  */
1255
595k
    info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
1256
  /* qualifier */
1257
712k
  if (inst->opcode->iclass == ldst_unscaled
1258
652k
      || inst->opcode->iclass == ldstnapair_offs
1259
507k
      || inst->opcode->iclass == ldstpair_off
1260
321k
      || inst->opcode->iclass == ldst_unpriv)
1261
404k
    info->addr.writeback = 0;
1262
307k
  else
1263
307k
    {
1264
      /* pre/post- index */
1265
307k
      info->addr.writeback = 1;
1266
307k
      if (extract_field (self->fields[1], code, 0) == 1)
1267
154k
  info->addr.preind = 1;
1268
153k
      else
1269
153k
  info->addr.postind = 1;
1270
307k
    }
1271
1272
712k
  return true;
1273
712k
}
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
245k
{
1282
245k
  int shift;
1283
245k
  info->qualifier = get_expected_qualifier (inst, info->idx);
1284
245k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
1285
0
    return 0;
1286
245k
  shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
1287
  /* Rn */
1288
245k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1289
  /* uimm12 */
1290
245k
  info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
1291
245k
  return true;
1292
245k
}
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.2k
{
1301
10.2k
  aarch64_insn imm;
1302
1303
10.2k
  info->qualifier = get_expected_qualifier (inst, info->idx);
1304
10.2k
  if (info->qualifier == AARCH64_OPND_QLF_ERR)
1305
0
    return 0;
1306
  /* Rn */
1307
10.2k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1308
  /* simm10 */
1309
10.2k
  imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
1310
10.2k
  info->addr.offset.imm = sign_extend (imm, 9) << 3;
1311
10.2k
  if (extract_field (self->fields[3], code, 0) == 1) {
1312
5.83k
    info->addr.writeback = 1;
1313
5.83k
    info->addr.preind = 1;
1314
5.83k
  }
1315
10.2k
  return true;
1316
10.2k
}
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.1k
{
1326
  /* The opcode dependent area stores the number of elements in
1327
     each structure to be loaded/stored.  */
1328
21.1k
  int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
1329
1330
  /* Rn */
1331
21.1k
  info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1332
  /* Rm | #<amount>  */
1333
21.1k
  info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1334
21.1k
  if (info->addr.offset.regno == 31)
1335
3.21k
    {
1336
3.21k
      if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
1337
  /* Special handling of loading single structure to all lane.  */
1338
667
  info->addr.offset.imm = (is_ld1r ? 1
1339
667
         : inst->operands[0].reglist.num_regs)
1340
667
    * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1341
2.54k
      else
1342
2.54k
  info->addr.offset.imm = inst->operands[0].reglist.num_regs
1343
2.54k
    * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
1344
2.54k
    * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
1345
3.21k
    }
1346
17.8k
  else
1347
17.8k
    info->addr.offset.is_reg = 1;
1348
21.1k
  info->addr.writeback = 1;
1349
1350
21.1k
  return true;
1351
21.1k
}
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
28.7k
{
1360
28.7k
  aarch64_insn value;
1361
  /* cond */
1362
28.7k
  value = extract_field (FLD_cond, code, 0);
1363
28.7k
  info->cond = get_cond_from_value (value);
1364
28.7k
  return true;
1365
28.7k
}
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
13.9k
{
1375
  /* op0:op1:CRn:CRm:op2 */
1376
13.9k
  info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
1377
13.9k
               FLD_CRm, FLD_op2);
1378
13.9k
  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
13.9k
  if (inst->opcode->iclass == ic_system)
1383
13.9k
    {
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
13.9k
      if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ)
1387
5.85k
  info->sysreg.flags = F_REG_READ;
1388
8.05k
      else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE))
1389
8.05k
         == F_SYS_WRITE)
1390
8.05k
  info->sysreg.flags = F_REG_WRITE;
1391
13.9k
    }
1392
1393
13.9k
  return true;
1394
13.9k
}
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
350
{
1403
350
  int i;
1404
350
  aarch64_insn fld_crm = extract_field (FLD_CRm, code, 0);
1405
  /* op1:op2 */
1406
350
  info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1407
1.94k
  for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1408
1.86k
    if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1409
525
      {
1410
        /* PSTATEFIELD name can be encoded partially in CRm[3:1].  */
1411
525
        uint32_t flags = aarch64_pstatefields[i].flags;
1412
525
        if ((flags & F_REG_IN_CRM)
1413
264
            && ((fld_crm & 0xe) != PSTATE_DECODE_CRM (flags)))
1414
264
          continue;
1415
261
        info->sysreg.flags = flags;
1416
261
        return true;
1417
525
      }
1418
  /* Reserved value in <pstatefield>.  */
1419
89
  return false;
1420
350
}
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.1k
{
1430
23.1k
  int i;
1431
23.1k
  aarch64_insn value;
1432
23.1k
  const aarch64_sys_ins_reg *sysins_ops;
1433
  /* op0:op1:CRn:CRm:op2 */
1434
23.1k
  value = extract_fields (code, 0, 5,
1435
23.1k
        FLD_op0, FLD_op1, FLD_CRn,
1436
23.1k
        FLD_CRm, FLD_op2);
1437
1438
23.1k
  switch (info->type)
1439
23.1k
    {
1440
3.19k
    case AARCH64_OPND_GIC: sysins_ops = aarch64_sys_ins_gic; break;
1441
3.19k
    case AARCH64_OPND_GICR: sysins_ops = aarch64_sys_ins_gicr; break;
1442
738
    case AARCH64_OPND_GSB: sysins_ops = aarch64_sys_ins_gsb; break;
1443
2.56k
    case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1444
2.73k
    case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1445
2.73k
    case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1446
2.97k
    case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1447
1.74k
    case AARCH64_OPND_SYSREG_TLBIP: sysins_ops = aarch64_sys_regs_tlbi; break;
1448
3.23k
    case AARCH64_OPND_SYSREG_PLBI: sysins_ops = aarch64_sys_regs_plbi; break;
1449
0
    case AARCH64_OPND_SYSREG_SR:
1450
0
  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
0
  value = value & ~(0x7);
1454
0
  break;
1455
0
    default: return false;
1456
23.1k
    }
1457
1458
1.18M
  for (i = 0; sysins_ops[i].name != NULL; ++i)
1459
1.16M
    if (sysins_ops[i].value == value)
1460
1.47k
      {
1461
1.47k
  info->sysins_op = sysins_ops + i;
1462
1.47k
  DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1463
1.47k
         info->sysins_op->name,
1464
1.47k
         (unsigned)info->sysins_op->value,
1465
1.47k
         aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1466
1.47k
  return true;
1467
1.47k
      }
1468
1469
21.6k
  return false;
1470
23.1k
}
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
592
{
1481
  /* CRm */
1482
592
  info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1483
592
  return true;
1484
592
}
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
342
{
1495
  /* For the DSB nXS barrier variant immediate is encoded in 2-bit field.  */
1496
342
  aarch64_insn field = extract_field (FLD_CRm_dsb_nxs, code, 0);
1497
342
  info->barrier = aarch64_barrier_dsb_nxs_options + field;
1498
342
  return true;
1499
342
}
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
45.1k
{
1510
  /* prfop in Rt */
1511
45.1k
  info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1512
45.1k
  return true;
1513
45.1k
}
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
362
{
1525
  /* CRm:op2.  */
1526
362
  unsigned hint_number;
1527
362
  int i;
1528
1529
362
  hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1530
1531
2.75k
  for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1532
2.75k
    {
1533
2.75k
      if (hint_number == aarch64_hint_options[i].value)
1534
362
  {
1535
362
    info->hint_option = &(aarch64_hint_options[i]);
1536
362
    return true;
1537
362
  }
1538
2.75k
    }
1539
1540
0
  return false;
1541
362
}
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
60.3k
{
1552
60.3k
  aarch64_insn value;
1553
1554
  /* Rm */
1555
60.3k
  info->reg.regno = extract_field (FLD_Rm, code, 0);
1556
  /* option */
1557
60.3k
  value = extract_field (FLD_option, code, 0);
1558
60.3k
  info->shifter.kind =
1559
60.3k
    aarch64_get_operand_modifier_from_value (value, true /* extend_p */);
1560
  /* imm3 */
1561
60.3k
  info->shifter.amount = extract_field (FLD_imm3_10, code,  0);
1562
1563
  /* This makes the constraint checking happy.  */
1564
60.3k
  info->shifter.operator_present = 1;
1565
1566
  /* Assume inst->operands[0].qualifier has been resolved.  */
1567
60.3k
  assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_UNKNOWN);
1568
60.3k
  info->qualifier = AARCH64_OPND_QLF_W;
1569
60.3k
  if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1570
16.2k
      && (info->shifter.kind == AARCH64_MOD_UXTX
1571
13.3k
    || info->shifter.kind == AARCH64_MOD_SXTX))
1572
5.49k
    info->qualifier = AARCH64_OPND_QLF_X;
1573
1574
60.3k
  return true;
1575
60.3k
}
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
569k
{
1586
569k
  aarch64_insn value;
1587
1588
  /* Rm */
1589
569k
  info->reg.regno = extract_field (FLD_Rm, code, 0);
1590
  /* shift */
1591
569k
  value = extract_field (FLD_shift, code, 0);
1592
569k
  info->shifter.kind =
1593
569k
    aarch64_get_operand_modifier_from_value (value, false /* extend_p */);
1594
569k
  if (info->shifter.kind == AARCH64_MOD_ROR
1595
111k
      && inst->opcode->iclass != log_shift)
1596
    /* ROR is not available for the shifted register operand in arithmetic
1597
       instructions.  */
1598
25.3k
    return false;
1599
  /* imm6 */
1600
544k
  info->shifter.amount = extract_field (FLD_imm6_10, code,  0);
1601
1602
  /* This makes the constraint checking happy.  */
1603
544k
  info->shifter.operator_present = 1;
1604
1605
544k
  return true;
1606
569k
}
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
876
{
1617
  /* Rm */
1618
876
  info->reg.regno = extract_field (FLD_Rm, code, 0);
1619
  /* imm3 */
1620
876
  info->shifter.kind = AARCH64_MOD_LSL;
1621
876
  info->shifter.amount = extract_field (FLD_imm3_10, code,  0);
1622
876
  return true;
1623
876
}
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
94.9k
{
1634
94.9k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1635
94.9k
  info->addr.offset.imm = offset * (1 + get_operand_specific_data (self));
1636
94.9k
  info->addr.offset.is_reg = false;
1637
94.9k
  info->addr.writeback = false;
1638
94.9k
  info->addr.preind = true;
1639
94.9k
  if (offset != 0)
1640
88.6k
    info->shifter.kind = AARCH64_MOD_MUL_VL;
1641
94.9k
  info->shifter.amount = 1;
1642
94.9k
  info->shifter.operator_present = (info->addr.offset.imm != 0);
1643
94.9k
  info->shifter.amount_present = false;
1644
94.9k
  return true;
1645
94.9k
}
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
85.7k
{
1657
85.7k
  int offset;
1658
1659
85.7k
  offset = extract_field (FLD_SVE_imm4, code, 0);
1660
85.7k
  offset = ((offset + 8) & 15) - 8;
1661
85.7k
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1662
85.7k
}
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.27k
{
1674
3.27k
  int offset;
1675
1676
3.27k
  offset = extract_field (FLD_SVE_imm6, code, 0);
1677
3.27k
  offset = (((offset + 32) & 63) - 32);
1678
3.27k
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1679
3.27k
}
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
5.87k
{
1693
5.87k
  int offset;
1694
1695
5.87k
  offset = extract_fields (code, 0, 2, FLD_SVE_imm6, FLD_imm3_10);
1696
5.87k
  offset = (((offset + 256) & 511) - 256);
1697
5.87k
  return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1698
5.87k
}
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
33.3k
{
1708
33.3k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1709
33.3k
  info->addr.offset.imm = offset * (1 << get_operand_specific_data (self));
1710
33.3k
  info->addr.offset.is_reg = false;
1711
33.3k
  info->addr.writeback = false;
1712
33.3k
  info->addr.preind = true;
1713
33.3k
  info->shifter.operator_present = false;
1714
33.3k
  info->shifter.amount_present = false;
1715
33.3k
  return true;
1716
33.3k
}
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.96k
{
1727
2.96k
  int offset = sign_extend (extract_field (FLD_SVE_imm4, code, 0), 3);
1728
2.96k
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1729
2.96k
}
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.5k
{
1740
14.5k
  int offset = extract_field (FLD_SVE_imm6, code, 0);
1741
14.5k
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1742
14.5k
}
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
175k
{
1753
175k
  int index_regno;
1754
1755
175k
  index_regno = extract_field (self->fields[1], code, 0);
1756
175k
  if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
1757
1.53k
    return false;
1758
1759
174k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1760
174k
  info->addr.offset.regno = index_regno;
1761
174k
  info->addr.offset.is_reg = true;
1762
174k
  info->addr.writeback = false;
1763
174k
  info->addr.preind = true;
1764
174k
  info->shifter.kind = AARCH64_MOD_LSL;
1765
174k
  info->shifter.amount = get_operand_specific_data (self);
1766
174k
  info->shifter.operator_present = (info->shifter.amount != 0);
1767
174k
  info->shifter.amount_present = (info->shifter.amount != 0);
1768
174k
  return true;
1769
175k
}
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
73.7k
{
1781
73.7k
  info->addr.base_regno = extract_field (self->fields[0], code, 0);
1782
73.7k
  info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1783
73.7k
  info->addr.offset.is_reg = true;
1784
73.7k
  info->addr.writeback = false;
1785
73.7k
  info->addr.preind = true;
1786
73.7k
  if (extract_field (self->fields[2], code, 0))
1787
34.5k
    info->shifter.kind = AARCH64_MOD_SXTW;
1788
39.2k
  else
1789
39.2k
    info->shifter.kind = AARCH64_MOD_UXTW;
1790
73.7k
  info->shifter.amount = get_operand_specific_data (self);
1791
73.7k
  info->shifter.operator_present = true;
1792
73.7k
  info->shifter.amount_present = (info->shifter.amount != 0);
1793
73.7k
  return true;
1794
73.7k
}
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
15.8k
{
1805
15.8k
  int offset = extract_field (FLD_imm5, code, 0);
1806
15.8k
  return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1807
15.8k
}
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
983
            || 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
983
{
1839
983
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_LSL);
1840
983
}
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
297
{
1851
297
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_SXTW);
1852
297
}
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
955
{
1863
955
  return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
1864
955
}
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.1k
{
1871
20.1k
  info->shifter.kind = AARCH64_MOD_LSL;
1872
20.1k
  info->shifter.amount = 0;
1873
20.1k
  if (info->imm.value & 0x100)
1874
6.74k
    {
1875
6.74k
      if (value == 0)
1876
  /* Decode 0x100 as #0, LSL #8.  */
1877
614
  info->shifter.amount = 8;
1878
6.12k
      else
1879
6.12k
  value *= 256;
1880
6.74k
    }
1881
20.1k
  info->shifter.operator_present = (info->shifter.amount != 0);
1882
20.1k
  info->shifter.amount_present = (info->shifter.amount != 0);
1883
20.1k
  info->imm.value = value;
1884
20.1k
  return true;
1885
20.1k
}
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.58k
{
1894
2.58k
  return (aarch64_ext_imm (self, info, code, inst, errors)
1895
2.58k
    && decode_sve_aimm (info, (uint8_t) info->imm.value));
1896
2.58k
}
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
59.9k
{
1904
59.9k
  unsigned int num_regs = get_operand_specific_data (self);
1905
59.9k
  info->reglist.first_regno = extract_all_fields (self, code);
1906
59.9k
  info->reglist.num_regs = num_regs;
1907
59.9k
  info->reglist.stride = 1;
1908
59.9k
  return true;
1909
59.9k
}
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.5k
{
1918
17.5k
  return (aarch64_ext_imm (self, info, code, inst, errors)
1919
17.5k
    && decode_sve_aimm (info, (int8_t) info->imm.value));
1920
17.5k
}
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
87
{
1930
87
  if (extract_field (self->fields[0], code, 0))
1931
28
    info->imm.value = 0x3f800000;
1932
59
  else
1933
59
    info->imm.value = 0x3f000000;
1934
87
  info->imm.is_fp = true;
1935
87
  return true;
1936
87
}
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
304
{
1946
304
  if (extract_field (self->fields[0], code, 0))
1947
110
    info->imm.value = 0x40000000;
1948
194
  else
1949
194
    info->imm.value = 0x3f000000;
1950
304
  info->imm.is_fp = true;
1951
304
  return true;
1952
304
}
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.17k
{
1962
1.17k
  if (extract_field (self->fields[0], code, 0))
1963
121
    info->imm.value = 0x3f800000;
1964
1.05k
  else
1965
1.05k
    info->imm.value = 0x0;
1966
1.17k
  info->imm.is_fp = true;
1967
1.17k
  return true;
1968
1.17k
}
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
734
{
1977
734
  aarch64_insn Qsize;   /* fields Q:S:size.  */
1978
734
  int fld_v = extract_field (self->fields[0], code, 0);
1979
734
  int fld_rv = extract_field (self->fields[1], code, 0);
1980
734
  int fld_zan_imm =  extract_field (FLD_imm4_5, code, 0);
1981
1982
734
  Qsize = extract_fields (inst->value, 0, 2, FLD_SME_size_22, FLD_SME_Q);
1983
734
  switch (Qsize)
1984
734
    {
1985
134
    case 0x0:
1986
134
      info->qualifier = AARCH64_OPND_QLF_S_B;
1987
134
      info->indexed_za.regno = 0;
1988
134
      info->indexed_za.index.imm = fld_zan_imm;
1989
134
      break;
1990
297
    case 0x2:
1991
297
      info->qualifier = AARCH64_OPND_QLF_S_H;
1992
297
      info->indexed_za.regno = fld_zan_imm >> 3;
1993
297
      info->indexed_za.index.imm = fld_zan_imm & 0x07;
1994
297
      break;
1995
49
    case 0x4:
1996
49
      info->qualifier = AARCH64_OPND_QLF_S_S;
1997
49
      info->indexed_za.regno = fld_zan_imm >> 2;
1998
49
      info->indexed_za.index.imm = fld_zan_imm & 0x03;
1999
49
      break;
2000
125
    case 0x6:
2001
125
      info->qualifier = AARCH64_OPND_QLF_S_D;
2002
125
      info->indexed_za.regno = fld_zan_imm >> 1;
2003
125
      info->indexed_za.index.imm = fld_zan_imm & 0x01;
2004
125
      break;
2005
129
    case 0x7:
2006
129
      info->qualifier = AARCH64_OPND_QLF_S_Q;
2007
129
      info->indexed_za.regno = fld_zan_imm;
2008
129
      break;
2009
0
    default:
2010
0
      return false;
2011
734
    }
2012
2013
734
  info->indexed_za.index.regno = fld_rv + 12;
2014
734
  info->indexed_za.v = fld_v;
2015
2016
734
  return true;
2017
734
}
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
131k
{
2027
131k
  int fld_size = extract_field (self->fields[0], code, 0);
2028
131k
  int fld_q = extract_field (self->fields[1], code, 0);
2029
131k
  int fld_v = extract_field (self->fields[2], code, 0);
2030
131k
  int fld_rv = extract_field (self->fields[3], code, 0);
2031
131k
  int fld_zan_imm = extract_field (self->fields[4], code, 0);
2032
2033
  /* Deduce qualifier encoded in size and Q fields.  */
2034
131k
  if (fld_size == 0)
2035
18.6k
    {
2036
18.6k
      info->indexed_za.regno = 0;
2037
18.6k
      info->indexed_za.index.imm = fld_zan_imm;
2038
18.6k
    }
2039
112k
  else if (fld_size == 1)
2040
4.19k
    {
2041
4.19k
      info->indexed_za.regno = fld_zan_imm >> 3;
2042
4.19k
      info->indexed_za.index.imm = fld_zan_imm & 0x07;
2043
4.19k
    }
2044
108k
  else if (fld_size == 2)
2045
5.84k
    {
2046
5.84k
      info->indexed_za.regno = fld_zan_imm >> 2;
2047
5.84k
      info->indexed_za.index.imm = fld_zan_imm & 0x03;
2048
5.84k
    }
2049
102k
  else if (fld_size == 3 && fld_q == 0)
2050
86.1k
    {
2051
86.1k
      info->indexed_za.regno = fld_zan_imm >> 1;
2052
86.1k
      info->indexed_za.index.imm = fld_zan_imm & 0x01;
2053
86.1k
    }
2054
16.2k
  else if (fld_size == 3 && fld_q == 1)
2055
16.2k
    {
2056
16.2k
      info->indexed_za.regno = fld_zan_imm;
2057
16.2k
      info->indexed_za.index.imm = 0;
2058
16.2k
    }
2059
0
  else
2060
0
    return false;
2061
2062
131k
  info->indexed_za.index.regno = fld_rv + 12;
2063
131k
  info->indexed_za.v = fld_v;
2064
2065
131k
  return true;
2066
131k
}
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.34k
{
2075
7.34k
  int ebytes = aarch64_get_qualifier_esize (info->qualifier);
2076
7.34k
  int range_size = get_opcode_dependent_value (inst->opcode);
2077
7.34k
  int fld_v = extract_field (self->fields[0], code, 0);
2078
7.34k
  int fld_rv = extract_field (self->fields[1], code, 0);
2079
7.34k
  int fld_zan_imm = extract_field (self->fields[2], code, 0);
2080
7.34k
  int max_value = 16 / range_size / ebytes;
2081
2082
7.34k
  if (max_value == 0)
2083
152
    max_value = 1;
2084
2085
7.34k
  int regno = fld_zan_imm / max_value;
2086
7.34k
  if (regno >= ebytes)
2087
106
    return false;
2088
2089
7.24k
  info->indexed_za.regno = regno;
2090
7.24k
  info->indexed_za.index.imm = (fld_zan_imm % max_value) * range_size;
2091
7.24k
  info->indexed_za.index.countm1 = range_size - 1;
2092
7.24k
  info->indexed_za.index.regno = fld_rv + 12;
2093
7.24k
  info->indexed_za.v = fld_v;
2094
2095
7.24k
  return true;
2096
7.34k
}
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
53.2k
{
2125
53.2k
  int regno = extract_field (self->fields[0], code, 0);
2126
53.2k
  if (info->type == AARCH64_OPND_SME_ZA_array_off4)
2127
974
    regno += 12;
2128
52.2k
  else
2129
52.2k
    regno += 8;
2130
53.2k
  int imm = extract_field (self->fields[1], code, 0);
2131
53.2k
  int num_offsets = get_operand_specific_data (self);
2132
53.2k
  if (num_offsets == 0)
2133
12.1k
    num_offsets = 1;
2134
53.2k
  info->indexed_za.index.regno = regno;
2135
53.2k
  info->indexed_za.index.imm = imm * num_offsets;
2136
53.2k
  info->indexed_za.index.countm1 = num_offsets - 1;
2137
53.2k
  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
2138
53.2k
  return true;
2139
53.2k
}
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
529
{
2148
529
  int v = extract_field (self->fields[0], code, 0);
2149
529
  int regno = 12 + extract_field (self->fields[1], code, 0);
2150
529
  int imm, za_reg, num_offset = 2;
2151
2152
529
  switch (info->qualifier)
2153
529
    {
2154
115
    case AARCH64_OPND_QLF_S_B:
2155
115
      imm = extract_field (self->fields[2], code, 0);
2156
115
      info->indexed_za.index.imm = imm * num_offset;
2157
115
      break;
2158
28
    case AARCH64_OPND_QLF_S_H:
2159
147
    case AARCH64_OPND_QLF_S_S:
2160
147
      za_reg = extract_field (self->fields[2], code, 0);
2161
147
      imm = extract_field (self->fields[3], code, 0);
2162
147
      info->indexed_za.index.imm = imm * num_offset;
2163
147
      info->indexed_za.regno = za_reg;
2164
147
      break;
2165
267
    case AARCH64_OPND_QLF_S_D:
2166
267
      za_reg = extract_field (self->fields[2], code, 0);
2167
267
      info->indexed_za.regno = za_reg;
2168
267
      break;
2169
0
    default:
2170
0
      return false;
2171
529
    }
2172
2173
529
  info->indexed_za.index.regno = regno;
2174
529
  info->indexed_za.index.countm1 = num_offset - 1;
2175
529
  info->indexed_za.v = v;
2176
529
  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
2177
529
  return true;
2178
529
}
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.02k
{
2187
1.02k
  int v = extract_field (self->fields[0], code, 0);
2188
1.02k
  int regno = 12 + extract_field (self->fields[1], code, 0);
2189
1.02k
  int imm, za_reg, num_offset =4;
2190
2191
1.02k
  switch (info->qualifier)
2192
1.02k
    {
2193
301
    case AARCH64_OPND_QLF_S_B:
2194
301
      imm = extract_field (self->fields[2], code, 0);
2195
301
      info->indexed_za.index.imm = imm * num_offset;
2196
301
      break;
2197
124
    case AARCH64_OPND_QLF_S_H:
2198
124
      za_reg = extract_field (self->fields[2], code, 0);
2199
124
      imm = extract_field (self->fields[3], code, 0);
2200
124
      info->indexed_za.index.imm = imm * num_offset;
2201
124
      info->indexed_za.regno = za_reg;
2202
124
      break;
2203
217
    case AARCH64_OPND_QLF_S_S:
2204
602
    case AARCH64_OPND_QLF_S_D:
2205
602
      za_reg = extract_field (self->fields[2], code, 0);
2206
602
      info->indexed_za.regno = za_reg;
2207
602
      break;
2208
0
    default:
2209
0
      return false;
2210
1.02k
    }
2211
2212
1.02k
  info->indexed_za.index.regno = regno;
2213
1.02k
  info->indexed_za.index.countm1 = num_offset - 1;
2214
1.02k
  info->indexed_za.v = v;
2215
1.02k
  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
2216
1.02k
  return true;
2217
1.02k
}
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
974
{
2225
974
  int regno = extract_field (self->fields[0], code, 0);
2226
974
  int imm = extract_field (self->fields[1], code, 0);
2227
974
  info->addr.base_regno = regno;
2228
974
  info->addr.offset.imm = imm;
2229
  /* MUL VL operator is always present for this operand.  */
2230
974
  info->shifter.kind = AARCH64_MOD_MUL_VL;
2231
974
  info->shifter.operator_present = (imm != 0);
2232
974
  return true;
2233
974
}
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
88
{
2242
88
  info->pstatefield = 0x1b;
2243
88
  aarch64_insn fld_crm = extract_field (self->fields[0], code, 0);
2244
88
  fld_crm >>= 1;    /* CRm[3:1].  */
2245
2246
88
  if (fld_crm == 0x1)
2247
0
    info->reg.regno = 's';
2248
88
  else if (fld_crm == 0x2)
2249
0
    info->reg.regno = 'z';
2250
88
  else
2251
88
    return false;
2252
2253
0
  return true;
2254
88
}
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.1k
{
2262
10.1k
  aarch64_insn fld_rm = extract_field (self->fields[0], code, 0);
2263
10.1k
  aarch64_insn fld_pn = extract_field (self->fields[1], code, 0);
2264
10.1k
  aarch64_insn fld_i1 = extract_field (self->fields[2], code, 0);
2265
10.1k
  aarch64_insn fld_tszh = extract_field (self->fields[3], code, 0);
2266
10.1k
  aarch64_insn fld_tszl = extract_field (self->fields[4], code, 0);
2267
10.1k
  int imm;
2268
2269
10.1k
  info->indexed_za.regno = fld_pn;
2270
10.1k
  info->indexed_za.index.regno = fld_rm + 12;
2271
2272
10.1k
  if (fld_tszl & 0x1)
2273
2.28k
    imm = (fld_i1 << 3) | (fld_tszh << 2) | (fld_tszl >> 1);
2274
7.85k
  else if (fld_tszl & 0x2)
2275
5.17k
    imm = (fld_i1 << 2) | (fld_tszh << 1) | (fld_tszl >> 2);
2276
2.68k
  else if (fld_tszl & 0x4)
2277
1.86k
    imm = (fld_i1 << 1) | fld_tszh;
2278
820
  else if (fld_tszh)
2279
820
    imm = fld_i1;
2280
0
  else
2281
0
    return false;
2282
2283
10.1k
  info->indexed_za.index.imm = imm;
2284
10.1k
  return true;
2285
10.1k
}
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.28k
{
2297
3.28k
  int val;
2298
2299
3.28k
  info->reglane.regno = extract_field (self->fields[0], code, 0);
2300
3.28k
  val = extract_all_fields_after (self, 1, code);
2301
3.28k
  if ((val & 31) == 0)
2302
0
    return 0;
2303
6.82k
  while ((val & 1) == 0)
2304
3.53k
    val /= 2;
2305
3.28k
  info->reglane.index = val / 2;
2306
3.28k
  return true;
2307
3.28k
}
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.37k
{
2316
5.37k
  int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
2317
5.37k
  return (aarch64_ext_limm (self, info, code, inst, errors)
2318
5.37k
    && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
2319
5.37k
}
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
34.8k
{
2330
34.8k
  unsigned int reg_bits = get_operand_specific_data (self);
2331
34.8k
  unsigned int val = extract_all_fields (self, code);
2332
34.8k
  info->reglane.regno = val & ((1 << reg_bits) - 1);
2333
34.8k
  info->reglane.index = val >> reg_bits;
2334
34.8k
  return true;
2335
34.8k
}
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
286k
{
2346
286k
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
2347
286k
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
2348
286k
  info->reglist.stride = 1;
2349
286k
  return true;
2350
286k
}
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
318
{
2376
318
  info->reglist.first_regno = extract_field (self->fields[0], code, 0);
2377
318
  info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
2378
318
  info->reglist.stride = 1;
2379
318
  info->reglist.has_index = true;
2380
318
  info->reglist.index = extract_field (FLD_imm1_22, code, 0);
2381
318
  return true;
2382
318
}
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.0k
{
2394
13.0k
  unsigned int upper = extract_field (self->fields[0], code, 0);
2395
13.0k
  unsigned int lower = extract_field (self->fields[1], code, 0);
2396
13.0k
  info->reglist.first_regno = upper * 16 + lower;
2397
13.0k
  info->reglist.num_regs = get_operand_specific_data (self);
2398
13.0k
  info->reglist.stride = 16 / info->reglist.num_regs;
2399
13.0k
  return true;
2400
13.0k
}
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
6.87k
{
2410
6.87k
  int val;
2411
2412
6.87k
  if (!aarch64_ext_imm (self, info, code, inst, errors))
2413
0
    return false;
2414
6.87k
  val = extract_field (FLD_SVE_imm4, code, 0);
2415
6.87k
  info->shifter.kind = AARCH64_MOD_MUL;
2416
6.87k
  info->shifter.amount = val + 1;
2417
6.87k
  info->shifter.operator_present = (val != 0);
2418
6.87k
  info->shifter.amount_present = (val != 0);
2419
6.87k
  return true;
2420
6.87k
}
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.5k
{
2427
45.3k
  while ((value & -value) != value)
2428
32.7k
    value -= value & -value;
2429
12.5k
  return value;
2430
12.5k
}
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.31k
{
2438
3.31k
  if (!aarch64_ext_imm (self, info, code, inst, errors)
2439
3.31k
      || info->imm.value == 0)
2440
0
    return false;
2441
2442
3.31k
  info->imm.value -= get_top_bit (info->imm.value);
2443
3.31k
  return true;
2444
3.31k
}
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.25k
{
2452
9.25k
  if (!aarch64_ext_imm (self, info, code, inst, errors)
2453
9.25k
      || info->imm.value == 0)
2454
0
    return false;
2455
2456
9.25k
  info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
2457
9.25k
  return true;
2458
9.25k
}
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
33.0k
{
2467
33.0k
  info->reg.regno = extract_field (self->fields[0], code, 0);
2468
33.0k
  return info->reg.regno <= 30;
2469
33.0k
}
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
54.6k
{
2479
54.6k
  unsigned int val = extract_all_fields (self, code);
2480
54.6k
  info->reglane.regno = val & 31;
2481
54.6k
  info->reglane.index = val >> 5;
2482
54.6k
  return true;
2483
54.6k
}
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
485
{
2493
485
  unsigned int base = 1 << get_operand_field_width (self, 0);
2494
485
  info->imm.value = base - extract_field (self->fields[0], code, 0);
2495
485
  return true;
2496
485
}
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
172k
{
2524
172k
  int i;
2525
172k
  DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
2526
300k
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
2527
300k
    {
2528
300k
      aarch64_insn standard_value;
2529
300k
      if (candidates[i] == AARCH64_OPND_QLF_UNUSED)
2530
24.3k
  break;
2531
276k
      standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
2532
276k
      if ((standard_value & mask) == (value & mask))
2533
147k
  return candidates[i];
2534
276k
    }
2535
24.3k
  return AARCH64_OPND_QLF_ERR;
2536
172k
}
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
172k
{
2547
172k
  int i;
2548
568k
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
2549
568k
    if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_UNUSED)
2550
172k
      break;
2551
172k
}
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
356k
{
2561
356k
  int idx;
2562
356k
  aarch64_insn code;
2563
356k
  aarch64_insn value, mask;
2564
356k
  aarch64_field fld_sz;
2565
356k
  enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2566
2567
356k
  if (inst->opcode->iclass == asisdlse
2568
333k
     || inst->opcode->iclass == asisdlsep
2569
295k
     || inst->opcode->iclass == asisdlso
2570
295k
     || inst->opcode->iclass == asisdlsop)
2571
62.9k
    fld_sz = FLD_vldst_size;
2572
293k
  else
2573
293k
    fld_sz = FLD_size;
2574
2575
356k
  code = inst->value;
2576
356k
  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
356k
  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
356k
  idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
2586
356k
  DEBUG_TRACE ("key idx: %d", idx);
2587
2588
  /* For most related instruciton, size:Q are fully available for operand
2589
     encoding.  */
2590
356k
  if (mask == 0x7)
2591
191k
    {
2592
191k
      inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
2593
191k
      if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
2594
0
  return 0;
2595
191k
      return 1;
2596
191k
    }
2597
2598
165k
  get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2599
165k
           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
165k
  enum aarch64_opnd_qualifier qualifier
2613
165k
    = get_qualifier_from_partial_encoding (value, candidates, mask);
2614
2615
165k
  if (qualifier == AARCH64_OPND_QLF_ERR)
2616
24.3k
    return 0;
2617
2618
140k
  inst->operands[idx].qualifier = qualifier;
2619
140k
  return 1;
2620
165k
}
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
973
{
2628
973
  aarch64_field field = AARCH64_FIELD_NIL;
2629
973
  aarch64_insn value;
2630
973
  enum aarch64_opnd_qualifier qualifier;
2631
2632
973
  gen_sub_field (FLD_size, 0, 1, &field);
2633
973
  value = extract_field (field, inst->value, 0);
2634
973
  qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
2635
973
    : AARCH64_OPND_QLF_V_2D;
2636
973
  switch (inst->opcode->op)
2637
973
    {
2638
167
    case OP_FCVTN:
2639
452
    case OP_FCVTN2:
2640
      /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
2641
452
      inst->operands[1].qualifier = qualifier;
2642
452
      break;
2643
391
    case OP_FCVTL:
2644
521
    case OP_FCVTL2:
2645
      /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>.  */
2646
521
      inst->operands[0].qualifier = qualifier;
2647
521
      break;
2648
0
    default:
2649
0
      return 0;
2650
973
    }
2651
2652
973
  return 1;
2653
973
}
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
148
{
2661
148
  aarch64_field field = AARCH64_FIELD_NIL;
2662
148
  gen_sub_field (FLD_size, 0, 1, &field);
2663
148
  if (!extract_field (field, inst->value, 0))
2664
49
    return 0;
2665
99
  inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
2666
99
  return 1;
2667
148
}
2668
2669
/* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>.  */
2670
static int
2671
decode_fcvt (aarch64_inst *inst)
2672
396
{
2673
396
  enum aarch64_opnd_qualifier qualifier;
2674
396
  aarch64_insn value;
2675
396
  const aarch64_field field = AARCH64_FIELD (15, 2);
2676
2677
  /* opc dstsize */
2678
396
  value = extract_field (field, inst->value, 0);
2679
396
  switch (value)
2680
396
    {
2681
52
    case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
2682
155
    case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
2683
102
    case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
2684
87
    default: return 0;
2685
396
    }
2686
309
  inst->operands[0].qualifier = qualifier;
2687
2688
309
  return 1;
2689
396
}
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.0k
{
2697
15.0k
  unsigned int value;
2698
15.0k
  switch (inst->opcode->op)
2699
15.0k
    {
2700
396
    case OP_FCVT:
2701
396
      return decode_fcvt (inst);
2702
2703
167
    case OP_FCVTN:
2704
452
    case OP_FCVTN2:
2705
843
    case OP_FCVTL:
2706
973
    case OP_FCVTL2:
2707
973
      return decode_asimd_fcvt (inst);
2708
2709
148
    case OP_FCVTXN_S:
2710
148
      return decode_asisd_fcvtxn (inst);
2711
2712
948
    case OP_MOV_P_P:
2713
1.24k
    case OP_MOVS_P_P:
2714
      /* ORR/ORRS alias with Pn == Pm == Pg.  */
2715
1.24k
      value = extract_field (AARCH64_FIELD (5, 4), inst->value, 0);
2716
1.24k
      return (value == extract_field (AARCH64_FIELD (16, 4), inst->value, 0)
2717
607
        && value == extract_field (AARCH64_FIELD (10, 4),
2718
607
           inst->value, 0));
2719
2720
7.15k
    case OP_MOV_Z_P_Z:
2721
      /* SEL alias with Zd == Zm.  */
2722
7.15k
      return (extract_field (AARCH64_FIELD (0, 5), inst->value, 0)
2723
7.15k
        == extract_field (AARCH64_FIELD (16, 5), inst->value, 0));
2724
2725
1.86k
    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.86k
      value = extract_fields (inst->value, 0, 2, AARCH64_FIELD (22, 2),
2730
1.86k
            AARCH64_FIELD (16, 5));
2731
1.86k
      return value == (value & -value);
2732
2733
402
    case OP_MOV_Z_Z:
2734
      /* ORR alias with Zn == Zm.  */
2735
402
      return (extract_field (AARCH64_FIELD (5, 5), inst->value, 0)
2736
402
        == extract_field (AARCH64_FIELD (16, 5), inst->value, 0));
2737
2738
331
    case OP_MOVM_P_P_P:
2739
      /* SEL alias with Pd == Pm.  */
2740
331
      return (extract_field (AARCH64_FIELD (0, 4), inst->value, 0)
2741
331
        == extract_field (AARCH64_FIELD (16, 4), inst->value, 0));
2742
2743
610
    case OP_MOVZS_P_P_P:
2744
973
    case OP_MOVZ_P_P_P:
2745
      /* AND/ANDS alias with Pn == Pm.  */
2746
973
      return (extract_field (AARCH64_FIELD (5, 4), inst->value, 0)
2747
973
        == extract_field (AARCH64_FIELD (16, 4), inst->value, 0));
2748
2749
505
    case OP_NOTS_P_P_P_Z:
2750
1.56k
    case OP_NOT_P_P_P_Z:
2751
      /* EOR/EORS alias with Pm == Pg.  */
2752
1.56k
      return (extract_field (AARCH64_FIELD (16, 4), inst->value, 0)
2753
1.56k
        == extract_field (AARCH64_FIELD (10, 4), inst->value, 0));
2754
2755
0
    default:
2756
0
      return 0;
2757
15.0k
    }
2758
15.0k
}
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.22M
{
2769
3.22M
  int idx;
2770
3.22M
  aarch64_insn value;
2771
  /* Condition for truly conditional executed instructions, e.g. b.cond.  */
2772
3.22M
  if (inst->opcode->flags & F_COND)
2773
41.6k
    {
2774
41.6k
      value = extract_field (FLD_cond2, inst->value, 0);
2775
41.6k
      inst->cond = get_cond_from_value (value);
2776
41.6k
    }
2777
  /* 'sf' field.  */
2778
3.22M
  if (inst->opcode->flags & F_SF)
2779
2.41M
    {
2780
2.41M
      idx = select_operand_for_sf_field_coding (inst->opcode);
2781
2.41M
      value = extract_field (FLD_sf, inst->value, 0);
2782
2.41M
      if (inst->opcode->iclass == fprcvtfloat2int
2783
2.40M
    || inst->opcode->iclass == fprcvtint2float)
2784
2.07k
  {
2785
2.07k
    if (value == 0)
2786
1.06k
      inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S;
2787
1.00k
    else
2788
1.00k
      inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D;
2789
2.07k
  }
2790
2.40M
      else
2791
2.40M
  inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2792
2.41M
      if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
2793
0
  return 0;
2794
2.41M
      if ((inst->opcode->flags & F_N)
2795
171k
    && extract_field (FLD_N, inst->value, 0) != value)
2796
82.5k
  return 0;
2797
2.41M
    }
2798
  /* 'sf' field.  */
2799
3.14M
  if (inst->opcode->flags & F_LSE_SZ)
2800
39.1k
    {
2801
39.1k
      idx = select_operand_for_sf_field_coding (inst->opcode);
2802
39.1k
      value = extract_field (FLD_lse_sz, inst->value, 0);
2803
39.1k
      inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2804
39.1k
      if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
2805
0
  return 0;
2806
39.1k
    }
2807
  /* rcpc3 'size' field.  */
2808
3.14M
  if (inst->opcode->flags & F_RCPC3_SIZE)
2809
28.8k
    {
2810
28.8k
      value = extract_field (FLD_rcpc3_size, inst->value, 0);
2811
28.8k
      for (int i = 0;
2812
69.6k
     aarch64_operands[inst->operands[i].type].op_class != AARCH64_OPND_CLASS_ADDRESS;
2813
40.8k
     i++)
2814
45.3k
  {
2815
45.3k
    if (aarch64_operands[inst->operands[i].type].op_class
2816
45.3k
        == AARCH64_OPND_CLASS_INT_REG)
2817
33.4k
      {
2818
33.4k
        inst->operands[i].qualifier = get_greg_qualifier_from_value (value & 1);
2819
33.4k
        if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
2820
0
    return 0;
2821
33.4k
      }
2822
11.8k
    else if (aarch64_operands[inst->operands[i].type].op_class
2823
11.8k
        == AARCH64_OPND_CLASS_FP_REG)
2824
11.8k
      {
2825
11.8k
        value += (extract_field (FLD_opc1, inst->value, 0) << 2);
2826
11.8k
        inst->operands[i].qualifier = get_sreg_qualifier_from_value (value);
2827
11.8k
        if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
2828
4.56k
    return 0;
2829
11.8k
      }
2830
45.3k
  }
2831
28.8k
    }
2832
2833
  /* size:Q fields.  */
2834
3.13M
  if (inst->opcode->flags & F_SIZEQ)
2835
356k
    return decode_sizeq (inst);
2836
2837
2.78M
  if (inst->opcode->flags & F_FPTYPE)
2838
73.1k
    {
2839
73.1k
      idx = select_operand_for_fptype_field_coding (inst->opcode);
2840
73.1k
      value = extract_field (FLD_type, inst->value, 0);
2841
73.1k
      switch (value)
2842
73.1k
  {
2843
23.8k
  case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
2844
7.61k
  case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
2845
26.9k
  case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
2846
14.6k
  default: return 0;
2847
73.1k
  }
2848
73.1k
    }
2849
2850
2.76M
  if (inst->opcode->flags & F_SSIZE)
2851
18.4k
    {
2852
      /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2853
   of the base opcode.  */
2854
18.4k
      aarch64_insn mask;
2855
18.4k
      enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2856
18.4k
      idx = select_operand_for_scalar_size_field_coding (inst->opcode);
2857
18.4k
      value = extract_field (FLD_size, inst->value, inst->opcode->mask);
2858
18.4k
      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
18.4k
      if (mask == 0x3)
2862
11.5k
  {
2863
11.5k
    inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
2864
11.5k
    if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
2865
0
      return 0;
2866
11.5k
  }
2867
6.89k
      else
2868
6.89k
  {
2869
6.89k
    get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2870
6.89k
             candidates);
2871
6.89k
    inst->operands[idx].qualifier
2872
6.89k
      = get_qualifier_from_partial_encoding (value, candidates, mask);
2873
6.89k
  }
2874
18.4k
    }
2875
2876
2.76M
  if (inst->opcode->flags & F_LSFE_SZ)
2877
14.8k
    {
2878
14.8k
      value = extract_field (FLD_ldst_size, inst->value, 0);
2879
2880
14.8k
      if (value > 0x3)
2881
0
  return 0;
2882
2883
14.8k
      for (int i = 0;
2884
44.4k
     aarch64_operands[inst->operands[i].type].op_class != AARCH64_OPND_CLASS_ADDRESS;
2885
29.6k
     i++)
2886
29.6k
  {
2887
29.6k
    inst->operands[i].qualifier = get_sreg_qualifier_from_value (value);
2888
29.6k
    if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
2889
0
      return 0;
2890
29.6k
  }
2891
14.8k
    }
2892
2893
2.76M
  if (inst->opcode->flags & F_T)
2894
13.0k
    {
2895
      /* Num of consecutive '0's on the right side of imm5<3:0>.  */
2896
13.0k
      int num = 0;
2897
13.0k
      unsigned val, Q;
2898
13.0k
      assert (aarch64_get_operand_class (inst->opcode->operands[0])
2899
13.0k
        == 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.0k
      val = extract_field (FLD_imm5, inst->value, 0);
2911
28.6k
      while ((val & 0x1) == 0 && ++num <= 3)
2912
15.6k
  val >>= 1;
2913
13.0k
      if (num > 3)
2914
1.39k
  return 0;
2915
11.6k
      Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
2916
11.6k
      inst->operands[0].qualifier =
2917
11.6k
  get_vreg_qualifier_from_value ((num << 1) | Q);
2918
11.6k
      if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR)
2919
0
  return 0;
2920
2921
11.6k
    }
2922
2923
2.76M
  if ((inst->opcode->flags & F_OPD_SIZE) && inst->opcode->iclass == sve2_urqvs)
2924
770
    {
2925
770
      unsigned size;
2926
770
      size = (unsigned) extract_field (FLD_size, inst->value,
2927
770
               inst->opcode->mask);
2928
770
      inst->operands[0].qualifier
2929
770
  = get_vreg_qualifier_from_value (1 + (size << 1));
2930
770
      if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR)
2931
0
  return 0;
2932
770
      inst->operands[2].qualifier = get_sreg_qualifier_from_value (size);
2933
770
      if (inst->operands[2].qualifier == AARCH64_OPND_QLF_ERR)
2934
0
  return 0;
2935
770
    }
2936
2937
2.76M
  if (inst->opcode->flags & F_GPRSIZE_IN_Q)
2938
184k
    {
2939
      /* Use Rt to encode in the case of e.g.
2940
   STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}].  */
2941
184k
      idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
2942
184k
      if (idx == -1)
2943
5.40k
  {
2944
    /* Otherwise use the result operand, which has to be a integer
2945
       register.  */
2946
5.40k
    assert (aarch64_get_operand_class (inst->opcode->operands[0])
2947
5.40k
      == AARCH64_OPND_CLASS_INT_REG);
2948
5.40k
    idx = 0;
2949
5.40k
  }
2950
184k
      assert (idx == 0 || idx == 1);
2951
184k
      value = extract_field (FLD_Q, inst->value, 0);
2952
184k
      inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2953
184k
      if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
2954
0
  return 0;
2955
184k
    }
2956
2957
2.76M
  if (inst->opcode->flags & F_LDS_SIZE)
2958
37.4k
    {
2959
37.4k
      aarch64_field field = AARCH64_FIELD_NIL;
2960
37.4k
      assert (aarch64_get_operand_class (inst->opcode->operands[0])
2961
37.4k
        == AARCH64_OPND_CLASS_INT_REG);
2962
37.4k
      gen_sub_field (FLD_opc, 0, 1, &field);
2963
37.4k
      value = extract_field (field, inst->value, 0);
2964
37.4k
      inst->operands[0].qualifier
2965
37.4k
  = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
2966
37.4k
    }
2967
2968
  /* Miscellaneous decoding; done as the last step.  */
2969
2.76M
  if (inst->opcode->flags & F_MISC)
2970
15.0k
    return do_misc_decoding (inst);
2971
2972
2.75M
  return 1;
2973
2.76M
}
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.04k
{
2983
3.04k
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2984
396
    {
2985
396
      copy_operand_info (inst, 2, 3);
2986
396
      inst->operands[3].type = AARCH64_OPND_NIL;
2987
396
      return 1;
2988
396
    }
2989
2.65k
  return 0;
2990
3.04k
}
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
956
{
2998
956
  if (inst->operands[2].imm.value == 0)
2999
836
    {
3000
836
      inst->operands[2].type = AARCH64_OPND_NIL;
3001
836
      return 1;
3002
836
    }
3003
120
  return 0;
3004
956
}
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
25.7k
{
3013
25.7k
  int64_t imms, val;
3014
3015
25.7k
  imms = inst->operands[3].imm.value;
3016
25.7k
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
3017
25.7k
  if (imms == val)
3018
605
    {
3019
605
      inst->operands[3].type = AARCH64_OPND_NIL;
3020
605
      return 1;
3021
605
    }
3022
3023
25.1k
  return 0;
3024
25.7k
}
3025
3026
/* Convert MOV to ORR.  */
3027
static int
3028
convert_orr_to_mov (aarch64_inst *inst)
3029
661
{
3030
  /* MOV <Vd>.<T>, <Vn>.<T>
3031
     is equivalent to:
3032
     ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>.  */
3033
661
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
3034
128
    {
3035
128
      inst->operands[2].type = AARCH64_OPND_NIL;
3036
128
      return 1;
3037
128
    }
3038
533
  return 0;
3039
661
}
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
34.2k
{
3049
34.2k
  int64_t immr, imms;
3050
3051
34.2k
  immr = inst->operands[2].imm.value;
3052
34.2k
  imms = inst->operands[3].imm.value;
3053
34.2k
  if (imms >= immr)
3054
16.7k
    {
3055
16.7k
      int64_t lsb = immr;
3056
16.7k
      inst->operands[2].imm.value = lsb;
3057
16.7k
      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
16.7k
      reset_operand_qualifier (inst, 2);
3061
16.7k
      reset_operand_qualifier (inst, 3);
3062
16.7k
      return 1;
3063
16.7k
    }
3064
3065
17.4k
  return 0;
3066
34.2k
}
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
17.4k
{
3076
17.4k
  int64_t immr, imms, val;
3077
3078
17.4k
  immr = inst->operands[2].imm.value;
3079
17.4k
  imms = inst->operands[3].imm.value;
3080
17.4k
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
3081
17.4k
  if (imms < immr)
3082
17.4k
    {
3083
17.4k
      inst->operands[2].imm.value = (val - immr) & (val - 1);
3084
17.4k
      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
17.4k
      reset_operand_qualifier (inst, 2);
3088
17.4k
      reset_operand_qualifier (inst, 3);
3089
17.4k
      return 1;
3090
17.4k
    }
3091
3092
0
  return 0;
3093
17.4k
}
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
407
{
3103
407
  int64_t immr, imms, val;
3104
3105
  /* Should have been assured by the base opcode value.  */
3106
407
  assert (inst->operands[1].reg.regno == 0x1f);
3107
3108
407
  immr = inst->operands[2].imm.value;
3109
407
  imms = inst->operands[3].imm.value;
3110
407
  val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
3111
407
  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
245
  return 0;
3132
407
}
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.28k
{
3142
8.28k
  int64_t immr = inst->operands[2].imm.value;
3143
8.28k
  int64_t imms = inst->operands[3].imm.value;
3144
8.28k
  int64_t val
3145
8.28k
    = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
3146
3147
8.28k
  if ((immr == 0 && imms == val) || immr == imms + 1)
3148
220
    {
3149
220
      inst->operands[3].type = AARCH64_OPND_NIL;
3150
220
      inst->operands[2].imm.value = val - imms;
3151
220
      return 1;
3152
220
    }
3153
3154
8.06k
  return 0;
3155
8.28k
}
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.67k
{
3165
4.67k
  if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
3166
975
      && (inst->operands[3].cond->value & 0xe) != 0xe)
3167
298
    {
3168
298
      copy_operand_info (inst, 2, 3);
3169
298
      inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
3170
298
      inst->operands[3].type = AARCH64_OPND_NIL;
3171
298
      return 1;
3172
298
    }
3173
4.37k
  return 0;
3174
4.67k
}
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
950
{
3184
950
  if (inst->operands[1].reg.regno == 0x1f
3185
950
      && inst->operands[2].reg.regno == 0x1f
3186
950
      && (inst->operands[3].cond->value & 0xe) != 0xe)
3187
293
    {
3188
293
      copy_operand_info (inst, 1, 3);
3189
293
      inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
3190
293
      inst->operands[3].type = AARCH64_OPND_NIL;
3191
293
      inst->operands[2].type = AARCH64_OPND_NIL;
3192
293
      return 1;
3193
293
    }
3194
657
  return 0;
3195
950
}
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.9k
{
3210
65.9k
  uint64_t value = inst->operands[1].imm.value;
3211
  /* MOVZ/MOVN #0 have a shift amount other than LSL #0.  */
3212
65.9k
  if (value == 0 && inst->operands[1].shifter.amount != 0)
3213
279
    return 0;
3214
65.6k
  inst->operands[1].type = AARCH64_OPND_IMM_MOV;
3215
65.6k
  inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
3216
65.6k
  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.6k
  if (inst->opcode->op == OP_MOVN)
3220
30.1k
    {
3221
30.1k
      int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
3222
30.1k
      value = ~value;
3223
      /* A MOVN has an immediate that could be encoded by MOVZ.  */
3224
30.1k
      if (aarch64_wide_constant_p (value, is32, NULL))
3225
64
  return 0;
3226
30.1k
    }
3227
65.5k
  inst->operands[1].imm.value = value;
3228
65.5k
  inst->operands[1].shifter.amount = 0;
3229
65.5k
  return 1;
3230
65.6k
}
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.51k
{
3245
1.51k
  int is32;
3246
1.51k
  uint64_t value;
3247
3248
  /* Should have been assured by the base opcode value.  */
3249
1.51k
  assert (inst->operands[1].reg.regno == 0x1f);
3250
1.51k
  copy_operand_info (inst, 1, 2);
3251
1.51k
  is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
3252
1.51k
  inst->operands[1].type = AARCH64_OPND_IMM_MOV;
3253
1.51k
  value = inst->operands[1].imm.value;
3254
  /* ORR has an immediate that could be generated by a MOVZ or MOVN
3255
     instruction.  */
3256
1.51k
  if (inst->operands[0].reg.regno != 0x1f
3257
1.10k
      && (aarch64_wide_constant_p (value, is32, NULL)
3258
666
    || aarch64_wide_constant_p (~value, is32, NULL)))
3259
632
    return 0;
3260
3261
883
  inst->operands[2].type = AARCH64_OPND_NIL;
3262
883
  return 1;
3263
1.51k
}
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
163k
{
3271
163k
  switch (alias->op)
3272
163k
    {
3273
17.2k
    case OP_ASR_IMM:
3274
25.7k
    case OP_LSR_IMM:
3275
25.7k
      return convert_bfm_to_sr (inst);
3276
8.28k
    case OP_LSL_IMM:
3277
8.28k
      return convert_ubfm_to_lsl (inst);
3278
1.65k
    case OP_CINC:
3279
3.71k
    case OP_CINV:
3280
4.67k
    case OP_CNEG:
3281
4.67k
      return convert_from_csel (inst);
3282
293
    case OP_CSET:
3283
950
    case OP_CSETM:
3284
950
      return convert_csinc_to_cset (inst);
3285
8.06k
    case OP_UBFX:
3286
17.3k
    case OP_BFXIL:
3287
34.2k
    case OP_SBFX:
3288
34.2k
      return convert_bfm_to_bfx (inst);
3289
10.8k
    case OP_SBFIZ:
3290
13.9k
    case OP_BFI:
3291
17.4k
    case OP_UBFIZ:
3292
17.4k
      return convert_bfm_to_bfi (inst);
3293
407
    case OP_BFC:
3294
407
      return convert_bfm_to_bfc (inst);
3295
661
    case OP_MOV_V:
3296
661
      return convert_orr_to_mov (inst);
3297
35.5k
    case OP_MOV_IMM_WIDE:
3298
65.9k
    case OP_MOV_IMM_WIDEN:
3299
65.9k
      return convert_movewide_to_mov (inst);
3300
1.51k
    case OP_MOV_IMM_LOG:
3301
1.51k
      return convert_movebitmask_to_mov (inst);
3302
3.04k
    case OP_ROR_IMM:
3303
3.04k
      return convert_extr_to_ror (inst);
3304
75
    case OP_SXTL:
3305
133
    case OP_SXTL2:
3306
893
    case OP_UXTL:
3307
956
    case OP_UXTL2:
3308
956
      return convert_shll_to_xtl (inst);
3309
0
    default:
3310
0
      return 0;
3311
163k
    }
3312
163k
}
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.01M
{
3375
7.01M
  const aarch64_opcode *opcode;
3376
7.01M
  const aarch64_opcode *alias;
3377
3378
7.01M
  opcode = inst->opcode;
3379
3380
  /* This opcode does not have an alias, so use itself.  */
3381
7.01M
  if (!opcode_has_alias (opcode))
3382
6.14M
    return;
3383
3384
871k
  alias = aarch64_find_alias_opcode (opcode);
3385
871k
  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.78M
  for (; alias; alias = aarch64_find_next_alias_opcode (alias))
3402
1.78M
    {
3403
1.78M
      DEBUG_TRACE ("try %s", alias->name);
3404
1.78M
      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.78M
      if (pseudo_opcode_p (alias))
3410
161k
  {
3411
161k
    DEBUG_TRACE ("skip pseudo %s", alias->name);
3412
161k
    continue;
3413
161k
  }
3414
3415
1.62M
      if ((inst->value & alias->mask) != alias->opcode)
3416
650k
  {
3417
650k
    DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
3418
650k
    continue;
3419
650k
  }
3420
3421
973k
      if (!AARCH64_CPU_HAS_ALL_FEATURES (arch_variant, *alias->avariant))
3422
72
  {
3423
72
    DEBUG_TRACE ("skip %s: we're missing features", alias->name);
3424
72
    continue;
3425
72
  }
3426
3427
      /* No need to do any complicated transformation on operands, if the alias
3428
   opcode does not have any operand.  */
3429
972k
      if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
3430
252
  {
3431
252
    DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
3432
252
    aarch64_replace_opcode (inst, alias);
3433
252
    return;
3434
252
  }
3435
972k
      if (alias->flags & F_CONV)
3436
163k
  {
3437
163k
    aarch64_inst copy;
3438
163k
    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
163k
    if (convert_to_alias (&copy, alias) == 1)
3442
103k
      {
3443
103k
        aarch64_replace_opcode (&copy, alias);
3444
103k
        if (aarch64_match_operands_constraint (&copy, NULL) != 1)
3445
0
    {
3446
0
      DEBUG_TRACE ("FAILED with alias %s ", alias->name);
3447
0
    }
3448
103k
        else
3449
103k
    {
3450
103k
      DEBUG_TRACE ("succeed with %s via conversion", alias->name);
3451
103k
      memcpy (inst, &copy, sizeof (aarch64_inst));
3452
103k
    }
3453
103k
        return;
3454
103k
      }
3455
163k
  }
3456
808k
      else
3457
808k
  {
3458
    /* Directly decode the alias opcode.  */
3459
808k
    aarch64_inst temp;
3460
808k
    memset (&temp, '\0', sizeof (aarch64_inst));
3461
808k
    if (aarch64_opcode_decode (alias, inst->value, &temp, 1, errors) == 1)
3462
767k
      {
3463
767k
        DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
3464
767k
        memcpy (inst, &temp, sizeof (aarch64_inst));
3465
767k
        return;
3466
767k
      }
3467
808k
  }
3468
972k
    }
3469
871k
}
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.63M
{
3480
8.63M
  int i, variant;
3481
3482
8.63M
  variant = 0;
3483
8.63M
  switch (inst->opcode->iclass)
3484
8.63M
    {
3485
86.6k
    case sme_mov:
3486
86.6k
      variant = extract_fields (inst->value, 0, 2, FLD_SME_Q, FLD_SME_size_22);
3487
86.6k
      if (variant >= 4 && variant < 7)
3488
1.23k
  return false;
3489
85.4k
      if (variant == 7)
3490
692
  variant = 4;
3491
85.4k
      break;
3492
3493
10.3k
    case sme_psel:
3494
10.3k
      i = extract_fields (inst->value, 0, 2, FLD_SME_tszh, FLD_SME_tszl);
3495
10.3k
      if (i == 0)
3496
255
  return false;
3497
21.5k
      while ((i & 1) == 0)
3498
11.3k
  {
3499
11.3k
    i >>= 1;
3500
11.3k
    variant += 1;
3501
11.3k
  }
3502
10.1k
      break;
3503
3504
598
    case sme_shift:
3505
598
      i = extract_field (FLD_SVE_tszh, inst->value, 0);
3506
598
      goto sve_shift;
3507
3508
155
    case sme_size_12_bh:
3509
155
      variant = extract_field (FLD_S, inst->value, 0);
3510
155
      if (variant > 1)
3511
0
  return false;
3512
155
      break;
3513
3514
1.67k
    case sme_size_12_bhs:
3515
1.67k
      variant = extract_field (FLD_SME_size_12, inst->value, 0);
3516
1.67k
      if (variant >= 3)
3517
400
  return false;
3518
1.27k
      break;
3519
3520
1.27k
    case sme_size_12_hs:
3521
363
      variant = extract_field (FLD_SME_size_12, inst->value, 0);
3522
363
      if (variant != 1 && variant != 2)
3523
52
  return false;
3524
311
      variant -= 1;
3525
311
      break;
3526
3527
129
    case sme_size_12_b:
3528
129
      variant = extract_field (FLD_SME_size_12, inst->value, 0);
3529
129
      if (variant != 0)
3530
102
  return false;
3531
27
      break;
3532
3533
12.0k
    case sme_size_22:
3534
12.0k
      variant = extract_field (FLD_SME_size_22, inst->value, 0);
3535
12.0k
      break;
3536
3537
3.12k
    case sme_size_22_hsd:
3538
3.12k
      variant = extract_field (FLD_SME_size_22, inst->value, 0);
3539
3.12k
      if (variant < 1)
3540
841
  return false;
3541
2.28k
      variant -= 1;
3542
2.28k
      break;
3543
3544
177
    case sme_sz_23:
3545
177
      variant = extract_field (FLD_SME_sz_23, inst->value, 0);
3546
177
      break;
3547
3548
17.0k
    case sve_cpy:
3549
17.0k
      variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_14);
3550
17.0k
      break;
3551
3552
4.52k
    case sve_index:
3553
4.52k
      i = extract_field (FLD_imm5, inst->value, 0);
3554
3555
4.52k
      if ((i & 31) == 0)
3556
346
  return false;
3557
10.5k
      while ((i & 1) == 0)
3558
6.33k
  {
3559
6.33k
    i >>= 1;
3560
6.33k
    variant += 1;
3561
6.33k
  }
3562
4.18k
      break;
3563
3564
49.5k
    case sve_limm:
3565
      /* Pick the smallest applicable element size.  */
3566
49.5k
      if ((inst->value & 0x20600) == 0x600)
3567
8.91k
  variant = 0;
3568
40.5k
      else if ((inst->value & 0x20400) == 0x400)
3569
4.37k
  variant = 1;
3570
36.2k
      else if ((inst->value & 0x20000) == 0)
3571
31.6k
  variant = 2;
3572
4.52k
      else
3573
4.52k
  variant = 3;
3574
49.5k
      break;
3575
3576
1.05k
    case sme2_mov:
3577
      /* .D is preferred over the other sizes in disassembly.  */
3578
1.05k
      variant = 3;
3579
1.05k
      break;
3580
3581
144k
    case sme_misc:
3582
604k
    case sve_misc:
3583
      /* These instructions have only a single variant.  */
3584
604k
      break;
3585
3586
3.60k
    case sve_movprfx:
3587
3.60k
      variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_16);
3588
3.60k
      break;
3589
3590
182
    case sve_pred_zm:
3591
182
      variant = extract_field (FLD_SVE_M_4, inst->value, 0);
3592
182
      break;
3593
3594
4.88k
    case sve_shift_pred:
3595
4.88k
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_8);
3596
6.92k
    sve_shift:
3597
6.92k
      if (i == 0)
3598
2.48k
  return false;
3599
11.7k
      while (i != 1)
3600
7.35k
  {
3601
7.35k
    i >>= 1;
3602
7.35k
    variant += 1;
3603
7.35k
  }
3604
4.43k
      break;
3605
3606
1.44k
    case sve_shift_unpred:
3607
1.44k
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
3608
1.44k
      goto sve_shift;
3609
3610
14.9k
    case sve_size_bhs:
3611
14.9k
      variant = extract_field (FLD_size, inst->value, 0);
3612
14.9k
      if (variant >= 3)
3613
2.94k
  return false;
3614
11.9k
      break;
3615
3616
187k
    case sve_size_bhsd:
3617
187k
      variant = extract_field (FLD_size, inst->value, 0);
3618
187k
      break;
3619
3620
193k
    case sve_size_hsd:
3621
193k
      i = extract_field (FLD_size, inst->value, 0);
3622
193k
      if (i < 1)
3623
43.1k
  return false;
3624
150k
      variant = i - 1;
3625
150k
      break;
3626
3627
567
    case sme_fp_sd:
3628
5.29k
    case sme_int_sd:
3629
6.43k
    case sve_size_bh:
3630
13.1k
    case sve_size_sd:
3631
13.1k
      variant = extract_field (FLD_SVE_sz, inst->value, 0);
3632
13.1k
      break;
3633
3634
7.74k
    case sve_size_sd2:
3635
7.74k
      variant = extract_field (FLD_SVE_sz2, inst->value, 0);
3636
7.74k
      break;
3637
3638
729
    case sve_size_sd3:
3639
729
      variant = extract_field (FLD_SVE_sz3, inst->value, 0);
3640
729
      break;
3641
3642
161
    case sve_size_sd4:
3643
161
      variant = extract_field (FLD_SVE_sz4, inst->value, 0);
3644
161
      break;
3645
3646
151
    case sve_size_hsd2:
3647
151
      i = extract_field (FLD_SVE_size, inst->value, 0);
3648
151
      if (i < 1)
3649
97
  return false;
3650
54
      variant = i - 1;
3651
54
      break;
3652
3653
199
    case sve_size_hsd3:
3654
199
      i = extract_field (FLD_len, inst->value, 0);
3655
199
      if (i < 1)
3656
33
  return false;
3657
166
      variant = i - 1;
3658
166
      break;
3659
3660
1.53k
    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.53k
      i = (extract_field (FLD_size, inst->value, 0) & 2);
3664
1.53k
      variant = (i >> 1);
3665
1.53k
      break;
3666
3667
2.82k
    case sve_shift_tsz_bhsd:
3668
2.82k
      i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
3669
2.82k
      if (i == 0)
3670
613
  return false;
3671
5.35k
      while (i != 1)
3672
3.15k
  {
3673
3.15k
    i >>= 1;
3674
3.15k
    variant += 1;
3675
3.15k
  }
3676
2.20k
      break;
3677
3678
887
    case sve_size_tsz_bhs:
3679
887
      i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
3680
887
      if (i == 0)
3681
260
  return false;
3682
1.09k
      while (i != 1)
3683
533
  {
3684
533
    if (i & 1)
3685
61
      return false;
3686
472
    i >>= 1;
3687
472
    variant += 1;
3688
472
  }
3689
566
      break;
3690
3691
7.43k
    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.43k
      i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
3695
7.43k
      if (i == 0)
3696
1.51k
  return false;
3697
14.7k
      while (i != 1)
3698
8.80k
  {
3699
8.80k
    i >>= 1;
3700
8.80k
    variant += 1;
3701
8.80k
  }
3702
5.92k
      break;
3703
3704
7.40M
    default:
3705
      /* No mapping between instruction class and qualifiers.  */
3706
7.40M
      return true;
3707
8.63M
    }
3708
3709
9.43M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3710
8.25M
    inst->operands[i].qualifier = inst->opcode->qualifiers_list[variant][i];
3711
1.17M
  return true;
3712
8.63M
}
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.2M
{
3726
20.2M
  int i;
3727
3728
20.2M
  DEBUG_TRACE ("enter with %s", opcode->name);
3729
3730
20.2M
  assert (opcode && inst);
3731
3732
  /* Clear inst.  */
3733
20.2M
  memset (inst, '\0', sizeof (aarch64_inst));
3734
3735
  /* Check the base opcode.  */
3736
20.2M
  if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
3737
11.4M
    {
3738
11.4M
      DEBUG_TRACE ("base opcode match FAIL");
3739
11.4M
      goto decode_fail;
3740
11.4M
    }
3741
3742
8.77M
  inst->opcode = opcode;
3743
8.77M
  inst->value = code;
3744
3745
  /* Assign operand codes and indexes, and set qualifiers to UNKNOWN.  */
3746
29.7M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3747
29.7M
    {
3748
29.7M
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3749
8.77M
  break;
3750
20.9M
      inst->operands[i].type = opcode->operands[i];
3751
20.9M
      inst->operands[i].idx = i;
3752
20.9M
      inst->operands[i].qualifier = AARCH64_OPND_QLF_UNKNOWN;
3753
20.9M
    }
3754
3755
  /* Call the opcode decoder indicated by flags.  */
3756
8.77M
  if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
3757
138k
    {
3758
138k
      DEBUG_TRACE ("opcode flag-based decoder FAIL");
3759
138k
      goto decode_fail;
3760
138k
    }
3761
3762
  /* Possibly use the instruction class to determine the correct
3763
     qualifier.  */
3764
8.63M
  if (!aarch64_decode_variant_using_iclass (inst))
3765
54.3k
    {
3766
54.3k
      DEBUG_TRACE ("iclass-based decoder FAIL");
3767
54.3k
      goto decode_fail;
3768
54.3k
    }
3769
3770
  /* Call operand decoders.  */
3771
27.9M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3772
27.9M
    {
3773
27.9M
      const aarch64_operand *opnd;
3774
27.9M
      enum aarch64_opnd type;
3775
3776
27.9M
      type = opcode->operands[i];
3777
27.9M
      if (type == AARCH64_OPND_NIL)
3778
8.02M
  break;
3779
19.9M
      opnd = &aarch64_operands[type];
3780
19.9M
      if (operand_has_extractor (opnd)
3781
19.9M
    && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst,
3782
19.9M
           errors)))
3783
554k
  {
3784
554k
    DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
3785
554k
    goto decode_fail;
3786
554k
  }
3787
19.9M
    }
3788
3789
  /* If the opcode has a verifier, then check it now.  */
3790
8.02M
  if (opcode->verifier
3791
67.7k
      && opcode->verifier (inst, code, 0, false, errors, NULL) != ERR_OK)
3792
9.44k
    {
3793
9.44k
      DEBUG_TRACE ("operand verifier FAIL");
3794
9.44k
      goto decode_fail;
3795
9.44k
    }
3796
3797
  /* Match the qualifiers.  */
3798
8.01M
  if (aarch64_match_operands_constraint (inst, NULL) == 1)
3799
7.77M
    {
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.77M
      if (!noaliases_p)
3806
7.01M
  determine_disassembling_preference (inst, errors);
3807
7.77M
      DEBUG_TRACE ("SUCCESS");
3808
7.77M
      return true;
3809
7.77M
    }
3810
238k
  else
3811
238k
    {
3812
238k
      DEBUG_TRACE ("constraint matching FAIL");
3813
238k
    }
3814
3815
12.4M
 decode_fail:
3816
12.4M
  return false;
3817
8.01M
}
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.01M
{
3826
7.01M
  switch (inst->opcode->iclass)
3827
7.01M
    {
3828
163k
    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
163k
      if (inst->operands[1].imm.value < 32)
3836
104k
  inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
3837
163k
      break;
3838
6.84M
    default: break;
3839
7.01M
    }
3840
7.01M
}
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
16.7M
{
3851
16.7M
  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.1M
  while (opcode != NULL)
3873
19.3M
    {
3874
      /* But only one opcode can be decoded successfully for, as the
3875
   decoding routine will check the constraint carefully.  */
3876
19.3M
      if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p, errors) == 1)
3877
7.01M
  return ERR_OK;
3878
12.3M
      opcode = aarch64_find_next_opcode (opcode);
3879
12.3M
    }
3880
3881
9.75M
  return ERR_UND;
3882
16.7M
}
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.0M
{
3892
38.0M
  static bool init = false;
3893
38.0M
  static char formats[16][4];
3894
38.0M
  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.0M
  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.0M
  num = (unsigned) style;
3916
38.0M
  assert (style <= 0xf);
3917
38.0M
  return formats[num];
3918
38.0M
}
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.0M
{
3940
19.0M
  int res;
3941
19.0M
  char *ptr, *tmp;
3942
19.0M
  struct obstack *stack = (struct obstack *) styler->state;
3943
19.0M
  va_list ap;
3944
3945
  /* These are the two strings for switching styles.  */
3946
19.0M
  const char *style_on = get_style_text (style);
3947
19.0M
  const char *style_off = get_style_text (dis_style_text);
3948
3949
  /* Calculate space needed once FMT and ARGS are expanded.  */
3950
19.0M
  va_copy (ap, args);
3951
19.0M
  res = vsnprintf (NULL, 0, fmt, ap);
3952
19.0M
  va_end (ap);
3953
19.0M
  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.0M
  ptr = (char *) obstack_alloc (stack, res + strlen (style_on)
3959
19.0M
        + strlen (style_off) + 1);
3960
19.0M
  tmp = stpcpy (ptr, style_on);
3961
19.0M
  res = vsnprintf (tmp, (res + 1), fmt, args);
3962
19.0M
  assert (res >= 0);
3963
19.0M
  tmp += res;
3964
19.0M
  strcpy (tmp, style_off);
3965
3966
19.0M
  return ptr;
3967
19.0M
}
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.01M
{
3976
7.01M
  char *notes = NULL;
3977
7.01M
  int i, pcrel_p, num_printed;
3978
7.01M
  struct aarch64_styler styler;
3979
7.01M
  struct obstack content;
3980
7.01M
  obstack_init (&content);
3981
3982
7.01M
  styler.apply_style = aarch64_apply_style;
3983
7.01M
  styler.state = (void *) &content;
3984
3985
22.6M
  for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3986
22.6M
    {
3987
22.6M
      char str[128];
3988
22.6M
      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
22.6M
      if (opcode->operands[i] == AARCH64_OPND_NIL
3996
15.6M
    || opnds[i].type == AARCH64_OPND_NIL)
3997
7.01M
  break;
3998
3999
      /* Generate the operand string in STR.  */
4000
15.6M
      aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
4001
15.6M
           &info->target, &notes, cmt, sizeof (cmt),
4002
15.6M
           arch_variant, &styler);
4003
4004
      /* Print the delimiter (taking account of omitted operand(s)).  */
4005
15.6M
      if (str[0] != '\0')
4006
15.6M
  (*info->fprintf_styled_func) (info->stream, dis_style_text, "%s",
4007
15.6M
              num_printed++ == 0 ? "\t" : ", ");
4008
4009
      /* Print the operand.  */
4010
15.6M
      if (pcrel_p)
4011
1.45M
  (*info->print_address_func) (info->target, info);
4012
14.2M
      else
4013
14.2M
  {
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.2M
    char *start, *curr;
4020
14.2M
    enum disassembler_style curr_style = dis_style_text;
4021
4022
14.2M
    start = curr = str;
4023
14.2M
    do
4024
121M
      {
4025
121M
        if (*curr == '\0'
4026
106M
      || (*curr == STYLE_MARKER_CHAR
4027
106M
          && ISXDIGIT (*(curr + 1))
4028
35.1M
          && *(curr + 2) == STYLE_MARKER_CHAR))
4029
49.3M
    {
4030
      /* Output content between our START position and CURR.  */
4031
49.3M
      int len = curr - start;
4032
49.3M
      if (len > 0)
4033
25.3M
        {
4034
25.3M
          if ((*info->fprintf_styled_func) (info->stream,
4035
25.3M
              curr_style,
4036
25.3M
              "%.*s",
4037
25.3M
              len, start) < 0)
4038
0
      break;
4039
25.3M
        }
4040
4041
49.3M
      if (*curr == '\0')
4042
14.2M
        break;
4043
4044
      /* Skip over the initial STYLE_MARKER_CHAR.  */
4045
35.1M
      ++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.1M
      if (*curr >= '0' && *curr <= '9')
4053
35.1M
        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.1M
      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.1M
      curr += 2;
4067
4068
      /* Reset the START to after the style marker.  */
4069
35.1M
      start = curr;
4070
35.1M
    }
4071
71.6M
        else
4072
71.6M
    ++curr;
4073
121M
      }
4074
14.2M
    while (true);
4075
14.2M
  }
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.6M
      if (cmt[0] != '\0')
4081
80.2k
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
4082
80.2k
              "\t// %s", cmt);
4083
15.6M
    }
4084
4085
7.01M
    if (notes && !no_notes)
4086
211
      {
4087
211
  *has_notes = true;
4088
211
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
4089
211
              "  // note: %s", notes);
4090
211
      }
4091
4092
7.01M
    obstack_free (&content, NULL);
4093
7.01M
}
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
83.2k
{
4100
83.2k
  const char *ptr;
4101
83.2k
  size_t len;
4102
4103
83.2k
  ptr = strchr (inst->opcode->name, '.');
4104
83.2k
  assert (ptr && inst->cond);
4105
83.2k
  len = ptr - inst->opcode->name;
4106
83.2k
  assert (len < 8);
4107
83.2k
  strncpy (name, inst->opcode->name, len);
4108
83.2k
  name[len] = '\0';
4109
83.2k
}
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.01M
{
4116
7.01M
  if (inst->opcode->flags & F_COND)
4117
41.6k
    {
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
41.6k
      char name[8];
4122
4123
41.6k
      remove_dot_suffix (name, inst);
4124
41.6k
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
4125
41.6k
            "%s.%s", name, inst->cond->names[0]);
4126
41.6k
    }
4127
6.96M
  else
4128
6.96M
    (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
4129
6.96M
          "%s", inst->opcode->name);
4130
7.01M
}
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.01M
{
4138
7.01M
  if (inst->opcode->flags & F_COND)
4139
41.6k
    {
4140
41.6k
      char name[8];
4141
41.6k
      unsigned int i, num_conds;
4142
4143
41.6k
      remove_dot_suffix (name, inst);
4144
41.6k
      num_conds = ARRAY_SIZE (inst->cond->names);
4145
77.9k
      for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
4146
36.3k
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
4147
36.3k
              "%s %s.%s",
4148
36.3k
              i == 1 ? "  //" : ",",
4149
36.3k
              name, inst->cond->names[i]);
4150
41.6k
    }
4151
7.01M
}
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
12.7k
{
4159
12.7k
  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
12.7k
  assert (detail->non_fatal);
4165
4166
12.7k
  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
4167
12.7k
        "  // note: ");
4168
12.7k
  switch (detail->kind)
4169
12.7k
    {
4170
3.75k
    case AARCH64_OPDE_A_SHOULD_FOLLOW_B:
4171
3.75k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
4172
3.75k
            _("this `%s' should have an immediately"
4173
3.75k
              " preceding `%s'"),
4174
3.75k
            detail->data[0].s, detail->data[1].s);
4175
3.75k
      break;
4176
4177
4.21k
    case AARCH64_OPDE_EXPECTED_A_AFTER_B:
4178
4.21k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
4179
4.21k
            _("expected `%s' after previous `%s'"),
4180
4.21k
            detail->data[0].s, detail->data[1].s);
4181
4.21k
      break;
4182
4183
4.76k
    default:
4184
4.76k
      assert (detail->error);
4185
4.76k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
4186
4.76k
            "%s", detail->error);
4187
4.76k
      if (detail->index >= 0)
4188
1.23k
  (*info->fprintf_styled_func) (info->stream, dis_style_text,
4189
1.23k
              " at operand %d", detail->index + 1);
4190
4.76k
      break;
4191
12.7k
    }
4192
12.7k
}
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.01M
{
4202
7.01M
  bool has_notes = false;
4203
4204
7.01M
  print_mnemonic_name (inst, info);
4205
7.01M
  print_operands (pc, inst->opcode, inst->operands, info, &has_notes);
4206
7.01M
  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.01M
  if (has_notes)
4212
211
    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.01M
  enum err_type result = verify_constraints (inst, code, pc, false,
4218
7.01M
               mismatch_details, &insn_sequence);
4219
7.01M
  switch (result)
4220
7.01M
    {
4221
12.7k
    case ERR_VFI:
4222
12.7k
      print_verifier_notes (mismatch_details, info);
4223
12.7k
      break;
4224
0
    case ERR_UND:
4225
0
    case ERR_UNP:
4226
6.99M
    default:
4227
6.99M
      break;
4228
7.01M
    }
4229
7.01M
}
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
16.7M
{
4239
16.7M
  static const char *err_msg[ERR_NR_ENTRIES+1] =
4240
16.7M
    {
4241
16.7M
      [ERR_OK]  = "_",
4242
16.7M
      [ERR_UND] = "undefined",
4243
16.7M
      [ERR_UNP] = "unpredictable",
4244
16.7M
    };
4245
4246
16.7M
  enum err_type ret;
4247
16.7M
  aarch64_inst inst;
4248
4249
16.7M
  info->insn_info_valid = 1;
4250
16.7M
  info->branch_delay_insns = 0;
4251
16.7M
  info->data_size = 0;
4252
16.7M
  info->target = 0;
4253
16.7M
  info->target2 = 0;
4254
4255
16.7M
  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
16.7M
  ret = aarch64_decode_insn (word, &inst, no_aliases, errors);
4264
4265
16.7M
  switch (ret)
4266
16.7M
    {
4267
9.75M
    case ERR_UND:
4268
9.75M
    case ERR_UNP:
4269
      /* Handle undefined instructions.  */
4270
9.75M
      info->insn_type = dis_noninsn;
4271
9.75M
      (*info->fprintf_styled_func) (info->stream,
4272
9.75M
            dis_style_assembler_directive,
4273
9.75M
            ".inst\t");
4274
9.75M
      (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
4275
9.75M
            "0x%08x", word);
4276
9.75M
      asymbol * sym = NULL;
4277
      /* See if this "instruction" is actually the address of something.  */
4278
9.75M
      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.75M
      if (sym == NULL)
4292
9.75M
  info->fprintf_styled_func (info->stream, dis_style_comment_start,
4293
9.75M
           " ; %s", err_msg[ret]);
4294
9.75M
      break;
4295
7.01M
    case ERR_OK:
4296
7.01M
      user_friendly_fixup (&inst);
4297
7.01M
      if (inst.opcode->iclass == condbranch
4298
6.96M
    || inst.opcode->iclass == testbranch
4299
6.80M
    || inst.opcode->iclass == compbranch)
4300
455k
        info->insn_type = dis_condbranch;
4301
6.55M
      else if (inst.opcode->iclass == branch_imm)
4302
270k
        info->insn_type = dis_jsr;
4303
7.01M
      print_aarch64_insn (pc, &inst, word, info, errors);
4304
7.01M
      break;
4305
0
    default:
4306
0
      abort ();
4307
16.7M
    }
4308
16.7M
}
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
42
{
4317
42
  const char * name;
4318
4319
42
  if (sym == NULL)
4320
0
    return false;
4321
4322
42
  name = bfd_asymbol_name (sym);
4323
4324
42
  return name
4325
42
    && (name[0] != '$'
4326
0
  || (name[1] != 'x' && name[1] != 'd')
4327
0
  || (name[2] != '\0' && name[2] != '.'));
4328
42
}
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
887
{
4370
887
  asymbol * as;
4371
887
  elf_symbol_type *es;
4372
887
  unsigned int type;
4373
887
  const char *name;
4374
4375
  /* If the symbol is in a different section, ignore it.  */
4376
887
  if (info->section != NULL && info->section != info->symtab[n]->section)
4377
810
    return false;
4378
4379
77
  if (n >= info->symtab_size)
4380
0
    return false;
4381
4382
77
  as = info->symtab[n];
4383
77
  if (bfd_asymbol_flavour (as) != bfd_target_elf_flavour)
4384
0
    return false;
4385
77
  es = (elf_symbol_type *) as;
4386
4387
77
  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4388
4389
  /* If the symbol has function type then use that.  */
4390
77
  if (type == STT_FUNC)
4391
75
    {
4392
75
      *map_type = MAP_INSN;
4393
75
      return true;
4394
75
    }
4395
4396
  /* Check for mapping symbols.  */
4397
2
  name = bfd_asymbol_name(info->symtab[n]);
4398
2
  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
2
  return false;
4407
2
}
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
16.7M
{
4434
16.7M
  bfd_byte  buffer[INSNLEN];
4435
16.7M
  int   status;
4436
16.7M
  void    (*printer) (bfd_vma, uint32_t, struct disassemble_info *,
4437
16.7M
          aarch64_operand_error *);
4438
16.7M
  bool   found = false;
4439
16.7M
  unsigned int  size = 4;
4440
16.7M
  unsigned long data;
4441
16.7M
  aarch64_operand_error errors;
4442
16.7M
  static bool set_features;
4443
4444
16.7M
  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
16.7M
  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
16.7M
  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
16.7M
  enum map_type type = MAP_DATA;
4472
16.7M
  if ((info->section && info->section->flags & SEC_CODE) || !info->section)
4473
12.5M
    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
16.7M
  if (info->symtab_size != 0
4478
979
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4479
979
    {
4480
979
      int last_sym = -1;
4481
979
      bfd_vma addr, section_vma = 0;
4482
979
      bool can_use_search_opt_p;
4483
979
      int n;
4484
4485
979
      if (pc <= last_mapping_addr)
4486
60
  last_mapping_sym = -1;
4487
4488
      /* Start scanning at the start of the function, or wherever
4489
   we finished last time.  */
4490
979
      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
979
      can_use_search_opt_p = last_mapping_sym >= 0
4496
26
           && info->stop_offset == last_stop_offset;
4497
4498
979
      if (n >= last_mapping_sym && can_use_search_opt_p)
4499
6
  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
1.85k
      for (; n < info->symtab_size; n++)
4506
1.51k
  {
4507
1.51k
    addr = bfd_asymbol_value (info->symtab[n]);
4508
1.51k
    if (addr > pc)
4509
630
      break;
4510
880
    if (get_sym_code_type (info, n, &type))
4511
70
      {
4512
70
        last_sym = n;
4513
70
        found = true;
4514
70
      }
4515
880
  }
4516
4517
979
      if (!found)
4518
951
  {
4519
951
    n = info->symtab_pos;
4520
951
    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
951
    if (info->section)
4530
951
      section_vma = info->section->vma;
4531
4532
953
    for (; n >= 0; n--)
4533
7
      {
4534
7
        addr = bfd_asymbol_value (info->symtab[n]);
4535
7
        if (addr < section_vma)
4536
0
    break;
4537
4538
7
        if (get_sym_code_type (info, n, &type))
4539
5
    {
4540
5
      last_sym = n;
4541
5
      found = true;
4542
5
      break;
4543
5
    }
4544
7
      }
4545
951
  }
4546
4547
979
      last_mapping_sym = last_sym;
4548
979
      last_type = type;
4549
979
      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
979
      if (last_type == MAP_DATA)
4556
895
  {
4557
895
    size = 4 - (pc & 3);
4558
1.70k
    for (n = last_sym + 1; n < info->symtab_size; n++)
4559
1.38k
      {
4560
1.38k
        addr = bfd_asymbol_value (info->symtab[n]);
4561
1.38k
        if (addr > pc)
4562
573
    {
4563
573
      if (addr - pc < size)
4564
8
        size = addr - pc;
4565
573
      break;
4566
573
    }
4567
1.38k
      }
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
895
    if (size == 3)
4572
0
      size = (pc & 1) ? 1 : 2;
4573
895
  }
4574
979
    }
4575
16.7M
  else
4576
16.7M
    last_type = type;
4577
4578
  /* PR 10263: Disassemble data if requested to do so by the user.  */
4579
16.7M
  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
16.7M
  else
4587
16.7M
    {
4588
16.7M
      info->bytes_per_chunk = size = INSNLEN;
4589
16.7M
      info->display_endian = info->endian_code;
4590
16.7M
      printer = print_insn_aarch64_word;
4591
16.7M
    }
4592
4593
16.7M
  status = (*info->read_memory_func) (pc, buffer, size, info);
4594
16.7M
  if (status != 0)
4595
20.4k
    {
4596
20.4k
      (*info->memory_error_func) (status, pc, info);
4597
20.4k
      return -1;
4598
20.4k
    }
4599
4600
16.7M
  data = bfd_get_bits (buffer, size * 8,
4601
16.7M
           info->display_endian == BFD_ENDIAN_BIG);
4602
4603
16.7M
  (*printer) (pc, data, info, &errors);
4604
4605
16.7M
  return size;
4606
16.7M
}
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
}