Fix ARI warning in gdb/arch/arm-get-next-pcs.c
[binutils-gdb.git] / opcodes / aarch64-dis.c
blob647ce0d0ba99ec3ba87c49e28600ef4e7aef2534
1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of the GNU opcodes library.
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.
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.
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/>. */
21 #include "sysdep.h"
22 #include "bfd_stdint.h"
23 #include "dis-asm.h"
24 #include "libiberty.h"
25 #include "opintl.h"
26 #include "aarch64-dis.h"
27 #include "elf-bfd.h"
29 #define ERR_OK 0
30 #define ERR_UND -1
31 #define ERR_UNP -3
32 #define ERR_NYI -5
34 #define INSNLEN 4
36 /* Cached mapping symbol state. */
37 enum map_type
39 MAP_INSN,
40 MAP_DATA
43 static enum map_type last_type;
44 static int last_mapping_sym = -1;
45 static bfd_vma last_mapping_addr = 0;
47 /* Other options */
48 static int no_aliases = 0; /* If set disassemble as most general inst. */
51 static void
52 set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
56 static void
57 parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
59 /* Try to match options that are simple flags */
60 if (CONST_STRNEQ (option, "no-aliases"))
62 no_aliases = 1;
63 return;
66 if (CONST_STRNEQ (option, "aliases"))
68 no_aliases = 0;
69 return;
72 #ifdef DEBUG_AARCH64
73 if (CONST_STRNEQ (option, "debug_dump"))
75 debug_dump = 1;
76 return;
78 #endif /* DEBUG_AARCH64 */
80 /* Invalid option. */
81 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
84 static void
85 parse_aarch64_dis_options (const char *options)
87 const char *option_end;
89 if (options == NULL)
90 return;
92 while (*options != '\0')
94 /* Skip empty options. */
95 if (*options == ',')
97 options++;
98 continue;
101 /* We know that *options is neither NUL or a comma. */
102 option_end = options + 1;
103 while (*option_end != ',' && *option_end != '\0')
104 option_end++;
106 parse_aarch64_dis_option (options, option_end - options);
108 /* Go on to the next one. If option_end points to a comma, it
109 will be skipped above. */
110 options = option_end;
114 /* Functions doing the instruction disassembling. */
116 /* The unnamed arguments consist of the number of fields and information about
117 these fields where the VALUE will be extracted from CODE and returned.
118 MASK can be zero or the base mask of the opcode.
120 N.B. the fields are required to be in such an order than the most signficant
121 field for VALUE comes the first, e.g. the <index> in
122 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
123 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
124 the order of H, L, M. */
126 static inline aarch64_insn
127 extract_fields (aarch64_insn code, aarch64_insn mask, ...)
129 uint32_t num;
130 const aarch64_field *field;
131 enum aarch64_field_kind kind;
132 va_list va;
134 va_start (va, mask);
135 num = va_arg (va, uint32_t);
136 assert (num <= 5);
137 aarch64_insn value = 0x0;
138 while (num--)
140 kind = va_arg (va, enum aarch64_field_kind);
141 field = &fields[kind];
142 value <<= field->width;
143 value |= extract_field (kind, code, mask);
145 return value;
148 /* Sign-extend bit I of VALUE. */
149 static inline int32_t
150 sign_extend (aarch64_insn value, unsigned i)
152 uint32_t ret = value;
154 assert (i < 32);
155 if ((value >> i) & 0x1)
157 uint32_t val = (uint32_t)(-1) << i;
158 ret = ret | val;
160 return (int32_t) ret;
163 /* N.B. the following inline helpfer functions create a dependency on the
164 order of operand qualifier enumerators. */
166 /* Given VALUE, return qualifier for a general purpose register. */
167 static inline enum aarch64_opnd_qualifier
168 get_greg_qualifier_from_value (aarch64_insn value)
170 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
171 assert (value <= 0x1
172 && aarch64_get_qualifier_standard_value (qualifier) == value);
173 return qualifier;
176 /* Given VALUE, return qualifier for a vector register. This does not support
177 decoding instructions that accept the 2H vector type. */
179 static inline enum aarch64_opnd_qualifier
180 get_vreg_qualifier_from_value (aarch64_insn value)
182 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
184 /* Instructions using vector type 2H should not call this function. Skip over
185 the 2H qualifier. */
186 if (qualifier >= AARCH64_OPND_QLF_V_2H)
187 qualifier += 1;
189 assert (value <= 0x8
190 && aarch64_get_qualifier_standard_value (qualifier) == value);
191 return qualifier;
194 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
195 static inline enum aarch64_opnd_qualifier
196 get_sreg_qualifier_from_value (aarch64_insn value)
198 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
200 assert (value <= 0x4
201 && aarch64_get_qualifier_standard_value (qualifier) == value);
202 return qualifier;
205 /* Given the instruction in *INST which is probably half way through the
206 decoding and our caller wants to know the expected qualifier for operand
207 I. Return such a qualifier if we can establish it; otherwise return
208 AARCH64_OPND_QLF_NIL. */
210 static aarch64_opnd_qualifier_t
211 get_expected_qualifier (const aarch64_inst *inst, int i)
213 aarch64_opnd_qualifier_seq_t qualifiers;
214 /* Should not be called if the qualifier is known. */
215 assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
216 if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
217 i, qualifiers))
218 return qualifiers[i];
219 else
220 return AARCH64_OPND_QLF_NIL;
223 /* Operand extractors. */
226 aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
227 const aarch64_insn code,
228 const aarch64_inst *inst ATTRIBUTE_UNUSED)
230 info->reg.regno = extract_field (self->fields[0], code, 0);
231 return 1;
235 aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
236 const aarch64_insn code ATTRIBUTE_UNUSED,
237 const aarch64_inst *inst ATTRIBUTE_UNUSED)
239 assert (info->idx == 1
240 || info->idx ==3);
241 info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
242 return 1;
245 /* e.g. IC <ic_op>{, <Xt>}. */
247 aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
248 const aarch64_insn code,
249 const aarch64_inst *inst ATTRIBUTE_UNUSED)
251 info->reg.regno = extract_field (self->fields[0], code, 0);
252 assert (info->idx == 1
253 && (aarch64_get_operand_class (inst->operands[0].type)
254 == AARCH64_OPND_CLASS_SYSTEM));
255 /* This will make the constraint checking happy and more importantly will
256 help the disassembler determine whether this operand is optional or
257 not. */
258 info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
260 return 1;
263 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
265 aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
266 const aarch64_insn code,
267 const aarch64_inst *inst ATTRIBUTE_UNUSED)
269 /* regno */
270 info->reglane.regno = extract_field (self->fields[0], code,
271 inst->opcode->mask);
273 /* Index and/or type. */
274 if (inst->opcode->iclass == asisdone
275 || inst->opcode->iclass == asimdins)
277 if (info->type == AARCH64_OPND_En
278 && inst->opcode->operands[0] == AARCH64_OPND_Ed)
280 unsigned shift;
281 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
282 assert (info->idx == 1); /* Vn */
283 aarch64_insn value = extract_field (FLD_imm4, code, 0);
284 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
285 info->qualifier = get_expected_qualifier (inst, info->idx);
286 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
287 info->reglane.index = value >> shift;
289 else
291 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
292 imm5<3:0> <V>
293 0000 RESERVED
294 xxx1 B
295 xx10 H
296 x100 S
297 1000 D */
298 int pos = -1;
299 aarch64_insn value = extract_field (FLD_imm5, code, 0);
300 while (++pos <= 3 && (value & 0x1) == 0)
301 value >>= 1;
302 if (pos > 3)
303 return 0;
304 info->qualifier = get_sreg_qualifier_from_value (pos);
305 info->reglane.index = (unsigned) (value >> 1);
308 else
310 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
311 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
313 /* Need information in other operand(s) to help decoding. */
314 info->qualifier = get_expected_qualifier (inst, info->idx);
315 switch (info->qualifier)
317 case AARCH64_OPND_QLF_S_H:
318 /* h:l:m */
319 info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
320 FLD_M);
321 info->reglane.regno &= 0xf;
322 break;
323 case AARCH64_OPND_QLF_S_S:
324 /* h:l */
325 info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
326 break;
327 case AARCH64_OPND_QLF_S_D:
328 /* H */
329 info->reglane.index = extract_field (FLD_H, code, 0);
330 break;
331 default:
332 return 0;
336 return 1;
340 aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
341 const aarch64_insn code,
342 const aarch64_inst *inst ATTRIBUTE_UNUSED)
344 /* R */
345 info->reglist.first_regno = extract_field (self->fields[0], code, 0);
346 /* len */
347 info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
348 return 1;
351 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
353 aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
354 aarch64_opnd_info *info, const aarch64_insn code,
355 const aarch64_inst *inst)
357 aarch64_insn value;
358 /* Number of elements in each structure to be loaded/stored. */
359 unsigned expected_num = get_opcode_dependent_value (inst->opcode);
361 struct
363 unsigned is_reserved;
364 unsigned num_regs;
365 unsigned num_elements;
366 } data [] =
367 { {0, 4, 4},
368 {1, 4, 4},
369 {0, 4, 1},
370 {0, 4, 2},
371 {0, 3, 3},
372 {1, 3, 3},
373 {0, 3, 1},
374 {0, 1, 1},
375 {0, 2, 2},
376 {1, 2, 2},
377 {0, 2, 1},
380 /* Rt */
381 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
382 /* opcode */
383 value = extract_field (FLD_opcode, code, 0);
384 if (expected_num != data[value].num_elements || data[value].is_reserved)
385 return 0;
386 info->reglist.num_regs = data[value].num_regs;
388 return 1;
391 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
392 lanes instructions. */
394 aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
395 aarch64_opnd_info *info, const aarch64_insn code,
396 const aarch64_inst *inst)
398 aarch64_insn value;
400 /* Rt */
401 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
402 /* S */
403 value = extract_field (FLD_S, code, 0);
405 /* Number of registers is equal to the number of elements in
406 each structure to be loaded/stored. */
407 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
408 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
410 /* Except when it is LD1R. */
411 if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
412 info->reglist.num_regs = 2;
414 return 1;
417 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
418 load/store single element instructions. */
420 aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
421 aarch64_opnd_info *info, const aarch64_insn code,
422 const aarch64_inst *inst ATTRIBUTE_UNUSED)
424 aarch64_field field = {0, 0};
425 aarch64_insn QSsize; /* fields Q:S:size. */
426 aarch64_insn opcodeh2; /* opcode<2:1> */
428 /* Rt */
429 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
431 /* Decode the index, opcode<2:1> and size. */
432 gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
433 opcodeh2 = extract_field_2 (&field, code, 0);
434 QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
435 switch (opcodeh2)
437 case 0x0:
438 info->qualifier = AARCH64_OPND_QLF_S_B;
439 /* Index encoded in "Q:S:size". */
440 info->reglist.index = QSsize;
441 break;
442 case 0x1:
443 if (QSsize & 0x1)
444 /* UND. */
445 return 0;
446 info->qualifier = AARCH64_OPND_QLF_S_H;
447 /* Index encoded in "Q:S:size<1>". */
448 info->reglist.index = QSsize >> 1;
449 break;
450 case 0x2:
451 if ((QSsize >> 1) & 0x1)
452 /* UND. */
453 return 0;
454 if ((QSsize & 0x1) == 0)
456 info->qualifier = AARCH64_OPND_QLF_S_S;
457 /* Index encoded in "Q:S". */
458 info->reglist.index = QSsize >> 2;
460 else
462 if (extract_field (FLD_S, code, 0))
463 /* UND */
464 return 0;
465 info->qualifier = AARCH64_OPND_QLF_S_D;
466 /* Index encoded in "Q". */
467 info->reglist.index = QSsize >> 3;
469 break;
470 default:
471 return 0;
474 info->reglist.has_index = 1;
475 info->reglist.num_regs = 0;
476 /* Number of registers is equal to the number of elements in
477 each structure to be loaded/stored. */
478 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
479 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
481 return 1;
484 /* Decode fields immh:immb and/or Q for e.g.
485 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
486 or SSHR <V><d>, <V><n>, #<shift>. */
489 aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
490 aarch64_opnd_info *info, const aarch64_insn code,
491 const aarch64_inst *inst)
493 int pos;
494 aarch64_insn Q, imm, immh;
495 enum aarch64_insn_class iclass = inst->opcode->iclass;
497 immh = extract_field (FLD_immh, code, 0);
498 if (immh == 0)
499 return 0;
500 imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
501 pos = 4;
502 /* Get highest set bit in immh. */
503 while (--pos >= 0 && (immh & 0x8) == 0)
504 immh <<= 1;
506 assert ((iclass == asimdshf || iclass == asisdshf)
507 && (info->type == AARCH64_OPND_IMM_VLSR
508 || info->type == AARCH64_OPND_IMM_VLSL));
510 if (iclass == asimdshf)
512 Q = extract_field (FLD_Q, code, 0);
513 /* immh Q <T>
514 0000 x SEE AdvSIMD modified immediate
515 0001 0 8B
516 0001 1 16B
517 001x 0 4H
518 001x 1 8H
519 01xx 0 2S
520 01xx 1 4S
521 1xxx 0 RESERVED
522 1xxx 1 2D */
523 info->qualifier =
524 get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
526 else
527 info->qualifier = get_sreg_qualifier_from_value (pos);
529 if (info->type == AARCH64_OPND_IMM_VLSR)
530 /* immh <shift>
531 0000 SEE AdvSIMD modified immediate
532 0001 (16-UInt(immh:immb))
533 001x (32-UInt(immh:immb))
534 01xx (64-UInt(immh:immb))
535 1xxx (128-UInt(immh:immb)) */
536 info->imm.value = (16 << pos) - imm;
537 else
538 /* immh:immb
539 immh <shift>
540 0000 SEE AdvSIMD modified immediate
541 0001 (UInt(immh:immb)-8)
542 001x (UInt(immh:immb)-16)
543 01xx (UInt(immh:immb)-32)
544 1xxx (UInt(immh:immb)-64) */
545 info->imm.value = imm - (8 << pos);
547 return 1;
550 /* Decode shift immediate for e.g. sshr (imm). */
552 aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
553 aarch64_opnd_info *info, const aarch64_insn code,
554 const aarch64_inst *inst ATTRIBUTE_UNUSED)
556 int64_t imm;
557 aarch64_insn val;
558 val = extract_field (FLD_size, code, 0);
559 switch (val)
561 case 0: imm = 8; break;
562 case 1: imm = 16; break;
563 case 2: imm = 32; break;
564 default: return 0;
566 info->imm.value = imm;
567 return 1;
570 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
571 value in the field(s) will be extracted as unsigned immediate value. */
573 aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
574 const aarch64_insn code,
575 const aarch64_inst *inst ATTRIBUTE_UNUSED)
577 int64_t imm;
578 /* Maximum of two fields to extract. */
579 assert (self->fields[2] == FLD_NIL);
581 if (self->fields[1] == FLD_NIL)
582 imm = extract_field (self->fields[0], code, 0);
583 else
584 /* e.g. TBZ b5:b40. */
585 imm = extract_fields (code, 0, 2, self->fields[0], self->fields[1]);
587 if (info->type == AARCH64_OPND_FPIMM)
588 info->imm.is_fp = 1;
590 if (operand_need_sign_extension (self))
591 imm = sign_extend (imm, get_operand_fields_width (self) - 1);
593 if (operand_need_shift_by_two (self))
594 imm <<= 2;
596 if (info->type == AARCH64_OPND_ADDR_ADRP)
597 imm <<= 12;
599 info->imm.value = imm;
600 return 1;
603 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
605 aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
606 const aarch64_insn code,
607 const aarch64_inst *inst ATTRIBUTE_UNUSED)
609 aarch64_ext_imm (self, info, code, inst);
610 info->shifter.kind = AARCH64_MOD_LSL;
611 info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
612 return 1;
615 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
616 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
618 aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
619 aarch64_opnd_info *info,
620 const aarch64_insn code,
621 const aarch64_inst *inst ATTRIBUTE_UNUSED)
623 uint64_t imm;
624 enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
625 aarch64_field field = {0, 0};
627 assert (info->idx == 1);
629 if (info->type == AARCH64_OPND_SIMD_FPIMM)
630 info->imm.is_fp = 1;
632 /* a:b:c:d:e:f:g:h */
633 imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
634 if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
636 /* Either MOVI <Dd>, #<imm>
637 or MOVI <Vd>.2D, #<imm>.
638 <imm> is a 64-bit immediate
639 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
640 encoded in "a:b:c:d:e:f:g:h". */
641 int i;
642 unsigned abcdefgh = imm;
643 for (imm = 0ull, i = 0; i < 8; i++)
644 if (((abcdefgh >> i) & 0x1) != 0)
645 imm |= 0xffull << (8 * i);
647 info->imm.value = imm;
649 /* cmode */
650 info->qualifier = get_expected_qualifier (inst, info->idx);
651 switch (info->qualifier)
653 case AARCH64_OPND_QLF_NIL:
654 /* no shift */
655 info->shifter.kind = AARCH64_MOD_NONE;
656 return 1;
657 case AARCH64_OPND_QLF_LSL:
658 /* shift zeros */
659 info->shifter.kind = AARCH64_MOD_LSL;
660 switch (aarch64_get_qualifier_esize (opnd0_qualifier))
662 case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
663 case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
664 case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
665 default: assert (0); return 0;
667 /* 00: 0; 01: 8; 10:16; 11:24. */
668 info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
669 break;
670 case AARCH64_OPND_QLF_MSL:
671 /* shift ones */
672 info->shifter.kind = AARCH64_MOD_MSL;
673 gen_sub_field (FLD_cmode, 0, 1, &field); /* per word */
674 info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
675 break;
676 default:
677 assert (0);
678 return 0;
681 return 1;
684 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
686 aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
687 aarch64_opnd_info *info, const aarch64_insn code,
688 const aarch64_inst *inst ATTRIBUTE_UNUSED)
690 info->imm.value = 64- extract_field (FLD_scale, code, 0);
691 return 1;
694 /* Decode arithmetic immediate for e.g.
695 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
697 aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
698 aarch64_opnd_info *info, const aarch64_insn code,
699 const aarch64_inst *inst ATTRIBUTE_UNUSED)
701 aarch64_insn value;
703 info->shifter.kind = AARCH64_MOD_LSL;
704 /* shift */
705 value = extract_field (FLD_shift, code, 0);
706 if (value >= 2)
707 return 0;
708 info->shifter.amount = value ? 12 : 0;
709 /* imm12 (unsigned) */
710 info->imm.value = extract_field (FLD_imm12, code, 0);
712 return 1;
715 /* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
718 aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
719 aarch64_opnd_info *info, const aarch64_insn code,
720 const aarch64_inst *inst ATTRIBUTE_UNUSED)
722 uint64_t imm, mask;
723 uint32_t sf;
724 uint32_t N, R, S;
725 unsigned simd_size;
726 aarch64_insn value;
728 value = extract_fields (code, 0, 3, FLD_N, FLD_immr, FLD_imms);
729 assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_W
730 || inst->operands[0].qualifier == AARCH64_OPND_QLF_X);
731 sf = aarch64_get_qualifier_esize (inst->operands[0].qualifier) != 4;
733 /* value is N:immr:imms. */
734 S = value & 0x3f;
735 R = (value >> 6) & 0x3f;
736 N = (value >> 12) & 0x1;
738 if (sf == 0 && N == 1)
739 return 0;
741 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
742 (in other words, right rotated by R), then replicated. */
743 if (N != 0)
745 simd_size = 64;
746 mask = 0xffffffffffffffffull;
748 else
750 switch (S)
752 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break;
753 case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
754 case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break;
755 case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break;
756 case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break;
757 default: return 0;
759 mask = (1ull << simd_size) - 1;
760 /* Top bits are IGNORED. */
761 R &= simd_size - 1;
763 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
764 if (S == simd_size - 1)
765 return 0;
766 /* S+1 consecutive bits to 1. */
767 /* NOTE: S can't be 63 due to detection above. */
768 imm = (1ull << (S + 1)) - 1;
769 /* Rotate to the left by simd_size - R. */
770 if (R != 0)
771 imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
772 /* Replicate the value according to SIMD size. */
773 switch (simd_size)
775 case 2: imm = (imm << 2) | imm;
776 case 4: imm = (imm << 4) | imm;
777 case 8: imm = (imm << 8) | imm;
778 case 16: imm = (imm << 16) | imm;
779 case 32: imm = (imm << 32) | imm;
780 case 64: break;
781 default: assert (0); return 0;
784 info->imm.value = sf ? imm : imm & 0xffffffff;
786 return 1;
789 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
790 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
792 aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
793 aarch64_opnd_info *info,
794 const aarch64_insn code, const aarch64_inst *inst)
796 aarch64_insn value;
798 /* Rt */
799 info->reg.regno = extract_field (FLD_Rt, code, 0);
801 /* size */
802 value = extract_field (FLD_ldst_size, code, 0);
803 if (inst->opcode->iclass == ldstpair_indexed
804 || inst->opcode->iclass == ldstnapair_offs
805 || inst->opcode->iclass == ldstpair_off
806 || inst->opcode->iclass == loadlit)
808 enum aarch64_opnd_qualifier qualifier;
809 switch (value)
811 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
812 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
813 case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
814 default: return 0;
816 info->qualifier = qualifier;
818 else
820 /* opc1:size */
821 value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
822 if (value > 0x4)
823 return 0;
824 info->qualifier = get_sreg_qualifier_from_value (value);
827 return 1;
830 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
832 aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
833 aarch64_opnd_info *info,
834 aarch64_insn code,
835 const aarch64_inst *inst ATTRIBUTE_UNUSED)
837 /* Rn */
838 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
839 return 1;
842 /* Decode the address operand for e.g.
843 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
845 aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
846 aarch64_opnd_info *info,
847 aarch64_insn code, const aarch64_inst *inst)
849 aarch64_insn S, value;
851 /* Rn */
852 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
853 /* Rm */
854 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
855 /* option */
856 value = extract_field (FLD_option, code, 0);
857 info->shifter.kind =
858 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
859 /* Fix-up the shifter kind; although the table-driven approach is
860 efficient, it is slightly inflexible, thus needing this fix-up. */
861 if (info->shifter.kind == AARCH64_MOD_UXTX)
862 info->shifter.kind = AARCH64_MOD_LSL;
863 /* S */
864 S = extract_field (FLD_S, code, 0);
865 if (S == 0)
867 info->shifter.amount = 0;
868 info->shifter.amount_present = 0;
870 else
872 int size;
873 /* Need information in other operand(s) to help achieve the decoding
874 from 'S' field. */
875 info->qualifier = get_expected_qualifier (inst, info->idx);
876 /* Get the size of the data element that is accessed, which may be
877 different from that of the source register size, e.g. in strb/ldrb. */
878 size = aarch64_get_qualifier_esize (info->qualifier);
879 info->shifter.amount = get_logsz (size);
880 info->shifter.amount_present = 1;
883 return 1;
886 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
888 aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
889 aarch64_insn code, const aarch64_inst *inst)
891 aarch64_insn imm;
892 info->qualifier = get_expected_qualifier (inst, info->idx);
894 /* Rn */
895 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
896 /* simm (imm9 or imm7) */
897 imm = extract_field (self->fields[0], code, 0);
898 info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
899 if (self->fields[0] == FLD_imm7)
900 /* scaled immediate in ld/st pair instructions. */
901 info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
902 /* qualifier */
903 if (inst->opcode->iclass == ldst_unscaled
904 || inst->opcode->iclass == ldstnapair_offs
905 || inst->opcode->iclass == ldstpair_off
906 || inst->opcode->iclass == ldst_unpriv)
907 info->addr.writeback = 0;
908 else
910 /* pre/post- index */
911 info->addr.writeback = 1;
912 if (extract_field (self->fields[1], code, 0) == 1)
913 info->addr.preind = 1;
914 else
915 info->addr.postind = 1;
918 return 1;
921 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
923 aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
924 aarch64_insn code,
925 const aarch64_inst *inst ATTRIBUTE_UNUSED)
927 int shift;
928 info->qualifier = get_expected_qualifier (inst, info->idx);
929 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
930 /* Rn */
931 info->addr.base_regno = extract_field (self->fields[0], code, 0);
932 /* uimm12 */
933 info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
934 return 1;
937 /* Decode the address operand for e.g.
938 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
940 aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
941 aarch64_opnd_info *info,
942 aarch64_insn code, const aarch64_inst *inst)
944 /* The opcode dependent area stores the number of elements in
945 each structure to be loaded/stored. */
946 int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
948 /* Rn */
949 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
950 /* Rm | #<amount> */
951 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
952 if (info->addr.offset.regno == 31)
954 if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
955 /* Special handling of loading single structure to all lane. */
956 info->addr.offset.imm = (is_ld1r ? 1
957 : inst->operands[0].reglist.num_regs)
958 * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
959 else
960 info->addr.offset.imm = inst->operands[0].reglist.num_regs
961 * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
962 * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
964 else
965 info->addr.offset.is_reg = 1;
966 info->addr.writeback = 1;
968 return 1;
971 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
973 aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
974 aarch64_opnd_info *info,
975 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
977 aarch64_insn value;
978 /* cond */
979 value = extract_field (FLD_cond, code, 0);
980 info->cond = get_cond_from_value (value);
981 return 1;
984 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
986 aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
987 aarch64_opnd_info *info,
988 aarch64_insn code,
989 const aarch64_inst *inst ATTRIBUTE_UNUSED)
991 /* op0:op1:CRn:CRm:op2 */
992 info->sysreg = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
993 FLD_CRm, FLD_op2);
994 return 1;
997 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
999 aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
1000 aarch64_opnd_info *info, aarch64_insn code,
1001 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1003 int i;
1004 /* op1:op2 */
1005 info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1006 for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1007 if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1008 return 1;
1009 /* Reserved value in <pstatefield>. */
1010 return 0;
1013 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1015 aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
1016 aarch64_opnd_info *info,
1017 aarch64_insn code,
1018 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1020 int i;
1021 aarch64_insn value;
1022 const aarch64_sys_ins_reg *sysins_ops;
1023 /* op0:op1:CRn:CRm:op2 */
1024 value = extract_fields (code, 0, 5,
1025 FLD_op0, FLD_op1, FLD_CRn,
1026 FLD_CRm, FLD_op2);
1028 switch (info->type)
1030 case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1031 case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1032 case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1033 case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1034 default: assert (0); return 0;
1037 for (i = 0; sysins_ops[i].name != NULL; ++i)
1038 if (sysins_ops[i].value == value)
1040 info->sysins_op = sysins_ops + i;
1041 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1042 info->sysins_op->name,
1043 (unsigned)info->sysins_op->value,
1044 aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1045 return 1;
1048 return 0;
1051 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1054 aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
1055 aarch64_opnd_info *info,
1056 aarch64_insn code,
1057 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1059 /* CRm */
1060 info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1061 return 1;
1064 /* Decode the prefetch operation option operand for e.g.
1065 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1068 aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
1069 aarch64_opnd_info *info,
1070 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
1072 /* prfop in Rt */
1073 info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1074 return 1;
1077 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1078 to the matching name/value pair in aarch64_hint_options. */
1081 aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
1082 aarch64_opnd_info *info,
1083 aarch64_insn code,
1084 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1086 /* CRm:op2. */
1087 unsigned hint_number;
1088 int i;
1090 hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1092 for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1094 if (hint_number == aarch64_hint_options[i].value)
1096 info->hint_option = &(aarch64_hint_options[i]);
1097 return 1;
1101 return 0;
1104 /* Decode the extended register operand for e.g.
1105 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1107 aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
1108 aarch64_opnd_info *info,
1109 aarch64_insn code,
1110 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1112 aarch64_insn value;
1114 /* Rm */
1115 info->reg.regno = extract_field (FLD_Rm, code, 0);
1116 /* option */
1117 value = extract_field (FLD_option, code, 0);
1118 info->shifter.kind =
1119 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1120 /* imm3 */
1121 info->shifter.amount = extract_field (FLD_imm3, code, 0);
1123 /* This makes the constraint checking happy. */
1124 info->shifter.operator_present = 1;
1126 /* Assume inst->operands[0].qualifier has been resolved. */
1127 assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
1128 info->qualifier = AARCH64_OPND_QLF_W;
1129 if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1130 && (info->shifter.kind == AARCH64_MOD_UXTX
1131 || info->shifter.kind == AARCH64_MOD_SXTX))
1132 info->qualifier = AARCH64_OPND_QLF_X;
1134 return 1;
1137 /* Decode the shifted register operand for e.g.
1138 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1140 aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
1141 aarch64_opnd_info *info,
1142 aarch64_insn code,
1143 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1145 aarch64_insn value;
1147 /* Rm */
1148 info->reg.regno = extract_field (FLD_Rm, code, 0);
1149 /* shift */
1150 value = extract_field (FLD_shift, code, 0);
1151 info->shifter.kind =
1152 aarch64_get_operand_modifier_from_value (value, FALSE /* extend_p */);
1153 if (info->shifter.kind == AARCH64_MOD_ROR
1154 && inst->opcode->iclass != log_shift)
1155 /* ROR is not available for the shifted register operand in arithmetic
1156 instructions. */
1157 return 0;
1158 /* imm6 */
1159 info->shifter.amount = extract_field (FLD_imm6, code, 0);
1161 /* This makes the constraint checking happy. */
1162 info->shifter.operator_present = 1;
1164 return 1;
1167 /* Bitfields that are commonly used to encode certain operands' information
1168 may be partially used as part of the base opcode in some instructions.
1169 For example, the bit 1 of the field 'size' in
1170 FCVTXN <Vb><d>, <Va><n>
1171 is actually part of the base opcode, while only size<0> is available
1172 for encoding the register type. Another example is the AdvSIMD
1173 instruction ORR (register), in which the field 'size' is also used for
1174 the base opcode, leaving only the field 'Q' available to encode the
1175 vector register arrangement specifier '8B' or '16B'.
1177 This function tries to deduce the qualifier from the value of partially
1178 constrained field(s). Given the VALUE of such a field or fields, the
1179 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1180 operand encoding), the function returns the matching qualifier or
1181 AARCH64_OPND_QLF_NIL if nothing matches.
1183 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1184 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1185 may end with AARCH64_OPND_QLF_NIL. */
1187 static enum aarch64_opnd_qualifier
1188 get_qualifier_from_partial_encoding (aarch64_insn value,
1189 const enum aarch64_opnd_qualifier* \
1190 candidates,
1191 aarch64_insn mask)
1193 int i;
1194 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
1195 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1197 aarch64_insn standard_value;
1198 if (candidates[i] == AARCH64_OPND_QLF_NIL)
1199 break;
1200 standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
1201 if ((standard_value & mask) == (value & mask))
1202 return candidates[i];
1204 return AARCH64_OPND_QLF_NIL;
1207 /* Given a list of qualifier sequences, return all possible valid qualifiers
1208 for operand IDX in QUALIFIERS.
1209 Assume QUALIFIERS is an array whose length is large enough. */
1211 static void
1212 get_operand_possible_qualifiers (int idx,
1213 const aarch64_opnd_qualifier_seq_t *list,
1214 enum aarch64_opnd_qualifier *qualifiers)
1216 int i;
1217 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1218 if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
1219 break;
1222 /* Decode the size Q field for e.g. SHADD.
1223 We tag one operand with the qualifer according to the code;
1224 whether the qualifier is valid for this opcode or not, it is the
1225 duty of the semantic checking. */
1227 static int
1228 decode_sizeq (aarch64_inst *inst)
1230 int idx;
1231 enum aarch64_opnd_qualifier qualifier;
1232 aarch64_insn code;
1233 aarch64_insn value, mask;
1234 enum aarch64_field_kind fld_sz;
1235 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1237 if (inst->opcode->iclass == asisdlse
1238 || inst->opcode->iclass == asisdlsep
1239 || inst->opcode->iclass == asisdlso
1240 || inst->opcode->iclass == asisdlsop)
1241 fld_sz = FLD_vldst_size;
1242 else
1243 fld_sz = FLD_size;
1245 code = inst->value;
1246 value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
1247 /* Obtain the info that which bits of fields Q and size are actually
1248 available for operand encoding. Opcodes like FMAXNM and FMLA have
1249 size[1] unavailable. */
1250 mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
1252 /* The index of the operand we are going to tag a qualifier and the qualifer
1253 itself are reasoned from the value of the size and Q fields and the
1254 possible valid qualifier lists. */
1255 idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
1256 DEBUG_TRACE ("key idx: %d", idx);
1258 /* For most related instruciton, size:Q are fully available for operand
1259 encoding. */
1260 if (mask == 0x7)
1262 inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
1263 return 1;
1266 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1267 candidates);
1268 #ifdef DEBUG_AARCH64
1269 if (debug_dump)
1271 int i;
1272 for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
1273 && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1274 DEBUG_TRACE ("qualifier %d: %s", i,
1275 aarch64_get_qualifier_name(candidates[i]));
1276 DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
1278 #endif /* DEBUG_AARCH64 */
1280 qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
1282 if (qualifier == AARCH64_OPND_QLF_NIL)
1283 return 0;
1285 inst->operands[idx].qualifier = qualifier;
1286 return 1;
1289 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1290 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1292 static int
1293 decode_asimd_fcvt (aarch64_inst *inst)
1295 aarch64_field field = {0, 0};
1296 aarch64_insn value;
1297 enum aarch64_opnd_qualifier qualifier;
1299 gen_sub_field (FLD_size, 0, 1, &field);
1300 value = extract_field_2 (&field, inst->value, 0);
1301 qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
1302 : AARCH64_OPND_QLF_V_2D;
1303 switch (inst->opcode->op)
1305 case OP_FCVTN:
1306 case OP_FCVTN2:
1307 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1308 inst->operands[1].qualifier = qualifier;
1309 break;
1310 case OP_FCVTL:
1311 case OP_FCVTL2:
1312 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1313 inst->operands[0].qualifier = qualifier;
1314 break;
1315 default:
1316 assert (0);
1317 return 0;
1320 return 1;
1323 /* Decode size[0], i.e. bit 22, for
1324 e.g. FCVTXN <Vb><d>, <Va><n>. */
1326 static int
1327 decode_asisd_fcvtxn (aarch64_inst *inst)
1329 aarch64_field field = {0, 0};
1330 gen_sub_field (FLD_size, 0, 1, &field);
1331 if (!extract_field_2 (&field, inst->value, 0))
1332 return 0;
1333 inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
1334 return 1;
1337 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1338 static int
1339 decode_fcvt (aarch64_inst *inst)
1341 enum aarch64_opnd_qualifier qualifier;
1342 aarch64_insn value;
1343 const aarch64_field field = {15, 2};
1345 /* opc dstsize */
1346 value = extract_field_2 (&field, inst->value, 0);
1347 switch (value)
1349 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
1350 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
1351 case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
1352 default: return 0;
1354 inst->operands[0].qualifier = qualifier;
1356 return 1;
1359 /* Do miscellaneous decodings that are not common enough to be driven by
1360 flags. */
1362 static int
1363 do_misc_decoding (aarch64_inst *inst)
1365 switch (inst->opcode->op)
1367 case OP_FCVT:
1368 return decode_fcvt (inst);
1369 case OP_FCVTN:
1370 case OP_FCVTN2:
1371 case OP_FCVTL:
1372 case OP_FCVTL2:
1373 return decode_asimd_fcvt (inst);
1374 case OP_FCVTXN_S:
1375 return decode_asisd_fcvtxn (inst);
1376 default:
1377 return 0;
1381 /* Opcodes that have fields shared by multiple operands are usually flagged
1382 with flags. In this function, we detect such flags, decode the related
1383 field(s) and store the information in one of the related operands. The
1384 'one' operand is not any operand but one of the operands that can
1385 accommadate all the information that has been decoded. */
1387 static int
1388 do_special_decoding (aarch64_inst *inst)
1390 int idx;
1391 aarch64_insn value;
1392 /* Condition for truly conditional executed instructions, e.g. b.cond. */
1393 if (inst->opcode->flags & F_COND)
1395 value = extract_field (FLD_cond2, inst->value, 0);
1396 inst->cond = get_cond_from_value (value);
1398 /* 'sf' field. */
1399 if (inst->opcode->flags & F_SF)
1401 idx = select_operand_for_sf_field_coding (inst->opcode);
1402 value = extract_field (FLD_sf, inst->value, 0);
1403 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1404 if ((inst->opcode->flags & F_N)
1405 && extract_field (FLD_N, inst->value, 0) != value)
1406 return 0;
1408 /* 'sf' field. */
1409 if (inst->opcode->flags & F_LSE_SZ)
1411 idx = select_operand_for_sf_field_coding (inst->opcode);
1412 value = extract_field (FLD_lse_sz, inst->value, 0);
1413 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1415 /* size:Q fields. */
1416 if (inst->opcode->flags & F_SIZEQ)
1417 return decode_sizeq (inst);
1419 if (inst->opcode->flags & F_FPTYPE)
1421 idx = select_operand_for_fptype_field_coding (inst->opcode);
1422 value = extract_field (FLD_type, inst->value, 0);
1423 switch (value)
1425 case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
1426 case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
1427 case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
1428 default: return 0;
1432 if (inst->opcode->flags & F_SSIZE)
1434 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
1435 of the base opcode. */
1436 aarch64_insn mask;
1437 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1438 idx = select_operand_for_scalar_size_field_coding (inst->opcode);
1439 value = extract_field (FLD_size, inst->value, inst->opcode->mask);
1440 mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
1441 /* For most related instruciton, the 'size' field is fully available for
1442 operand encoding. */
1443 if (mask == 0x3)
1444 inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
1445 else
1447 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1448 candidates);
1449 inst->operands[idx].qualifier
1450 = get_qualifier_from_partial_encoding (value, candidates, mask);
1454 if (inst->opcode->flags & F_T)
1456 /* Num of consecutive '0's on the right side of imm5<3:0>. */
1457 int num = 0;
1458 unsigned val, Q;
1459 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1460 == AARCH64_OPND_CLASS_SIMD_REG);
1461 /* imm5<3:0> q <t>
1462 0000 x reserved
1463 xxx1 0 8b
1464 xxx1 1 16b
1465 xx10 0 4h
1466 xx10 1 8h
1467 x100 0 2s
1468 x100 1 4s
1469 1000 0 reserved
1470 1000 1 2d */
1471 val = extract_field (FLD_imm5, inst->value, 0);
1472 while ((val & 0x1) == 0 && ++num <= 3)
1473 val >>= 1;
1474 if (num > 3)
1475 return 0;
1476 Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
1477 inst->operands[0].qualifier =
1478 get_vreg_qualifier_from_value ((num << 1) | Q);
1481 if (inst->opcode->flags & F_GPRSIZE_IN_Q)
1483 /* Use Rt to encode in the case of e.g.
1484 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
1485 idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
1486 if (idx == -1)
1488 /* Otherwise use the result operand, which has to be a integer
1489 register. */
1490 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1491 == AARCH64_OPND_CLASS_INT_REG);
1492 idx = 0;
1494 assert (idx == 0 || idx == 1);
1495 value = extract_field (FLD_Q, inst->value, 0);
1496 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1499 if (inst->opcode->flags & F_LDS_SIZE)
1501 aarch64_field field = {0, 0};
1502 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1503 == AARCH64_OPND_CLASS_INT_REG);
1504 gen_sub_field (FLD_opc, 0, 1, &field);
1505 value = extract_field_2 (&field, inst->value, 0);
1506 inst->operands[0].qualifier
1507 = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
1510 /* Miscellaneous decoding; done as the last step. */
1511 if (inst->opcode->flags & F_MISC)
1512 return do_misc_decoding (inst);
1514 return 1;
1517 /* Converters converting a real opcode instruction to its alias form. */
1519 /* ROR <Wd>, <Ws>, #<shift>
1520 is equivalent to:
1521 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
1522 static int
1523 convert_extr_to_ror (aarch64_inst *inst)
1525 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
1527 copy_operand_info (inst, 2, 3);
1528 inst->operands[3].type = AARCH64_OPND_NIL;
1529 return 1;
1531 return 0;
1534 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
1535 is equivalent to:
1536 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
1537 static int
1538 convert_shll_to_xtl (aarch64_inst *inst)
1540 if (inst->operands[2].imm.value == 0)
1542 inst->operands[2].type = AARCH64_OPND_NIL;
1543 return 1;
1545 return 0;
1548 /* Convert
1549 UBFM <Xd>, <Xn>, #<shift>, #63.
1551 LSR <Xd>, <Xn>, #<shift>. */
1552 static int
1553 convert_bfm_to_sr (aarch64_inst *inst)
1555 int64_t imms, val;
1557 imms = inst->operands[3].imm.value;
1558 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
1559 if (imms == val)
1561 inst->operands[3].type = AARCH64_OPND_NIL;
1562 return 1;
1565 return 0;
1568 /* Convert MOV to ORR. */
1569 static int
1570 convert_orr_to_mov (aarch64_inst *inst)
1572 /* MOV <Vd>.<T>, <Vn>.<T>
1573 is equivalent to:
1574 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
1575 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
1577 inst->operands[2].type = AARCH64_OPND_NIL;
1578 return 1;
1580 return 0;
1583 /* When <imms> >= <immr>, the instruction written:
1584 SBFX <Xd>, <Xn>, #<lsb>, #<width>
1585 is equivalent to:
1586 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
1588 static int
1589 convert_bfm_to_bfx (aarch64_inst *inst)
1591 int64_t immr, imms;
1593 immr = inst->operands[2].imm.value;
1594 imms = inst->operands[3].imm.value;
1595 if (imms >= immr)
1597 int64_t lsb = immr;
1598 inst->operands[2].imm.value = lsb;
1599 inst->operands[3].imm.value = imms + 1 - lsb;
1600 /* The two opcodes have different qualifiers for
1601 the immediate operands; reset to help the checking. */
1602 reset_operand_qualifier (inst, 2);
1603 reset_operand_qualifier (inst, 3);
1604 return 1;
1607 return 0;
1610 /* When <imms> < <immr>, the instruction written:
1611 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
1612 is equivalent to:
1613 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
1615 static int
1616 convert_bfm_to_bfi (aarch64_inst *inst)
1618 int64_t immr, imms, val;
1620 immr = inst->operands[2].imm.value;
1621 imms = inst->operands[3].imm.value;
1622 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
1623 if (imms < immr)
1625 inst->operands[2].imm.value = (val - immr) & (val - 1);
1626 inst->operands[3].imm.value = imms + 1;
1627 /* The two opcodes have different qualifiers for
1628 the immediate operands; reset to help the checking. */
1629 reset_operand_qualifier (inst, 2);
1630 reset_operand_qualifier (inst, 3);
1631 return 1;
1634 return 0;
1637 /* The instruction written:
1638 BFC <Xd>, #<lsb>, #<width>
1639 is equivalent to:
1640 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
1642 static int
1643 convert_bfm_to_bfc (aarch64_inst *inst)
1645 int64_t immr, imms, val;
1647 /* Should have been assured by the base opcode value. */
1648 assert (inst->operands[1].reg.regno == 0x1f);
1650 immr = inst->operands[2].imm.value;
1651 imms = inst->operands[3].imm.value;
1652 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
1653 if (imms < immr)
1655 /* Drop XZR from the second operand. */
1656 copy_operand_info (inst, 1, 2);
1657 copy_operand_info (inst, 2, 3);
1658 inst->operands[3].type = AARCH64_OPND_NIL;
1660 /* Recalculate the immediates. */
1661 inst->operands[1].imm.value = (val - immr) & (val - 1);
1662 inst->operands[2].imm.value = imms + 1;
1664 /* The two opcodes have different qualifiers for the operands; reset to
1665 help the checking. */
1666 reset_operand_qualifier (inst, 1);
1667 reset_operand_qualifier (inst, 2);
1668 reset_operand_qualifier (inst, 3);
1670 return 1;
1673 return 0;
1676 /* The instruction written:
1677 LSL <Xd>, <Xn>, #<shift>
1678 is equivalent to:
1679 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
1681 static int
1682 convert_ubfm_to_lsl (aarch64_inst *inst)
1684 int64_t immr = inst->operands[2].imm.value;
1685 int64_t imms = inst->operands[3].imm.value;
1686 int64_t val
1687 = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
1689 if ((immr == 0 && imms == val) || immr == imms + 1)
1691 inst->operands[3].type = AARCH64_OPND_NIL;
1692 inst->operands[2].imm.value = val - imms;
1693 return 1;
1696 return 0;
1699 /* CINC <Wd>, <Wn>, <cond>
1700 is equivalent to:
1701 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
1702 where <cond> is not AL or NV. */
1704 static int
1705 convert_from_csel (aarch64_inst *inst)
1707 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
1708 && (inst->operands[3].cond->value & 0xe) != 0xe)
1710 copy_operand_info (inst, 2, 3);
1711 inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
1712 inst->operands[3].type = AARCH64_OPND_NIL;
1713 return 1;
1715 return 0;
1718 /* CSET <Wd>, <cond>
1719 is equivalent to:
1720 CSINC <Wd>, WZR, WZR, invert(<cond>)
1721 where <cond> is not AL or NV. */
1723 static int
1724 convert_csinc_to_cset (aarch64_inst *inst)
1726 if (inst->operands[1].reg.regno == 0x1f
1727 && inst->operands[2].reg.regno == 0x1f
1728 && (inst->operands[3].cond->value & 0xe) != 0xe)
1730 copy_operand_info (inst, 1, 3);
1731 inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
1732 inst->operands[3].type = AARCH64_OPND_NIL;
1733 inst->operands[2].type = AARCH64_OPND_NIL;
1734 return 1;
1736 return 0;
1739 /* MOV <Wd>, #<imm>
1740 is equivalent to:
1741 MOVZ <Wd>, #<imm16>, LSL #<shift>.
1743 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1744 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1745 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1746 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1747 machine-instruction mnemonic must be used. */
1749 static int
1750 convert_movewide_to_mov (aarch64_inst *inst)
1752 uint64_t value = inst->operands[1].imm.value;
1753 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
1754 if (value == 0 && inst->operands[1].shifter.amount != 0)
1755 return 0;
1756 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
1757 inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
1758 value <<= inst->operands[1].shifter.amount;
1759 /* As an alias convertor, it has to be clear that the INST->OPCODE
1760 is the opcode of the real instruction. */
1761 if (inst->opcode->op == OP_MOVN)
1763 int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
1764 value = ~value;
1765 /* A MOVN has an immediate that could be encoded by MOVZ. */
1766 if (aarch64_wide_constant_p (value, is32, NULL) == TRUE)
1767 return 0;
1769 inst->operands[1].imm.value = value;
1770 inst->operands[1].shifter.amount = 0;
1771 return 1;
1774 /* MOV <Wd>, #<imm>
1775 is equivalent to:
1776 ORR <Wd>, WZR, #<imm>.
1778 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1779 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1780 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1781 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1782 machine-instruction mnemonic must be used. */
1784 static int
1785 convert_movebitmask_to_mov (aarch64_inst *inst)
1787 int is32;
1788 uint64_t value;
1790 /* Should have been assured by the base opcode value. */
1791 assert (inst->operands[1].reg.regno == 0x1f);
1792 copy_operand_info (inst, 1, 2);
1793 is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
1794 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
1795 value = inst->operands[1].imm.value;
1796 /* ORR has an immediate that could be generated by a MOVZ or MOVN
1797 instruction. */
1798 if (inst->operands[0].reg.regno != 0x1f
1799 && (aarch64_wide_constant_p (value, is32, NULL) == TRUE
1800 || aarch64_wide_constant_p (~value, is32, NULL) == TRUE))
1801 return 0;
1803 inst->operands[2].type = AARCH64_OPND_NIL;
1804 return 1;
1807 /* Some alias opcodes are disassembled by being converted from their real-form.
1808 N.B. INST->OPCODE is the real opcode rather than the alias. */
1810 static int
1811 convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
1813 switch (alias->op)
1815 case OP_ASR_IMM:
1816 case OP_LSR_IMM:
1817 return convert_bfm_to_sr (inst);
1818 case OP_LSL_IMM:
1819 return convert_ubfm_to_lsl (inst);
1820 case OP_CINC:
1821 case OP_CINV:
1822 case OP_CNEG:
1823 return convert_from_csel (inst);
1824 case OP_CSET:
1825 case OP_CSETM:
1826 return convert_csinc_to_cset (inst);
1827 case OP_UBFX:
1828 case OP_BFXIL:
1829 case OP_SBFX:
1830 return convert_bfm_to_bfx (inst);
1831 case OP_SBFIZ:
1832 case OP_BFI:
1833 case OP_UBFIZ:
1834 return convert_bfm_to_bfi (inst);
1835 case OP_BFC:
1836 return convert_bfm_to_bfc (inst);
1837 case OP_MOV_V:
1838 return convert_orr_to_mov (inst);
1839 case OP_MOV_IMM_WIDE:
1840 case OP_MOV_IMM_WIDEN:
1841 return convert_movewide_to_mov (inst);
1842 case OP_MOV_IMM_LOG:
1843 return convert_movebitmask_to_mov (inst);
1844 case OP_ROR_IMM:
1845 return convert_extr_to_ror (inst);
1846 case OP_SXTL:
1847 case OP_SXTL2:
1848 case OP_UXTL:
1849 case OP_UXTL2:
1850 return convert_shll_to_xtl (inst);
1851 default:
1852 return 0;
1856 static int aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
1857 aarch64_inst *, int);
1859 /* Given the instruction information in *INST, check if the instruction has
1860 any alias form that can be used to represent *INST. If the answer is yes,
1861 update *INST to be in the form of the determined alias. */
1863 /* In the opcode description table, the following flags are used in opcode
1864 entries to help establish the relations between the real and alias opcodes:
1866 F_ALIAS: opcode is an alias
1867 F_HAS_ALIAS: opcode has alias(es)
1868 F_P1
1869 F_P2
1870 F_P3: Disassembly preference priority 1-3 (the larger the
1871 higher). If nothing is specified, it is the priority
1872 0 by default, i.e. the lowest priority.
1874 Although the relation between the machine and the alias instructions are not
1875 explicitly described, it can be easily determined from the base opcode
1876 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
1877 description entries:
1879 The mask of an alias opcode must be equal to or a super-set (i.e. more
1880 constrained) of that of the aliased opcode; so is the base opcode value.
1882 if (opcode_has_alias (real) && alias_opcode_p (opcode)
1883 && (opcode->mask & real->mask) == real->mask
1884 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
1885 then OPCODE is an alias of, and only of, the REAL instruction
1887 The alias relationship is forced flat-structured to keep related algorithm
1888 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
1890 During the disassembling, the decoding decision tree (in
1891 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
1892 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
1893 not specified), the disassembler will check whether there is any alias
1894 instruction exists for this real instruction. If there is, the disassembler
1895 will try to disassemble the 32-bit binary again using the alias's rule, or
1896 try to convert the IR to the form of the alias. In the case of the multiple
1897 aliases, the aliases are tried one by one from the highest priority
1898 (currently the flag F_P3) to the lowest priority (no priority flag), and the
1899 first succeeds first adopted.
1901 You may ask why there is a need for the conversion of IR from one form to
1902 another in handling certain aliases. This is because on one hand it avoids
1903 adding more operand code to handle unusual encoding/decoding; on other
1904 hand, during the disassembling, the conversion is an effective approach to
1905 check the condition of an alias (as an alias may be adopted only if certain
1906 conditions are met).
1908 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
1909 aarch64_opcode_table and generated aarch64_find_alias_opcode and
1910 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
1912 static void
1913 determine_disassembling_preference (struct aarch64_inst *inst)
1915 const aarch64_opcode *opcode;
1916 const aarch64_opcode *alias;
1918 opcode = inst->opcode;
1920 /* This opcode does not have an alias, so use itself. */
1921 if (opcode_has_alias (opcode) == FALSE)
1922 return;
1924 alias = aarch64_find_alias_opcode (opcode);
1925 assert (alias);
1927 #ifdef DEBUG_AARCH64
1928 if (debug_dump)
1930 const aarch64_opcode *tmp = alias;
1931 printf ("#### LIST orderd: ");
1932 while (tmp)
1934 printf ("%s, ", tmp->name);
1935 tmp = aarch64_find_next_alias_opcode (tmp);
1937 printf ("\n");
1939 #endif /* DEBUG_AARCH64 */
1941 for (; alias; alias = aarch64_find_next_alias_opcode (alias))
1943 DEBUG_TRACE ("try %s", alias->name);
1944 assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
1946 /* An alias can be a pseudo opcode which will never be used in the
1947 disassembly, e.g. BIC logical immediate is such a pseudo opcode
1948 aliasing AND. */
1949 if (pseudo_opcode_p (alias))
1951 DEBUG_TRACE ("skip pseudo %s", alias->name);
1952 continue;
1955 if ((inst->value & alias->mask) != alias->opcode)
1957 DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
1958 continue;
1960 /* No need to do any complicated transformation on operands, if the alias
1961 opcode does not have any operand. */
1962 if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
1964 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
1965 aarch64_replace_opcode (inst, alias);
1966 return;
1968 if (alias->flags & F_CONV)
1970 aarch64_inst copy;
1971 memcpy (&copy, inst, sizeof (aarch64_inst));
1972 /* ALIAS is the preference as long as the instruction can be
1973 successfully converted to the form of ALIAS. */
1974 if (convert_to_alias (&copy, alias) == 1)
1976 aarch64_replace_opcode (&copy, alias);
1977 assert (aarch64_match_operands_constraint (&copy, NULL));
1978 DEBUG_TRACE ("succeed with %s via conversion", alias->name);
1979 memcpy (inst, &copy, sizeof (aarch64_inst));
1980 return;
1983 else
1985 /* Directly decode the alias opcode. */
1986 aarch64_inst temp;
1987 memset (&temp, '\0', sizeof (aarch64_inst));
1988 if (aarch64_opcode_decode (alias, inst->value, &temp, 1) == 1)
1990 DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
1991 memcpy (inst, &temp, sizeof (aarch64_inst));
1992 return;
1998 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
1999 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2000 return 1.
2002 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2003 determined and used to disassemble CODE; this is done just before the
2004 return. */
2006 static int
2007 aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
2008 aarch64_inst *inst, int noaliases_p)
2010 int i;
2012 DEBUG_TRACE ("enter with %s", opcode->name);
2014 assert (opcode && inst);
2016 /* Check the base opcode. */
2017 if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
2019 DEBUG_TRACE ("base opcode match FAIL");
2020 goto decode_fail;
2023 /* Clear inst. */
2024 memset (inst, '\0', sizeof (aarch64_inst));
2026 inst->opcode = opcode;
2027 inst->value = code;
2029 /* Assign operand codes and indexes. */
2030 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2032 if (opcode->operands[i] == AARCH64_OPND_NIL)
2033 break;
2034 inst->operands[i].type = opcode->operands[i];
2035 inst->operands[i].idx = i;
2038 /* Call the opcode decoder indicated by flags. */
2039 if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
2041 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2042 goto decode_fail;
2045 /* Call operand decoders. */
2046 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2048 const aarch64_operand *opnd;
2049 enum aarch64_opnd type;
2050 type = opcode->operands[i];
2051 if (type == AARCH64_OPND_NIL)
2052 break;
2053 opnd = &aarch64_operands[type];
2054 if (operand_has_extractor (opnd)
2055 && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst)))
2057 DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
2058 goto decode_fail;
2062 /* Match the qualifiers. */
2063 if (aarch64_match_operands_constraint (inst, NULL) == 1)
2065 /* Arriving here, the CODE has been determined as a valid instruction
2066 of OPCODE and *INST has been filled with information of this OPCODE
2067 instruction. Before the return, check if the instruction has any
2068 alias and should be disassembled in the form of its alias instead.
2069 If the answer is yes, *INST will be updated. */
2070 if (!noaliases_p)
2071 determine_disassembling_preference (inst);
2072 DEBUG_TRACE ("SUCCESS");
2073 return 1;
2075 else
2077 DEBUG_TRACE ("constraint matching FAIL");
2080 decode_fail:
2081 return 0;
2084 /* This does some user-friendly fix-up to *INST. It is currently focus on
2085 the adjustment of qualifiers to help the printed instruction
2086 recognized/understood more easily. */
2088 static void
2089 user_friendly_fixup (aarch64_inst *inst)
2091 switch (inst->opcode->iclass)
2093 case testbranch:
2094 /* TBNZ Xn|Wn, #uimm6, label
2095 Test and Branch Not Zero: conditionally jumps to label if bit number
2096 uimm6 in register Xn is not zero. The bit number implies the width of
2097 the register, which may be written and should be disassembled as Wn if
2098 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2100 if (inst->operands[1].imm.value < 32)
2101 inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
2102 break;
2103 default: break;
2107 /* Decode INSN and fill in *INST the instruction information. An alias
2108 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2109 success. */
2112 aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
2113 bfd_boolean noaliases_p)
2115 const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
2117 #ifdef DEBUG_AARCH64
2118 if (debug_dump)
2120 const aarch64_opcode *tmp = opcode;
2121 printf ("\n");
2122 DEBUG_TRACE ("opcode lookup:");
2123 while (tmp != NULL)
2125 aarch64_verbose (" %s", tmp->name);
2126 tmp = aarch64_find_next_opcode (tmp);
2129 #endif /* DEBUG_AARCH64 */
2131 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2132 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2133 opcode field and value, apart from the difference that one of them has an
2134 extra field as part of the opcode, but such a field is used for operand
2135 encoding in other opcode(s) ('immh' in the case of the example). */
2136 while (opcode != NULL)
2138 /* But only one opcode can be decoded successfully for, as the
2139 decoding routine will check the constraint carefully. */
2140 if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p) == 1)
2141 return ERR_OK;
2142 opcode = aarch64_find_next_opcode (opcode);
2145 return ERR_UND;
2148 /* Print operands. */
2150 static void
2151 print_operands (bfd_vma pc, const aarch64_opcode *opcode,
2152 const aarch64_opnd_info *opnds, struct disassemble_info *info)
2154 int i, pcrel_p, num_printed;
2155 for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2157 const size_t size = 128;
2158 char str[size];
2159 /* We regard the opcode operand info more, however we also look into
2160 the inst->operands to support the disassembling of the optional
2161 operand.
2162 The two operand code should be the same in all cases, apart from
2163 when the operand can be optional. */
2164 if (opcode->operands[i] == AARCH64_OPND_NIL
2165 || opnds[i].type == AARCH64_OPND_NIL)
2166 break;
2168 /* Generate the operand string in STR. */
2169 aarch64_print_operand (str, size, pc, opcode, opnds, i, &pcrel_p,
2170 &info->target);
2172 /* Print the delimiter (taking account of omitted operand(s)). */
2173 if (str[0] != '\0')
2174 (*info->fprintf_func) (info->stream, "%s",
2175 num_printed++ == 0 ? "\t" : ", ");
2177 /* Print the operand. */
2178 if (pcrel_p)
2179 (*info->print_address_func) (info->target, info);
2180 else
2181 (*info->fprintf_func) (info->stream, "%s", str);
2185 /* Print the instruction mnemonic name. */
2187 static void
2188 print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
2190 if (inst->opcode->flags & F_COND)
2192 /* For instructions that are truly conditionally executed, e.g. b.cond,
2193 prepare the full mnemonic name with the corresponding condition
2194 suffix. */
2195 char name[8], *ptr;
2196 size_t len;
2198 ptr = strchr (inst->opcode->name, '.');
2199 assert (ptr && inst->cond);
2200 len = ptr - inst->opcode->name;
2201 assert (len < 8);
2202 strncpy (name, inst->opcode->name, len);
2203 name [len] = '\0';
2204 (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
2206 else
2207 (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
2210 /* Print the instruction according to *INST. */
2212 static void
2213 print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
2214 struct disassemble_info *info)
2216 print_mnemonic_name (inst, info);
2217 print_operands (pc, inst->opcode, inst->operands, info);
2220 /* Entry-point of the instruction disassembler and printer. */
2222 static void
2223 print_insn_aarch64_word (bfd_vma pc,
2224 uint32_t word,
2225 struct disassemble_info *info)
2227 static const char *err_msg[6] =
2229 [ERR_OK] = "_",
2230 [-ERR_UND] = "undefined",
2231 [-ERR_UNP] = "unpredictable",
2232 [-ERR_NYI] = "NYI"
2235 int ret;
2236 aarch64_inst inst;
2238 info->insn_info_valid = 1;
2239 info->branch_delay_insns = 0;
2240 info->data_size = 0;
2241 info->target = 0;
2242 info->target2 = 0;
2244 if (info->flags & INSN_HAS_RELOC)
2245 /* If the instruction has a reloc associated with it, then
2246 the offset field in the instruction will actually be the
2247 addend for the reloc. (If we are using REL type relocs).
2248 In such cases, we can ignore the pc when computing
2249 addresses, since the addend is not currently pc-relative. */
2250 pc = 0;
2252 ret = aarch64_decode_insn (word, &inst, no_aliases);
2254 if (((word >> 21) & 0x3ff) == 1)
2256 /* RESERVED for ALES. */
2257 assert (ret != ERR_OK);
2258 ret = ERR_NYI;
2261 switch (ret)
2263 case ERR_UND:
2264 case ERR_UNP:
2265 case ERR_NYI:
2266 /* Handle undefined instructions. */
2267 info->insn_type = dis_noninsn;
2268 (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
2269 word, err_msg[-ret]);
2270 break;
2271 case ERR_OK:
2272 user_friendly_fixup (&inst);
2273 print_aarch64_insn (pc, &inst, info);
2274 break;
2275 default:
2276 abort ();
2280 /* Disallow mapping symbols ($x, $d etc) from
2281 being displayed in symbol relative addresses. */
2283 bfd_boolean
2284 aarch64_symbol_is_valid (asymbol * sym,
2285 struct disassemble_info * info ATTRIBUTE_UNUSED)
2287 const char * name;
2289 if (sym == NULL)
2290 return FALSE;
2292 name = bfd_asymbol_name (sym);
2294 return name
2295 && (name[0] != '$'
2296 || (name[1] != 'x' && name[1] != 'd')
2297 || (name[2] != '\0' && name[2] != '.'));
2300 /* Print data bytes on INFO->STREAM. */
2302 static void
2303 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
2304 uint32_t word,
2305 struct disassemble_info *info)
2307 switch (info->bytes_per_chunk)
2309 case 1:
2310 info->fprintf_func (info->stream, ".byte\t0x%02x", word);
2311 break;
2312 case 2:
2313 info->fprintf_func (info->stream, ".short\t0x%04x", word);
2314 break;
2315 case 4:
2316 info->fprintf_func (info->stream, ".word\t0x%08x", word);
2317 break;
2318 default:
2319 abort ();
2323 /* Try to infer the code or data type from a symbol.
2324 Returns nonzero if *MAP_TYPE was set. */
2326 static int
2327 get_sym_code_type (struct disassemble_info *info, int n,
2328 enum map_type *map_type)
2330 elf_symbol_type *es;
2331 unsigned int type;
2332 const char *name;
2334 es = *(elf_symbol_type **)(info->symtab + n);
2335 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2337 /* If the symbol has function type then use that. */
2338 if (type == STT_FUNC)
2340 *map_type = MAP_INSN;
2341 return TRUE;
2344 /* Check for mapping symbols. */
2345 name = bfd_asymbol_name(info->symtab[n]);
2346 if (name[0] == '$'
2347 && (name[1] == 'x' || name[1] == 'd')
2348 && (name[2] == '\0' || name[2] == '.'))
2350 *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
2351 return TRUE;
2354 return FALSE;
2357 /* Entry-point of the AArch64 disassembler. */
2360 print_insn_aarch64 (bfd_vma pc,
2361 struct disassemble_info *info)
2363 bfd_byte buffer[INSNLEN];
2364 int status;
2365 void (*printer) (bfd_vma, uint32_t, struct disassemble_info *);
2366 bfd_boolean found = FALSE;
2367 unsigned int size = 4;
2368 unsigned long data;
2370 if (info->disassembler_options)
2372 set_default_aarch64_dis_options (info);
2374 parse_aarch64_dis_options (info->disassembler_options);
2376 /* To avoid repeated parsing of these options, we remove them here. */
2377 info->disassembler_options = NULL;
2380 /* Aarch64 instructions are always little-endian */
2381 info->endian_code = BFD_ENDIAN_LITTLE;
2383 /* First check the full symtab for a mapping symbol, even if there
2384 are no usable non-mapping symbols for this address. */
2385 if (info->symtab_size != 0
2386 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
2388 enum map_type type = MAP_INSN;
2389 int last_sym = -1;
2390 bfd_vma addr;
2391 int n;
2393 if (pc <= last_mapping_addr)
2394 last_mapping_sym = -1;
2396 /* Start scanning at the start of the function, or wherever
2397 we finished last time. */
2398 n = info->symtab_pos + 1;
2399 if (n < last_mapping_sym)
2400 n = last_mapping_sym;
2402 /* Scan up to the location being disassembled. */
2403 for (; n < info->symtab_size; n++)
2405 addr = bfd_asymbol_value (info->symtab[n]);
2406 if (addr > pc)
2407 break;
2408 if ((info->section == NULL
2409 || info->section == info->symtab[n]->section)
2410 && get_sym_code_type (info, n, &type))
2412 last_sym = n;
2413 found = TRUE;
2417 if (!found)
2419 n = info->symtab_pos;
2420 if (n < last_mapping_sym)
2421 n = last_mapping_sym;
2423 /* No mapping symbol found at this address. Look backwards
2424 for a preceeding one. */
2425 for (; n >= 0; n--)
2427 if (get_sym_code_type (info, n, &type))
2429 last_sym = n;
2430 found = TRUE;
2431 break;
2436 last_mapping_sym = last_sym;
2437 last_type = type;
2439 /* Look a little bit ahead to see if we should print out
2440 less than four bytes of data. If there's a symbol,
2441 mapping or otherwise, after two bytes then don't
2442 print more. */
2443 if (last_type == MAP_DATA)
2445 size = 4 - (pc & 3);
2446 for (n = last_sym + 1; n < info->symtab_size; n++)
2448 addr = bfd_asymbol_value (info->symtab[n]);
2449 if (addr > pc)
2451 if (addr - pc < size)
2452 size = addr - pc;
2453 break;
2456 /* If the next symbol is after three bytes, we need to
2457 print only part of the data, so that we can use either
2458 .byte or .short. */
2459 if (size == 3)
2460 size = (pc & 1) ? 1 : 2;
2464 if (last_type == MAP_DATA)
2466 /* size was set above. */
2467 info->bytes_per_chunk = size;
2468 info->display_endian = info->endian;
2469 printer = print_insn_data;
2471 else
2473 info->bytes_per_chunk = size = INSNLEN;
2474 info->display_endian = info->endian_code;
2475 printer = print_insn_aarch64_word;
2478 status = (*info->read_memory_func) (pc, buffer, size, info);
2479 if (status != 0)
2481 (*info->memory_error_func) (status, pc, info);
2482 return -1;
2485 data = bfd_get_bits (buffer, size * 8,
2486 info->display_endian == BFD_ENDIAN_BIG);
2488 (*printer) (pc, data, info);
2490 return size;
2493 void
2494 print_aarch64_disassembler_options (FILE *stream)
2496 fprintf (stream, _("\n\
2497 The following AARCH64 specific disassembler options are supported for use\n\
2498 with the -M switch (multiple options should be separated by commas):\n"));
2500 fprintf (stream, _("\n\
2501 no-aliases Don't print instruction aliases.\n"));
2503 fprintf (stream, _("\n\
2504 aliases Do print instruction aliases.\n"));
2506 #ifdef DEBUG_AARCH64
2507 fprintf (stream, _("\n\
2508 debug_dump Temp switch for debug trace.\n"));
2509 #endif /* DEBUG_AARCH64 */
2511 fprintf (stream, _("\n"));