Coverage Report

Created: 2026-03-10 08:46

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