1 /* aarch64-asm.c -- AArch64 assembler support.
2 Copyright (C) 2012-2019 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)
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/>. */
23 #include "libiberty.h"
24 #include "aarch64-asm.h"
29 /* The unnamed arguments consist of the number of fields and information about
30 these fields where the VALUE will be inserted into CODE. MASK can be zero or
31 the base mask of the opcode.
33 N.B. the fields are required to be in such an order than the least signficant
34 field for VALUE comes the first, e.g. the <index> in
35 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
36 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
37 the order of M, L, H. */
40 insert_fields (aarch64_insn
*code
, aarch64_insn value
, aarch64_insn mask
, ...)
43 const aarch64_field
*field
;
44 enum aarch64_field_kind kind
;
48 num
= va_arg (va
, uint32_t);
52 kind
= va_arg (va
, enum aarch64_field_kind
);
53 field
= &fields
[kind
];
54 insert_field (kind
, code
, value
, mask
);
55 value
>>= field
->width
;
60 /* Insert a raw field value VALUE into all fields in SELF->fields.
61 The least significant bit goes in the final field. */
64 insert_all_fields (const aarch64_operand
*self
, aarch64_insn
*code
,
68 enum aarch64_field_kind kind
;
70 for (i
= ARRAY_SIZE (self
->fields
); i
-- > 0; )
71 if (self
->fields
[i
] != FLD_NIL
)
73 kind
= self
->fields
[i
];
74 insert_field (kind
, code
, value
, 0);
75 value
>>= fields
[kind
].width
;
79 /* Operand inserters. */
81 /* Insert register number. */
83 aarch64_ins_regno (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
85 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
86 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
88 insert_field (self
->fields
[0], code
, info
->reg
.regno
, 0);
92 /* Insert register number, index and/or other data for SIMD register element
93 operand, e.g. the last source operand in
94 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
96 aarch64_ins_reglane (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
97 aarch64_insn
*code
, const aarch64_inst
*inst
,
98 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
101 insert_field (self
->fields
[0], code
, info
->reglane
.regno
, inst
->opcode
->mask
);
102 /* index and/or type */
103 if (inst
->opcode
->iclass
== asisdone
|| inst
->opcode
->iclass
== asimdins
)
105 int pos
= info
->qualifier
- AARCH64_OPND_QLF_S_B
;
106 if (info
->type
== AARCH64_OPND_En
107 && inst
->opcode
->operands
[0] == AARCH64_OPND_Ed
)
109 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
110 assert (info
->idx
== 1); /* Vn */
111 aarch64_insn value
= info
->reglane
.index
<< pos
;
112 insert_field (FLD_imm4
, code
, value
, 0);
116 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
123 aarch64_insn value
= ((info
->reglane
.index
<< 1) | 1) << pos
;
124 insert_field (FLD_imm5
, code
, value
, 0);
127 else if (inst
->opcode
->iclass
== dotproduct
)
129 unsigned reglane_index
= info
->reglane
.index
;
130 switch (info
->qualifier
)
132 case AARCH64_OPND_QLF_S_4B
:
134 assert (reglane_index
< 4);
135 insert_fields (code
, reglane_index
, 0, 2, FLD_L
, FLD_H
);
141 else if (inst
->opcode
->iclass
== cryptosm3
)
143 /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
144 unsigned reglane_index
= info
->reglane
.index
;
145 assert (reglane_index
< 4);
146 insert_field (FLD_SM3_imm2
, code
, reglane_index
, 0);
150 /* index for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
151 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
152 unsigned reglane_index
= info
->reglane
.index
;
154 if (inst
->opcode
->op
== OP_FCMLA_ELEM
)
155 /* Complex operand takes two elements. */
158 switch (info
->qualifier
)
160 case AARCH64_OPND_QLF_S_H
:
162 assert (reglane_index
< 8);
163 insert_fields (code
, reglane_index
, 0, 3, FLD_M
, FLD_L
, FLD_H
);
165 case AARCH64_OPND_QLF_S_S
:
167 assert (reglane_index
< 4);
168 insert_fields (code
, reglane_index
, 0, 2, FLD_L
, FLD_H
);
170 case AARCH64_OPND_QLF_S_D
:
172 assert (reglane_index
< 2);
173 insert_field (FLD_H
, code
, reglane_index
, 0);
182 /* Insert regno and len field of a register list operand, e.g. Vn in TBL. */
184 aarch64_ins_reglist (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
186 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
187 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
190 insert_field (self
->fields
[0], code
, info
->reglist
.first_regno
, 0);
192 insert_field (FLD_len
, code
, info
->reglist
.num_regs
- 1, 0);
196 /* Insert Rt and opcode fields for a register list operand, e.g. Vt
197 in AdvSIMD load/store instructions. */
199 aarch64_ins_ldst_reglist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
200 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
201 const aarch64_inst
*inst
,
202 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
204 aarch64_insn value
= 0;
205 /* Number of elements in each structure to be loaded/stored. */
206 unsigned num
= get_opcode_dependent_value (inst
->opcode
);
209 insert_field (FLD_Rt
, code
, info
->reglist
.first_regno
, 0);
214 switch (info
->reglist
.num_regs
)
216 case 1: value
= 0x7; break;
217 case 2: value
= 0xa; break;
218 case 3: value
= 0x6; break;
219 case 4: value
= 0x2; break;
224 value
= info
->reglist
.num_regs
== 4 ? 0x3 : 0x8;
235 insert_field (FLD_opcode
, code
, value
, 0);
240 /* Insert Rt and S fields for a register list operand, e.g. Vt in AdvSIMD load
241 single structure to all lanes instructions. */
243 aarch64_ins_ldst_reglist_r (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
244 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
245 const aarch64_inst
*inst
,
246 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
249 /* The opcode dependent area stores the number of elements in
250 each structure to be loaded/stored. */
251 int is_ld1r
= get_opcode_dependent_value (inst
->opcode
) == 1;
254 insert_field (FLD_Rt
, code
, info
->reglist
.first_regno
, 0);
256 value
= (aarch64_insn
) 0;
257 if (is_ld1r
&& info
->reglist
.num_regs
== 2)
258 /* OP_LD1R does not have alternating variant, but have "two consecutive"
260 value
= (aarch64_insn
) 1;
261 insert_field (FLD_S
, code
, value
, 0);
266 /* Insert Q, opcode<2:1>, S, size and Rt fields for a register element list
267 operand e.g. Vt in AdvSIMD load/store single element instructions. */
269 aarch64_ins_ldst_elemlist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
270 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
271 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
272 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
274 aarch64_field field
= {0, 0};
275 aarch64_insn QSsize
= 0; /* fields Q:S:size. */
276 aarch64_insn opcodeh2
= 0; /* opcode<2:1> */
278 assert (info
->reglist
.has_index
);
281 insert_field (FLD_Rt
, code
, info
->reglist
.first_regno
, 0);
282 /* Encode the index, opcode<2:1> and size. */
283 switch (info
->qualifier
)
285 case AARCH64_OPND_QLF_S_B
:
286 /* Index encoded in "Q:S:size". */
287 QSsize
= info
->reglist
.index
;
290 case AARCH64_OPND_QLF_S_H
:
291 /* Index encoded in "Q:S:size<1>". */
292 QSsize
= info
->reglist
.index
<< 1;
295 case AARCH64_OPND_QLF_S_S
:
296 /* Index encoded in "Q:S". */
297 QSsize
= info
->reglist
.index
<< 2;
300 case AARCH64_OPND_QLF_S_D
:
301 /* Index encoded in "Q". */
302 QSsize
= info
->reglist
.index
<< 3 | 0x1;
308 insert_fields (code
, QSsize
, 0, 3, FLD_vldst_size
, FLD_S
, FLD_Q
);
309 gen_sub_field (FLD_asisdlso_opcode
, 1, 2, &field
);
310 insert_field_2 (&field
, code
, opcodeh2
, 0);
315 /* Insert fields immh:immb and/or Q for e.g. the shift immediate in
316 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
317 or SSHR <V><d>, <V><n>, #<shift>. */
319 aarch64_ins_advsimd_imm_shift (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
320 const aarch64_opnd_info
*info
,
321 aarch64_insn
*code
, const aarch64_inst
*inst
,
322 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
324 unsigned val
= aarch64_get_qualifier_standard_value (info
->qualifier
);
327 if (inst
->opcode
->iclass
== asimdshf
)
331 0000 x SEE AdvSIMD modified immediate
340 Q
= (val
& 0x1) ? 1 : 0;
341 insert_field (FLD_Q
, code
, Q
, inst
->opcode
->mask
);
345 assert (info
->type
== AARCH64_OPND_IMM_VLSR
346 || info
->type
== AARCH64_OPND_IMM_VLSL
);
348 if (info
->type
== AARCH64_OPND_IMM_VLSR
)
351 0000 SEE AdvSIMD modified immediate
352 0001 (16-UInt(immh:immb))
353 001x (32-UInt(immh:immb))
354 01xx (64-UInt(immh:immb))
355 1xxx (128-UInt(immh:immb)) */
356 imm
= (16 << (unsigned)val
) - info
->imm
.value
;
360 0000 SEE AdvSIMD modified immediate
361 0001 (UInt(immh:immb)-8)
362 001x (UInt(immh:immb)-16)
363 01xx (UInt(immh:immb)-32)
364 1xxx (UInt(immh:immb)-64) */
365 imm
= info
->imm
.value
+ (8 << (unsigned)val
);
366 insert_fields (code
, imm
, 0, 2, FLD_immb
, FLD_immh
);
371 /* Insert fields for e.g. the immediate operands in
372 BFM <Wd>, <Wn>, #<immr>, #<imms>. */
374 aarch64_ins_imm (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
376 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
377 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
381 imm
= info
->imm
.value
;
382 if (operand_need_shift_by_two (self
))
384 if (operand_need_shift_by_four (self
))
386 insert_all_fields (self
, code
, imm
);
390 /* Insert immediate and its shift amount for e.g. the last operand in
391 MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
393 aarch64_ins_imm_half (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
394 aarch64_insn
*code
, const aarch64_inst
*inst
,
395 aarch64_operand_error
*errors
)
398 aarch64_ins_imm (self
, info
, code
, inst
, errors
);
400 insert_field (FLD_hw
, code
, info
->shifter
.amount
>> 4, 0);
404 /* Insert cmode and "a:b:c:d:e:f:g:h" fields for e.g. the last operand in
405 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
407 aarch64_ins_advsimd_imm_modified (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
408 const aarch64_opnd_info
*info
,
410 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
411 aarch64_operand_error
*errors
414 enum aarch64_opnd_qualifier opnd0_qualifier
= inst
->operands
[0].qualifier
;
415 uint64_t imm
= info
->imm
.value
;
416 enum aarch64_modifier_kind kind
= info
->shifter
.kind
;
417 int amount
= info
->shifter
.amount
;
418 aarch64_field field
= {0, 0};
420 /* a:b:c:d:e:f:g:h */
421 if (!info
->imm
.is_fp
&& aarch64_get_qualifier_esize (opnd0_qualifier
) == 8)
423 /* Either MOVI <Dd>, #<imm>
424 or MOVI <Vd>.2D, #<imm>.
425 <imm> is a 64-bit immediate
426 "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
427 encoded in "a:b:c:d:e:f:g:h". */
428 imm
= aarch64_shrink_expanded_imm8 (imm
);
429 assert ((int)imm
>= 0);
431 insert_fields (code
, imm
, 0, 2, FLD_defgh
, FLD_abc
);
433 if (kind
== AARCH64_MOD_NONE
)
436 /* shift amount partially in cmode */
437 assert (kind
== AARCH64_MOD_LSL
|| kind
== AARCH64_MOD_MSL
);
438 if (kind
== AARCH64_MOD_LSL
)
440 /* AARCH64_MOD_LSL: shift zeros. */
441 int esize
= aarch64_get_qualifier_esize (opnd0_qualifier
);
442 assert (esize
== 4 || esize
== 2 || esize
== 1);
443 /* For 8-bit move immediate, the optional LSL #0 does not require
449 gen_sub_field (FLD_cmode
, 1, 2, &field
); /* per word */
451 gen_sub_field (FLD_cmode
, 1, 1, &field
); /* per halfword */
455 /* AARCH64_MOD_MSL: shift ones. */
457 gen_sub_field (FLD_cmode
, 0, 1, &field
); /* per word */
459 insert_field_2 (&field
, code
, amount
, 0);
464 /* Insert fields for an 8-bit floating-point immediate. */
466 aarch64_ins_fpimm (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
468 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
469 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
471 insert_all_fields (self
, code
, info
->imm
.value
);
475 /* Insert 1-bit rotation immediate (#90 or #270). */
477 aarch64_ins_imm_rotate1 (const aarch64_operand
*self
,
478 const aarch64_opnd_info
*info
,
479 aarch64_insn
*code
, const aarch64_inst
*inst
,
480 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
482 uint64_t rot
= (info
->imm
.value
- 90) / 180;
484 insert_field (self
->fields
[0], code
, rot
, inst
->opcode
->mask
);
488 /* Insert 2-bit rotation immediate (#0, #90, #180 or #270). */
490 aarch64_ins_imm_rotate2 (const aarch64_operand
*self
,
491 const aarch64_opnd_info
*info
,
492 aarch64_insn
*code
, const aarch64_inst
*inst
,
493 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
495 uint64_t rot
= info
->imm
.value
/ 90;
497 insert_field (self
->fields
[0], code
, rot
, inst
->opcode
->mask
);
501 /* Insert #<fbits> for the immediate operand in fp fix-point instructions,
502 e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
504 aarch64_ins_fbits (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
506 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
507 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
509 insert_field (self
->fields
[0], code
, 64 - info
->imm
.value
, 0);
513 /* Insert arithmetic immediate for e.g. the last operand in
514 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
516 aarch64_ins_aimm (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
517 aarch64_insn
*code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
518 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
521 aarch64_insn value
= info
->shifter
.amount
? 1 : 0;
522 insert_field (self
->fields
[0], code
, value
, 0);
523 /* imm12 (unsigned) */
524 insert_field (self
->fields
[1], code
, info
->imm
.value
, 0);
528 /* Common routine shared by aarch64_ins{,_inv}_limm. INVERT_P says whether
529 the operand should be inverted before encoding. */
531 aarch64_ins_limm_1 (const aarch64_operand
*self
,
532 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
533 const aarch64_inst
*inst
, bfd_boolean invert_p
,
534 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
537 uint64_t imm
= info
->imm
.value
;
538 int esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
542 /* The constraint check should have guaranteed this wouldn't happen. */
543 assert (aarch64_logical_immediate_p (imm
, esize
, &value
));
545 insert_fields (code
, value
, 0, 3, self
->fields
[2], self
->fields
[1],
550 /* Insert logical/bitmask immediate for e.g. the last operand in
551 ORR <Wd|WSP>, <Wn>, #<imm>. */
553 aarch64_ins_limm (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
554 aarch64_insn
*code
, const aarch64_inst
*inst
,
555 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
557 return aarch64_ins_limm_1 (self
, info
, code
, inst
,
558 inst
->opcode
->op
== OP_BIC
, errors
);
561 /* Insert a logical/bitmask immediate for the BIC alias of AND (etc.). */
563 aarch64_ins_inv_limm (const aarch64_operand
*self
,
564 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
565 const aarch64_inst
*inst
,
566 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
568 return aarch64_ins_limm_1 (self
, info
, code
, inst
, TRUE
, errors
);
571 /* Encode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
572 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
574 aarch64_ins_ft (const aarch64_operand
*self
, const aarch64_opnd_info
*info
,
575 aarch64_insn
*code
, const aarch64_inst
*inst
,
576 aarch64_operand_error
*errors
)
578 aarch64_insn value
= 0;
580 assert (info
->idx
== 0);
583 aarch64_ins_regno (self
, info
, code
, inst
, errors
);
584 if (inst
->opcode
->iclass
== ldstpair_indexed
585 || inst
->opcode
->iclass
== ldstnapair_offs
586 || inst
->opcode
->iclass
== ldstpair_off
587 || inst
->opcode
->iclass
== loadlit
)
590 switch (info
->qualifier
)
592 case AARCH64_OPND_QLF_S_S
: value
= 0; break;
593 case AARCH64_OPND_QLF_S_D
: value
= 1; break;
594 case AARCH64_OPND_QLF_S_Q
: value
= 2; break;
597 insert_field (FLD_ldst_size
, code
, value
, 0);
602 value
= aarch64_get_qualifier_standard_value (info
->qualifier
);
603 insert_fields (code
, value
, 0, 2, FLD_ldst_size
, FLD_opc1
);
609 /* Encode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
611 aarch64_ins_addr_simple (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
612 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
613 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
614 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
617 insert_field (FLD_Rn
, code
, info
->addr
.base_regno
, 0);
621 /* Encode the address operand for e.g.
622 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
624 aarch64_ins_addr_regoff (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
625 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
626 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
627 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
630 enum aarch64_modifier_kind kind
= info
->shifter
.kind
;
633 insert_field (FLD_Rn
, code
, info
->addr
.base_regno
, 0);
635 insert_field (FLD_Rm
, code
, info
->addr
.offset
.regno
, 0);
637 if (kind
== AARCH64_MOD_LSL
)
638 kind
= AARCH64_MOD_UXTX
; /* Trick to enable the table-driven. */
639 insert_field (FLD_option
, code
, aarch64_get_operand_modifier_value (kind
), 0);
641 if (info
->qualifier
!= AARCH64_OPND_QLF_S_B
)
642 S
= info
->shifter
.amount
!= 0;
644 /* For STR <Bt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}},
648 Must be #0 if <extend> is explicitly LSL. */
649 S
= info
->shifter
.operator_present
&& info
->shifter
.amount_present
;
650 insert_field (FLD_S
, code
, S
, 0);
655 /* Encode the address operand for e.g.
656 stlur <Xt>, [<Xn|SP>{, <amount>}]. */
658 aarch64_ins_addr_offset (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
659 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
660 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
661 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
664 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
667 int imm
= info
->addr
.offset
.imm
;
668 insert_field (self
->fields
[1], code
, imm
, 0);
671 if (info
->addr
.writeback
)
673 assert (info
->addr
.preind
== 1 && info
->addr
.postind
== 0);
674 insert_field (self
->fields
[2], code
, 1, 0);
679 /* Encode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>, #<simm>]!. */
681 aarch64_ins_addr_simm (const aarch64_operand
*self
,
682 const aarch64_opnd_info
*info
,
684 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
685 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
690 insert_field (FLD_Rn
, code
, info
->addr
.base_regno
, 0);
691 /* simm (imm9 or imm7) */
692 imm
= info
->addr
.offset
.imm
;
693 if (self
->fields
[0] == FLD_imm7
694 || info
->qualifier
== AARCH64_OPND_QLF_imm_tag
)
695 /* scaled immediate in ld/st pair instructions.. */
696 imm
>>= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
697 insert_field (self
->fields
[0], code
, imm
, 0);
698 /* pre/post- index */
699 if (info
->addr
.writeback
)
701 assert (inst
->opcode
->iclass
!= ldst_unscaled
702 && inst
->opcode
->iclass
!= ldstnapair_offs
703 && inst
->opcode
->iclass
!= ldstpair_off
704 && inst
->opcode
->iclass
!= ldst_unpriv
);
705 assert (info
->addr
.preind
!= info
->addr
.postind
);
706 if (info
->addr
.preind
)
707 insert_field (self
->fields
[1], code
, 1, 0);
713 /* Encode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
715 aarch64_ins_addr_simm10 (const aarch64_operand
*self
,
716 const aarch64_opnd_info
*info
,
718 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
719 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
724 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
726 imm
= info
->addr
.offset
.imm
>> 3;
727 insert_field (self
->fields
[1], code
, imm
>> 9, 0);
728 insert_field (self
->fields
[2], code
, imm
, 0);
730 if (info
->addr
.writeback
)
732 assert (info
->addr
.preind
== 1 && info
->addr
.postind
== 0);
733 insert_field (self
->fields
[3], code
, 1, 0);
738 /* Encode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]. */
740 aarch64_ins_addr_uimm12 (const aarch64_operand
*self
,
741 const aarch64_opnd_info
*info
,
743 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
744 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
746 int shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
749 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
751 insert_field (self
->fields
[1], code
,info
->addr
.offset
.imm
>> shift
, 0);
755 /* Encode the address operand for e.g.
756 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
758 aarch64_ins_simd_addr_post (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
759 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
760 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
761 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
764 insert_field (FLD_Rn
, code
, info
->addr
.base_regno
, 0);
766 if (info
->addr
.offset
.is_reg
)
767 insert_field (FLD_Rm
, code
, info
->addr
.offset
.regno
, 0);
769 insert_field (FLD_Rm
, code
, 0x1f, 0);
773 /* Encode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
775 aarch64_ins_cond (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
776 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
777 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
778 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
781 insert_field (FLD_cond
, code
, info
->cond
->value
, 0);
785 /* Encode the system register operand for e.g. MRS <Xt>, <systemreg>. */
787 aarch64_ins_sysreg (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
788 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
789 const aarch64_inst
*inst
,
790 aarch64_operand_error
*detail ATTRIBUTE_UNUSED
)
792 /* If a system instruction check if we have any restrictions on which
793 registers it can use. */
794 if (inst
->opcode
->iclass
== ic_system
)
796 uint64_t opcode_flags
797 = inst
->opcode
->flags
& (F_SYS_READ
| F_SYS_WRITE
);
798 uint32_t sysreg_flags
799 = info
->sysreg
.flags
& (F_REG_READ
| F_REG_WRITE
);
801 /* Check to see if it's read-only, else check if it's write only.
802 if it's both or unspecified don't care. */
803 if (opcode_flags
== F_SYS_READ
805 && sysreg_flags
!= F_REG_READ
)
807 detail
->kind
= AARCH64_OPDE_SYNTAX_ERROR
;
808 detail
->error
= _("specified register cannot be read from");
809 detail
->index
= info
->idx
;
810 detail
->non_fatal
= TRUE
;
812 else if (opcode_flags
== F_SYS_WRITE
814 && sysreg_flags
!= F_REG_WRITE
)
816 detail
->kind
= AARCH64_OPDE_SYNTAX_ERROR
;
817 detail
->error
= _("specified register cannot be written to");
818 detail
->index
= info
->idx
;
819 detail
->non_fatal
= TRUE
;
822 /* op0:op1:CRn:CRm:op2 */
823 insert_fields (code
, info
->sysreg
.value
, inst
->opcode
->mask
, 5,
824 FLD_op2
, FLD_CRm
, FLD_CRn
, FLD_op1
, FLD_op0
);
828 /* Encode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
830 aarch64_ins_pstatefield (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
831 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
832 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
833 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
836 insert_fields (code
, info
->pstatefield
, inst
->opcode
->mask
, 2,
841 /* Encode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
843 aarch64_ins_sysins_op (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
844 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
845 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
846 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
848 /* op1:CRn:CRm:op2 */
849 insert_fields (code
, info
->sysins_op
->value
, inst
->opcode
->mask
, 4,
850 FLD_op2
, FLD_CRm
, FLD_CRn
, FLD_op1
);
854 /* Encode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
857 aarch64_ins_barrier (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
858 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
859 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
860 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
863 insert_field (FLD_CRm
, code
, info
->barrier
->value
, 0);
867 /* Encode the prefetch operation option operand for e.g.
868 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
871 aarch64_ins_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
872 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
873 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
874 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
877 insert_field (FLD_Rt
, code
, info
->prfop
->value
, 0);
881 /* Encode the hint number for instructions that alias HINT but take an
885 aarch64_ins_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
886 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
887 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
888 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
891 insert_fields (code
, info
->hint_option
->value
, 0, 2, FLD_op2
, FLD_CRm
);
895 /* Encode the extended register operand for e.g.
896 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
898 aarch64_ins_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
899 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
900 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
901 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
903 enum aarch64_modifier_kind kind
;
906 insert_field (FLD_Rm
, code
, info
->reg
.regno
, 0);
908 kind
= info
->shifter
.kind
;
909 if (kind
== AARCH64_MOD_LSL
)
910 kind
= info
->qualifier
== AARCH64_OPND_QLF_W
911 ? AARCH64_MOD_UXTW
: AARCH64_MOD_UXTX
;
912 insert_field (FLD_option
, code
, aarch64_get_operand_modifier_value (kind
), 0);
914 insert_field (FLD_imm3
, code
, info
->shifter
.amount
, 0);
919 /* Encode the shifted register operand for e.g.
920 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
922 aarch64_ins_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
923 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
924 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
925 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
928 insert_field (FLD_Rm
, code
, info
->reg
.regno
, 0);
930 insert_field (FLD_shift
, code
,
931 aarch64_get_operand_modifier_value (info
->shifter
.kind
), 0);
933 insert_field (FLD_imm6
, code
, info
->shifter
.amount
, 0);
938 /* Encode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
939 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
940 SELF's operand-dependent value. fields[0] specifies the field that
941 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
943 aarch64_ins_sve_addr_ri_s4xvl (const aarch64_operand
*self
,
944 const aarch64_opnd_info
*info
,
946 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
947 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
949 int factor
= 1 + get_operand_specific_data (self
);
950 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
951 insert_field (FLD_SVE_imm4
, code
, info
->addr
.offset
.imm
/ factor
, 0);
955 /* Encode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
956 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
957 SELF's operand-dependent value. fields[0] specifies the field that
958 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
960 aarch64_ins_sve_addr_ri_s6xvl (const aarch64_operand
*self
,
961 const aarch64_opnd_info
*info
,
963 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
964 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
966 int factor
= 1 + get_operand_specific_data (self
);
967 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
968 insert_field (FLD_SVE_imm6
, code
, info
->addr
.offset
.imm
/ factor
, 0);
972 /* Encode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
973 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
974 SELF's operand-dependent value. fields[0] specifies the field that
975 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
976 and imm3 fields, with imm3 being the less-significant part. */
978 aarch64_ins_sve_addr_ri_s9xvl (const aarch64_operand
*self
,
979 const aarch64_opnd_info
*info
,
981 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
982 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
984 int factor
= 1 + get_operand_specific_data (self
);
985 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
986 insert_fields (code
, info
->addr
.offset
.imm
/ factor
, 0,
987 2, FLD_imm3
, FLD_SVE_imm6
);
991 /* Encode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
992 is a 4-bit signed number and where <shift> is SELF's operand-dependent
993 value. fields[0] specifies the base register field. */
995 aarch64_ins_sve_addr_ri_s4 (const aarch64_operand
*self
,
996 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
997 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
998 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1000 int factor
= 1 << get_operand_specific_data (self
);
1001 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1002 insert_field (FLD_SVE_imm4
, code
, info
->addr
.offset
.imm
/ factor
, 0);
1006 /* Encode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1007 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1008 value. fields[0] specifies the base register field. */
1010 aarch64_ins_sve_addr_ri_u6 (const aarch64_operand
*self
,
1011 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1012 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1013 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1015 int factor
= 1 << get_operand_specific_data (self
);
1016 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1017 insert_field (FLD_SVE_imm6
, code
, info
->addr
.offset
.imm
/ factor
, 0);
1021 /* Encode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1022 is SELF's operand-dependent value. fields[0] specifies the base
1023 register field and fields[1] specifies the offset register field. */
1025 aarch64_ins_sve_addr_rr_lsl (const aarch64_operand
*self
,
1026 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1027 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1028 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1030 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1031 insert_field (self
->fields
[1], code
, info
->addr
.offset
.regno
, 0);
1035 /* Encode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1036 <shift> is SELF's operand-dependent value. fields[0] specifies the
1037 base register field, fields[1] specifies the offset register field and
1038 fields[2] is a single-bit field that selects SXTW over UXTW. */
1040 aarch64_ins_sve_addr_rz_xtw (const aarch64_operand
*self
,
1041 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1042 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1043 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1045 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1046 insert_field (self
->fields
[1], code
, info
->addr
.offset
.regno
, 0);
1047 if (info
->shifter
.kind
== AARCH64_MOD_UXTW
)
1048 insert_field (self
->fields
[2], code
, 0, 0);
1050 insert_field (self
->fields
[2], code
, 1, 0);
1054 /* Encode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1055 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1056 fields[0] specifies the base register field. */
1058 aarch64_ins_sve_addr_zi_u5 (const aarch64_operand
*self
,
1059 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1060 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1061 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1063 int factor
= 1 << get_operand_specific_data (self
);
1064 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1065 insert_field (FLD_imm5
, code
, info
->addr
.offset
.imm
/ factor
, 0);
1069 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1070 where <modifier> is fixed by the instruction and where <msz> is a
1071 2-bit unsigned number. fields[0] specifies the base register field
1072 and fields[1] specifies the offset register field. */
1074 aarch64_ext_sve_addr_zz (const aarch64_operand
*self
,
1075 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1076 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1078 insert_field (self
->fields
[0], code
, info
->addr
.base_regno
, 0);
1079 insert_field (self
->fields
[1], code
, info
->addr
.offset
.regno
, 0);
1080 insert_field (FLD_SVE_msz
, code
, info
->shifter
.amount
, 0);
1084 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1085 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1086 field and fields[1] specifies the offset register field. */
1088 aarch64_ins_sve_addr_zz_lsl (const aarch64_operand
*self
,
1089 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1090 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1091 aarch64_operand_error
*errors
)
1093 return aarch64_ext_sve_addr_zz (self
, info
, code
, errors
);
1096 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1097 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1098 field and fields[1] specifies the offset register field. */
1100 aarch64_ins_sve_addr_zz_sxtw (const aarch64_operand
*self
,
1101 const aarch64_opnd_info
*info
,
1103 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1104 aarch64_operand_error
*errors
)
1106 return aarch64_ext_sve_addr_zz (self
, info
, code
, errors
);
1109 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1110 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1111 field and fields[1] specifies the offset register field. */
1113 aarch64_ins_sve_addr_zz_uxtw (const aarch64_operand
*self
,
1114 const aarch64_opnd_info
*info
,
1116 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1117 aarch64_operand_error
*errors
)
1119 return aarch64_ext_sve_addr_zz (self
, info
, code
, errors
);
1122 /* Encode an SVE ADD/SUB immediate. */
1124 aarch64_ins_sve_aimm (const aarch64_operand
*self
,
1125 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1126 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1127 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1129 if (info
->shifter
.amount
== 8)
1130 insert_all_fields (self
, code
, (info
->imm
.value
& 0xff) | 256);
1131 else if (info
->imm
.value
!= 0 && (info
->imm
.value
& 0xff) == 0)
1132 insert_all_fields (self
, code
, ((info
->imm
.value
/ 256) & 0xff) | 256);
1134 insert_all_fields (self
, code
, info
->imm
.value
& 0xff);
1138 /* Encode an SVE CPY/DUP immediate. */
1140 aarch64_ins_sve_asimm (const aarch64_operand
*self
,
1141 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1142 const aarch64_inst
*inst
,
1143 aarch64_operand_error
*errors
)
1145 return aarch64_ins_sve_aimm (self
, info
, code
, inst
, errors
);
1148 /* Encode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1149 array specifies which field to use for Zn. MM is encoded in the
1150 concatenation of imm5 and SVE_tszh, with imm5 being the less
1151 significant part. */
1153 aarch64_ins_sve_index (const aarch64_operand
*self
,
1154 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1155 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1156 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1158 unsigned int esize
= aarch64_get_qualifier_esize (info
->qualifier
);
1159 insert_field (self
->fields
[0], code
, info
->reglane
.regno
, 0);
1160 insert_fields (code
, (info
->reglane
.index
* 2 + 1) * esize
, 0,
1161 2, FLD_imm5
, FLD_SVE_tszh
);
1165 /* Encode a logical/bitmask immediate for the MOV alias of SVE DUPM. */
1167 aarch64_ins_sve_limm_mov (const aarch64_operand
*self
,
1168 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1169 const aarch64_inst
*inst
,
1170 aarch64_operand_error
*errors
)
1172 return aarch64_ins_limm (self
, info
, code
, inst
, errors
);
1175 /* Encode Zn[MM], where Zn occupies the least-significant part of the field
1176 and where MM occupies the most-significant part. The operand-dependent
1177 value specifies the number of bits in Zn. */
1179 aarch64_ins_sve_quad_index (const aarch64_operand
*self
,
1180 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1181 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1182 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1184 unsigned int reg_bits
= get_operand_specific_data (self
);
1185 assert (info
->reglane
.regno
< (1U << reg_bits
));
1186 unsigned int val
= (info
->reglane
.index
<< reg_bits
) + info
->reglane
.regno
;
1187 insert_all_fields (self
, code
, val
);
1191 /* Encode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1194 aarch64_ins_sve_reglist (const aarch64_operand
*self
,
1195 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1196 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1197 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1199 insert_field (self
->fields
[0], code
, info
->reglist
.first_regno
, 0);
1203 /* Encode <pattern>{, MUL #<amount>}. The fields array specifies which
1204 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1207 aarch64_ins_sve_scale (const aarch64_operand
*self
,
1208 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1209 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1210 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1212 insert_all_fields (self
, code
, info
->imm
.value
);
1213 insert_field (FLD_SVE_imm4
, code
, info
->shifter
.amount
- 1, 0);
1217 /* Encode an SVE shift left immediate. */
1219 aarch64_ins_sve_shlimm (const aarch64_operand
*self
,
1220 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1221 const aarch64_inst
*inst
,
1222 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1224 const aarch64_opnd_info
*prev_operand
;
1227 assert (info
->idx
> 0);
1228 prev_operand
= &inst
->operands
[info
->idx
- 1];
1229 esize
= aarch64_get_qualifier_esize (prev_operand
->qualifier
);
1230 insert_all_fields (self
, code
, 8 * esize
+ info
->imm
.value
);
1234 /* Encode an SVE shift right immediate. */
1236 aarch64_ins_sve_shrimm (const aarch64_operand
*self
,
1237 const aarch64_opnd_info
*info
, aarch64_insn
*code
,
1238 const aarch64_inst
*inst
,
1239 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1241 const aarch64_opnd_info
*prev_operand
;
1244 unsigned int opnd_backshift
= get_operand_specific_data (self
);
1245 assert (info
->idx
>= (int)opnd_backshift
);
1246 prev_operand
= &inst
->operands
[info
->idx
- opnd_backshift
];
1247 esize
= aarch64_get_qualifier_esize (prev_operand
->qualifier
);
1248 insert_all_fields (self
, code
, 16 * esize
- info
->imm
.value
);
1252 /* Encode a single-bit immediate that selects between #0.5 and #1.0.
1253 The fields array specifies which field to use. */
1255 aarch64_ins_sve_float_half_one (const aarch64_operand
*self
,
1256 const aarch64_opnd_info
*info
,
1258 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1259 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1261 if (info
->imm
.value
== 0x3f000000)
1262 insert_field (self
->fields
[0], code
, 0, 0);
1264 insert_field (self
->fields
[0], code
, 1, 0);
1268 /* Encode a single-bit immediate that selects between #0.5 and #2.0.
1269 The fields array specifies which field to use. */
1271 aarch64_ins_sve_float_half_two (const aarch64_operand
*self
,
1272 const aarch64_opnd_info
*info
,
1274 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1275 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1277 if (info
->imm
.value
== 0x3f000000)
1278 insert_field (self
->fields
[0], code
, 0, 0);
1280 insert_field (self
->fields
[0], code
, 1, 0);
1284 /* Encode a single-bit immediate that selects between #0.0 and #1.0.
1285 The fields array specifies which field to use. */
1287 aarch64_ins_sve_float_zero_one (const aarch64_operand
*self
,
1288 const aarch64_opnd_info
*info
,
1290 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1291 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1293 if (info
->imm
.value
== 0)
1294 insert_field (self
->fields
[0], code
, 0, 0);
1296 insert_field (self
->fields
[0], code
, 1, 0);
1300 /* Miscellaneous encoding functions. */
1302 /* Encode size[0], i.e. bit 22, for
1303 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1306 encode_asimd_fcvt (aarch64_inst
*inst
)
1309 aarch64_field field
= {0, 0};
1310 enum aarch64_opnd_qualifier qualifier
;
1312 switch (inst
->opcode
->op
)
1316 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1317 qualifier
= inst
->operands
[1].qualifier
;
1321 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1322 qualifier
= inst
->operands
[0].qualifier
;
1327 assert (qualifier
== AARCH64_OPND_QLF_V_4S
1328 || qualifier
== AARCH64_OPND_QLF_V_2D
);
1329 value
= (qualifier
== AARCH64_OPND_QLF_V_4S
) ? 0 : 1;
1330 gen_sub_field (FLD_size
, 0, 1, &field
);
1331 insert_field_2 (&field
, &inst
->value
, value
, 0);
1334 /* Encode size[0], i.e. bit 22, for
1335 e.g. FCVTXN <Vb><d>, <Va><n>. */
1338 encode_asisd_fcvtxn (aarch64_inst
*inst
)
1340 aarch64_insn val
= 1;
1341 aarch64_field field
= {0, 0};
1342 assert (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_S_S
);
1343 gen_sub_field (FLD_size
, 0, 1, &field
);
1344 insert_field_2 (&field
, &inst
->value
, val
, 0);
1347 /* Encode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1349 encode_fcvt (aarch64_inst
*inst
)
1352 const aarch64_field field
= {15, 2};
1355 switch (inst
->operands
[0].qualifier
)
1357 case AARCH64_OPND_QLF_S_S
: val
= 0; break;
1358 case AARCH64_OPND_QLF_S_D
: val
= 1; break;
1359 case AARCH64_OPND_QLF_S_H
: val
= 3; break;
1362 insert_field_2 (&field
, &inst
->value
, val
, 0);
1367 /* Return the index in qualifiers_list that INST is using. Should only
1368 be called once the qualifiers are known to be valid. */
1371 aarch64_get_variant (struct aarch64_inst
*inst
)
1373 int i
, nops
, variant
;
1375 nops
= aarch64_num_of_operands (inst
->opcode
);
1376 for (variant
= 0; variant
< AARCH64_MAX_QLF_SEQ_NUM
; ++variant
)
1378 for (i
= 0; i
< nops
; ++i
)
1379 if (inst
->opcode
->qualifiers_list
[variant
][i
]
1380 != inst
->operands
[i
].qualifier
)
1388 /* Do miscellaneous encodings that are not common enough to be driven by
1392 do_misc_encoding (aarch64_inst
*inst
)
1396 switch (inst
->opcode
->op
)
1405 encode_asimd_fcvt (inst
);
1408 encode_asisd_fcvtxn (inst
);
1412 /* Copy Pn to Pm and Pg. */
1413 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
1414 insert_field (FLD_SVE_Pm
, &inst
->value
, value
, 0);
1415 insert_field (FLD_SVE_Pg4_10
, &inst
->value
, value
, 0);
1418 /* Copy Zd to Zm. */
1419 value
= extract_field (FLD_SVE_Zd
, inst
->value
, 0);
1420 insert_field (FLD_SVE_Zm_16
, &inst
->value
, value
, 0);
1423 /* Fill in the zero immediate. */
1424 insert_fields (&inst
->value
, 1 << aarch64_get_variant (inst
), 0,
1425 2, FLD_imm5
, FLD_SVE_tszh
);
1428 /* Copy Zn to Zm. */
1429 value
= extract_field (FLD_SVE_Zn
, inst
->value
, 0);
1430 insert_field (FLD_SVE_Zm_16
, &inst
->value
, value
, 0);
1435 /* Copy Pd to Pm. */
1436 value
= extract_field (FLD_SVE_Pd
, inst
->value
, 0);
1437 insert_field (FLD_SVE_Pm
, &inst
->value
, value
, 0);
1439 case OP_MOVZS_P_P_P
:
1441 /* Copy Pn to Pm. */
1442 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
1443 insert_field (FLD_SVE_Pm
, &inst
->value
, value
, 0);
1445 case OP_NOTS_P_P_P_Z
:
1446 case OP_NOT_P_P_P_Z
:
1447 /* Copy Pg to Pm. */
1448 value
= extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0);
1449 insert_field (FLD_SVE_Pm
, &inst
->value
, value
, 0);
1455 /* Encode the 'size' and 'Q' field for e.g. SHADD. */
1457 encode_sizeq (aarch64_inst
*inst
)
1460 enum aarch64_field_kind kind
;
1463 /* Get the index of the operand whose information we are going to use
1464 to encode the size and Q fields.
1465 This is deduced from the possible valid qualifier lists. */
1466 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
1467 DEBUG_TRACE ("idx: %d; qualifier: %s", idx
,
1468 aarch64_get_qualifier_name (inst
->operands
[idx
].qualifier
));
1469 sizeq
= aarch64_get_qualifier_standard_value (inst
->operands
[idx
].qualifier
);
1471 insert_field (FLD_Q
, &inst
->value
, sizeq
& 0x1, inst
->opcode
->mask
);
1473 if (inst
->opcode
->iclass
== asisdlse
1474 || inst
->opcode
->iclass
== asisdlsep
1475 || inst
->opcode
->iclass
== asisdlso
1476 || inst
->opcode
->iclass
== asisdlsop
)
1477 kind
= FLD_vldst_size
;
1480 insert_field (kind
, &inst
->value
, (sizeq
>> 1) & 0x3, inst
->opcode
->mask
);
1483 /* Opcodes that have fields shared by multiple operands are usually flagged
1484 with flags. In this function, we detect such flags and use the
1485 information in one of the related operands to do the encoding. The 'one'
1486 operand is not any operand but one of the operands that has the enough
1487 information for such an encoding. */
1490 do_special_encoding (struct aarch64_inst
*inst
)
1493 aarch64_insn value
= 0;
1495 DEBUG_TRACE ("enter with coding 0x%x", (uint32_t) inst
->value
);
1497 /* Condition for truly conditional executed instructions, e.g. b.cond. */
1498 if (inst
->opcode
->flags
& F_COND
)
1500 insert_field (FLD_cond2
, &inst
->value
, inst
->cond
->value
, 0);
1502 if (inst
->opcode
->flags
& F_SF
)
1504 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
1505 value
= (inst
->operands
[idx
].qualifier
== AARCH64_OPND_QLF_X
1506 || inst
->operands
[idx
].qualifier
== AARCH64_OPND_QLF_SP
)
1508 insert_field (FLD_sf
, &inst
->value
, value
, 0);
1509 if (inst
->opcode
->flags
& F_N
)
1510 insert_field (FLD_N
, &inst
->value
, value
, inst
->opcode
->mask
);
1512 if (inst
->opcode
->flags
& F_LSE_SZ
)
1514 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
1515 value
= (inst
->operands
[idx
].qualifier
== AARCH64_OPND_QLF_X
1516 || inst
->operands
[idx
].qualifier
== AARCH64_OPND_QLF_SP
)
1518 insert_field (FLD_lse_sz
, &inst
->value
, value
, 0);
1520 if (inst
->opcode
->flags
& F_SIZEQ
)
1521 encode_sizeq (inst
);
1522 if (inst
->opcode
->flags
& F_FPTYPE
)
1524 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
1525 switch (inst
->operands
[idx
].qualifier
)
1527 case AARCH64_OPND_QLF_S_S
: value
= 0; break;
1528 case AARCH64_OPND_QLF_S_D
: value
= 1; break;
1529 case AARCH64_OPND_QLF_S_H
: value
= 3; break;
1530 default: assert (0);
1532 insert_field (FLD_type
, &inst
->value
, value
, 0);
1534 if (inst
->opcode
->flags
& F_SSIZE
)
1536 enum aarch64_opnd_qualifier qualifier
;
1537 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
1538 qualifier
= inst
->operands
[idx
].qualifier
;
1539 assert (qualifier
>= AARCH64_OPND_QLF_S_B
1540 && qualifier
<= AARCH64_OPND_QLF_S_Q
);
1541 value
= aarch64_get_qualifier_standard_value (qualifier
);
1542 insert_field (FLD_size
, &inst
->value
, value
, inst
->opcode
->mask
);
1544 if (inst
->opcode
->flags
& F_T
)
1546 int num
; /* num of consecutive '0's on the right side of imm5<3:0>. */
1547 aarch64_field field
= {0, 0};
1548 enum aarch64_opnd_qualifier qualifier
;
1551 qualifier
= inst
->operands
[idx
].qualifier
;
1552 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
1553 == AARCH64_OPND_CLASS_SIMD_REG
1554 && qualifier
>= AARCH64_OPND_QLF_V_8B
1555 && qualifier
<= AARCH64_OPND_QLF_V_2D
);
1566 value
= aarch64_get_qualifier_standard_value (qualifier
);
1567 insert_field (FLD_Q
, &inst
->value
, value
& 0x1, inst
->opcode
->mask
);
1568 num
= (int) value
>> 1;
1569 assert (num
>= 0 && num
<= 3);
1570 gen_sub_field (FLD_imm5
, 0, num
+ 1, &field
);
1571 insert_field_2 (&field
, &inst
->value
, 1 << num
, inst
->opcode
->mask
);
1573 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
1575 /* Use Rt to encode in the case of e.g.
1576 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
1577 enum aarch64_opnd_qualifier qualifier
;
1578 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
1580 /* Otherwise use the result operand, which has to be a integer
1583 assert (idx
== 0 || idx
== 1);
1584 assert (aarch64_get_operand_class (inst
->opcode
->operands
[idx
])
1585 == AARCH64_OPND_CLASS_INT_REG
);
1586 qualifier
= inst
->operands
[idx
].qualifier
;
1587 insert_field (FLD_Q
, &inst
->value
,
1588 aarch64_get_qualifier_standard_value (qualifier
), 0);
1590 if (inst
->opcode
->flags
& F_LDS_SIZE
)
1592 /* e.g. LDRSB <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1593 enum aarch64_opnd_qualifier qualifier
;
1594 aarch64_field field
= {0, 0};
1595 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
1596 == AARCH64_OPND_CLASS_INT_REG
);
1597 gen_sub_field (FLD_opc
, 0, 1, &field
);
1598 qualifier
= inst
->operands
[0].qualifier
;
1599 insert_field_2 (&field
, &inst
->value
,
1600 1 - aarch64_get_qualifier_standard_value (qualifier
), 0);
1602 /* Miscellaneous encoding as the last step. */
1603 if (inst
->opcode
->flags
& F_MISC
)
1604 do_misc_encoding (inst
);
1606 DEBUG_TRACE ("exit with coding 0x%x", (uint32_t) inst
->value
);
1609 /* Some instructions (including all SVE ones) use the instruction class
1610 to describe how a qualifiers_list index is represented in the instruction
1611 encoding. If INST is such an instruction, encode the chosen qualifier
1615 aarch64_encode_variant_using_iclass (struct aarch64_inst
*inst
)
1618 switch (inst
->opcode
->iclass
)
1621 insert_fields (&inst
->value
, aarch64_get_variant (inst
),
1622 0, 2, FLD_SVE_M_14
, FLD_size
);
1626 case sve_shift_pred
:
1627 case sve_shift_unpred
:
1628 case sve_shift_tsz_hsd
:
1629 case sve_shift_tsz_bhsd
:
1630 /* For indices and shift amounts, the variant is encoded as
1631 part of the immediate. */
1635 /* For sve_limm, the .B, .H, and .S forms are just a convenience
1636 and depend on the immediate. They don't have a separate
1641 /* sve_misc instructions have only a single variant. */
1645 insert_fields (&inst
->value
, aarch64_get_variant (inst
),
1646 0, 2, FLD_SVE_M_16
, FLD_size
);
1650 insert_field (FLD_SVE_M_4
, &inst
->value
, aarch64_get_variant (inst
), 0);
1655 insert_field (FLD_size
, &inst
->value
, aarch64_get_variant (inst
), 0);
1659 insert_field (FLD_size
, &inst
->value
, aarch64_get_variant (inst
) + 1, 0);
1664 insert_field (FLD_SVE_sz
, &inst
->value
, aarch64_get_variant (inst
), 0);
1668 insert_field (FLD_SVE_sz2
, &inst
->value
, aarch64_get_variant (inst
), 0);
1672 insert_field (FLD_SVE_size
, &inst
->value
,
1673 aarch64_get_variant (inst
) + 1, 0);
1676 case sve_size_tsz_bhs
:
1677 insert_fields (&inst
->value
,
1678 (1 << aarch64_get_variant (inst
)),
1679 0, 2, FLD_SVE_tszl_19
, FLD_SVE_sz
);
1683 variant
= aarch64_get_variant (inst
) + 1;
1686 insert_field (FLD_size
, &inst
->value
, variant
, 0);
1694 /* Converters converting an alias opcode instruction to its real form. */
1696 /* ROR <Wd>, <Ws>, #<shift>
1698 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
1700 convert_ror_to_extr (aarch64_inst
*inst
)
1702 copy_operand_info (inst
, 3, 2);
1703 copy_operand_info (inst
, 2, 1);
1706 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
1708 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
1710 convert_xtl_to_shll (aarch64_inst
*inst
)
1712 inst
->operands
[2].qualifier
= inst
->operands
[1].qualifier
;
1713 inst
->operands
[2].imm
.value
= 0;
1717 LSR <Xd>, <Xn>, #<shift>
1719 UBFM <Xd>, <Xn>, #<shift>, #63. */
1721 convert_sr_to_bfm (aarch64_inst
*inst
)
1723 inst
->operands
[3].imm
.value
=
1724 inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
1727 /* Convert MOV to ORR. */
1729 convert_mov_to_orr (aarch64_inst
*inst
)
1731 /* MOV <Vd>.<T>, <Vn>.<T>
1733 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
1734 copy_operand_info (inst
, 2, 1);
1737 /* When <imms> >= <immr>, the instruction written:
1738 SBFX <Xd>, <Xn>, #<lsb>, #<width>
1740 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
1743 convert_bfx_to_bfm (aarch64_inst
*inst
)
1747 /* Convert the operand. */
1748 lsb
= inst
->operands
[2].imm
.value
;
1749 width
= inst
->operands
[3].imm
.value
;
1750 inst
->operands
[2].imm
.value
= lsb
;
1751 inst
->operands
[3].imm
.value
= lsb
+ width
- 1;
1754 /* When <imms> < <immr>, the instruction written:
1755 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
1757 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
1760 convert_bfi_to_bfm (aarch64_inst
*inst
)
1764 /* Convert the operand. */
1765 lsb
= inst
->operands
[2].imm
.value
;
1766 width
= inst
->operands
[3].imm
.value
;
1767 if (inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
)
1769 inst
->operands
[2].imm
.value
= (32 - lsb
) & 0x1f;
1770 inst
->operands
[3].imm
.value
= width
- 1;
1774 inst
->operands
[2].imm
.value
= (64 - lsb
) & 0x3f;
1775 inst
->operands
[3].imm
.value
= width
- 1;
1779 /* The instruction written:
1780 BFC <Xd>, #<lsb>, #<width>
1782 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
1785 convert_bfc_to_bfm (aarch64_inst
*inst
)
1790 copy_operand_info (inst
, 3, 2);
1791 copy_operand_info (inst
, 2, 1);
1792 copy_operand_info (inst
, 1, 0);
1793 inst
->operands
[1].reg
.regno
= 0x1f;
1795 /* Convert the immediate operand. */
1796 lsb
= inst
->operands
[2].imm
.value
;
1797 width
= inst
->operands
[3].imm
.value
;
1798 if (inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
)
1800 inst
->operands
[2].imm
.value
= (32 - lsb
) & 0x1f;
1801 inst
->operands
[3].imm
.value
= width
- 1;
1805 inst
->operands
[2].imm
.value
= (64 - lsb
) & 0x3f;
1806 inst
->operands
[3].imm
.value
= width
- 1;
1810 /* The instruction written:
1811 LSL <Xd>, <Xn>, #<shift>
1813 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
1816 convert_lsl_to_ubfm (aarch64_inst
*inst
)
1818 int64_t shift
= inst
->operands
[2].imm
.value
;
1820 if (inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
)
1822 inst
->operands
[2].imm
.value
= (32 - shift
) & 0x1f;
1823 inst
->operands
[3].imm
.value
= 31 - shift
;
1827 inst
->operands
[2].imm
.value
= (64 - shift
) & 0x3f;
1828 inst
->operands
[3].imm
.value
= 63 - shift
;
1832 /* CINC <Wd>, <Wn>, <cond>
1834 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>). */
1837 convert_to_csel (aarch64_inst
*inst
)
1839 copy_operand_info (inst
, 3, 2);
1840 copy_operand_info (inst
, 2, 1);
1841 inst
->operands
[3].cond
= get_inverted_cond (inst
->operands
[3].cond
);
1844 /* CSET <Wd>, <cond>
1846 CSINC <Wd>, WZR, WZR, invert(<cond>). */
1849 convert_cset_to_csinc (aarch64_inst
*inst
)
1851 copy_operand_info (inst
, 3, 1);
1852 copy_operand_info (inst
, 2, 0);
1853 copy_operand_info (inst
, 1, 0);
1854 inst
->operands
[1].reg
.regno
= 0x1f;
1855 inst
->operands
[2].reg
.regno
= 0x1f;
1856 inst
->operands
[3].cond
= get_inverted_cond (inst
->operands
[3].cond
);
1861 MOVZ <Wd>, #<imm16>, LSL #<shift>. */
1864 convert_mov_to_movewide (aarch64_inst
*inst
)
1867 uint32_t shift_amount
;
1870 switch (inst
->opcode
->op
)
1872 case OP_MOV_IMM_WIDE
:
1873 value
= inst
->operands
[1].imm
.value
;
1875 case OP_MOV_IMM_WIDEN
:
1876 value
= ~inst
->operands
[1].imm
.value
;
1881 inst
->operands
[1].type
= AARCH64_OPND_HALF
;
1882 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
1883 if (! aarch64_wide_constant_p (value
, is32
, &shift_amount
))
1884 /* The constraint check should have guaranteed this wouldn't happen. */
1886 value
>>= shift_amount
;
1888 inst
->operands
[1].imm
.value
= value
;
1889 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_LSL
;
1890 inst
->operands
[1].shifter
.amount
= shift_amount
;
1895 ORR <Wd>, WZR, #<imm>. */
1898 convert_mov_to_movebitmask (aarch64_inst
*inst
)
1900 copy_operand_info (inst
, 2, 1);
1901 inst
->operands
[1].reg
.regno
= 0x1f;
1902 inst
->operands
[1].skip
= 0;
1905 /* Some alias opcodes are assembled by being converted to their real-form. */
1908 convert_to_real (aarch64_inst
*inst
, const aarch64_opcode
*real
)
1910 const aarch64_opcode
*alias
= inst
->opcode
;
1912 if ((alias
->flags
& F_CONV
) == 0)
1913 goto convert_to_real_return
;
1919 convert_sr_to_bfm (inst
);
1922 convert_lsl_to_ubfm (inst
);
1927 convert_to_csel (inst
);
1931 convert_cset_to_csinc (inst
);
1936 convert_bfx_to_bfm (inst
);
1941 convert_bfi_to_bfm (inst
);
1944 convert_bfc_to_bfm (inst
);
1947 convert_mov_to_orr (inst
);
1949 case OP_MOV_IMM_WIDE
:
1950 case OP_MOV_IMM_WIDEN
:
1951 convert_mov_to_movewide (inst
);
1953 case OP_MOV_IMM_LOG
:
1954 convert_mov_to_movebitmask (inst
);
1957 convert_ror_to_extr (inst
);
1963 convert_xtl_to_shll (inst
);
1969 convert_to_real_return
:
1970 aarch64_replace_opcode (inst
, real
);
1973 /* Encode *INST_ORI of the opcode code OPCODE.
1974 Return the encoded result in *CODE and if QLF_SEQ is not NULL, return the
1975 matched operand qualifier sequence in *QLF_SEQ. */
1978 aarch64_opcode_encode (const aarch64_opcode
*opcode
,
1979 const aarch64_inst
*inst_ori
, aarch64_insn
*code
,
1980 aarch64_opnd_qualifier_t
*qlf_seq
,
1981 aarch64_operand_error
*mismatch_detail
,
1982 aarch64_instr_sequence
* insn_sequence
)
1985 const aarch64_opcode
*aliased
;
1986 aarch64_inst copy
, *inst
;
1988 DEBUG_TRACE ("enter with %s", opcode
->name
);
1990 /* Create a copy of *INST_ORI, so that we can do any change we want. */
1994 assert (inst
->opcode
== NULL
|| inst
->opcode
== opcode
);
1995 if (inst
->opcode
== NULL
)
1996 inst
->opcode
= opcode
;
1998 /* Constrain the operands.
1999 After passing this, the encoding is guaranteed to succeed. */
2000 if (aarch64_match_operands_constraint (inst
, mismatch_detail
) == 0)
2002 DEBUG_TRACE ("FAIL since operand constraint not met");
2006 /* Get the base value.
2007 Note: this has to be before the aliasing handling below in order to
2008 get the base value from the alias opcode before we move on to the
2009 aliased opcode for encoding. */
2010 inst
->value
= opcode
->opcode
;
2012 /* No need to do anything else if the opcode does not have any operand. */
2013 if (aarch64_num_of_operands (opcode
) == 0)
2016 /* Assign operand indexes and check types. Also put the matched
2017 operand qualifiers in *QLF_SEQ to return. */
2018 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2020 assert (opcode
->operands
[i
] == inst
->operands
[i
].type
);
2021 inst
->operands
[i
].idx
= i
;
2022 if (qlf_seq
!= NULL
)
2023 *qlf_seq
= inst
->operands
[i
].qualifier
;
2026 aliased
= aarch64_find_real_opcode (opcode
);
2027 /* If the opcode is an alias and it does not ask for direct encoding by
2028 itself, the instruction will be transformed to the form of real opcode
2029 and the encoding will be carried out using the rules for the aliased
2031 if (aliased
!= NULL
&& (opcode
->flags
& F_CONV
))
2033 DEBUG_TRACE ("real opcode '%s' has been found for the alias %s",
2034 aliased
->name
, opcode
->name
);
2035 /* Convert the operands to the form of the real opcode. */
2036 convert_to_real (inst
, aliased
);
2040 aarch64_opnd_info
*info
= inst
->operands
;
2042 /* Call the inserter of each operand. */
2043 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
, ++info
)
2045 const aarch64_operand
*opnd
;
2046 enum aarch64_opnd type
= opcode
->operands
[i
];
2047 if (type
== AARCH64_OPND_NIL
)
2051 DEBUG_TRACE ("skip the incomplete operand %d", i
);
2054 opnd
= &aarch64_operands
[type
];
2055 if (operand_has_inserter (opnd
)
2056 && !aarch64_insert_operand (opnd
, info
, &inst
->value
, inst
,
2061 /* Call opcode encoders indicated by flags. */
2062 if (opcode_has_special_coder (opcode
))
2063 do_special_encoding (inst
);
2065 /* Possibly use the instruction class to encode the chosen qualifier
2067 aarch64_encode_variant_using_iclass (inst
);
2069 /* Run a verifier if the instruction has one set. */
2070 if (opcode
->verifier
)
2072 enum err_type result
= opcode
->verifier (inst
, *code
, 0, TRUE
,
2073 mismatch_detail
, insn_sequence
);
2085 /* Always run constrain verifiers, this is needed because constrains need to
2086 maintain a global state. Regardless if the instruction has the flag set
2088 enum err_type result
= verify_constraints (inst
, *code
, 0, TRUE
,
2089 mismatch_detail
, insn_sequence
);
2102 DEBUG_TRACE ("exit with %s", opcode
->name
);
2104 *code
= inst
->value
;