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