34be79482a60dbae687355d83eb67b24dddd837d
[deliverable/binutils-gdb.git] / opcodes / aarch64-asm.c
1 /* aarch64-asm.c -- AArch64 assembler support.
2 Copyright (C) 2012-2016 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
4
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
20
21 #include "sysdep.h"
22 #include <stdarg.h>
23 #include "libiberty.h"
24 #include "aarch64-asm.h"
25
26 /* Utilities. */
27
28 /* The unnamed arguments consist of the number of fields and information about
29 these fields where the VALUE will be inserted into CODE. MASK can be zero or
30 the base mask of the opcode.
31
32 N.B. the fields are required to be in such an order than the least signficant
33 field for VALUE comes the first, e.g. the <index> in
34 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
35 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
36 the order of M, L, H. */
37
38 static inline void
39 insert_fields (aarch64_insn *code, aarch64_insn value, aarch64_insn mask, ...)
40 {
41 uint32_t num;
42 const aarch64_field *field;
43 enum aarch64_field_kind kind;
44 va_list va;
45
46 va_start (va, mask);
47 num = va_arg (va, uint32_t);
48 assert (num <= 5);
49 while (num--)
50 {
51 kind = va_arg (va, enum aarch64_field_kind);
52 field = &fields[kind];
53 insert_field (kind, code, value, mask);
54 value >>= field->width;
55 }
56 va_end (va);
57 }
58
59 /* Insert a raw field value VALUE into all fields in SELF->fields.
60 The least significant bit goes in the final field. */
61
62 static void
63 insert_all_fields (const aarch64_operand *self, aarch64_insn *code,
64 aarch64_insn value)
65 {
66 unsigned int i;
67 enum aarch64_field_kind kind;
68
69 for (i = ARRAY_SIZE (self->fields); i-- > 0; )
70 if (self->fields[i] != FLD_NIL)
71 {
72 kind = self->fields[i];
73 insert_field (kind, code, value, 0);
74 value >>= fields[kind].width;
75 }
76 }
77
78 /* Operand inserters. */
79
80 /* Insert register number. */
81 const char *
82 aarch64_ins_regno (const aarch64_operand *self, const aarch64_opnd_info *info,
83 aarch64_insn *code,
84 const aarch64_inst *inst ATTRIBUTE_UNUSED)
85 {
86 insert_field (self->fields[0], code, info->reg.regno, 0);
87 return NULL;
88 }
89
90 /* Insert register number, index and/or other data for SIMD register element
91 operand, e.g. the last source operand in
92 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
93 const char *
94 aarch64_ins_reglane (const aarch64_operand *self, const aarch64_opnd_info *info,
95 aarch64_insn *code, const aarch64_inst *inst)
96 {
97 /* regno */
98 insert_field (self->fields[0], code, info->reglane.regno, inst->opcode->mask);
99 /* index and/or type */
100 if (inst->opcode->iclass == asisdone || inst->opcode->iclass == asimdins)
101 {
102 int pos = info->qualifier - AARCH64_OPND_QLF_S_B;
103 if (info->type == AARCH64_OPND_En
104 && inst->opcode->operands[0] == AARCH64_OPND_Ed)
105 {
106 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
107 assert (info->idx == 1); /* Vn */
108 aarch64_insn value = info->reglane.index << pos;
109 insert_field (FLD_imm4, code, value, 0);
110 }
111 else
112 {
113 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
114 imm5<3:0> <V>
115 0000 RESERVED
116 xxx1 B
117 xx10 H
118 x100 S
119 1000 D */
120 aarch64_insn value = ((info->reglane.index << 1) | 1) << pos;
121 insert_field (FLD_imm5, code, value, 0);
122 }
123 }
124 else
125 {
126 /* index for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
127 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
128 switch (info->qualifier)
129 {
130 case AARCH64_OPND_QLF_S_H:
131 /* H:L:M */
132 insert_fields (code, info->reglane.index, 0, 3, FLD_M, FLD_L, FLD_H);
133 break;
134 case AARCH64_OPND_QLF_S_S:
135 /* H:L */
136 insert_fields (code, info->reglane.index, 0, 2, FLD_L, FLD_H);
137 break;
138 case AARCH64_OPND_QLF_S_D:
139 /* H */
140 insert_field (FLD_H, code, info->reglane.index, 0);
141 break;
142 default:
143 assert (0);
144 }
145 }
146 return NULL;
147 }
148
149 /* Insert regno and len field of a register list operand, e.g. Vn in TBL. */
150 const char *
151 aarch64_ins_reglist (const aarch64_operand *self, const aarch64_opnd_info *info,
152 aarch64_insn *code,
153 const aarch64_inst *inst ATTRIBUTE_UNUSED)
154 {
155 /* R */
156 insert_field (self->fields[0], code, info->reglist.first_regno, 0);
157 /* len */
158 insert_field (FLD_len, code, info->reglist.num_regs - 1, 0);
159 return NULL;
160 }
161
162 /* Insert Rt and opcode fields for a register list operand, e.g. Vt
163 in AdvSIMD load/store instructions. */
164 const char *
165 aarch64_ins_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
166 const aarch64_opnd_info *info, aarch64_insn *code,
167 const aarch64_inst *inst)
168 {
169 aarch64_insn value = 0;
170 /* Number of elements in each structure to be loaded/stored. */
171 unsigned num = get_opcode_dependent_value (inst->opcode);
172
173 /* Rt */
174 insert_field (FLD_Rt, code, info->reglist.first_regno, 0);
175 /* opcode */
176 switch (num)
177 {
178 case 1:
179 switch (info->reglist.num_regs)
180 {
181 case 1: value = 0x7; break;
182 case 2: value = 0xa; break;
183 case 3: value = 0x6; break;
184 case 4: value = 0x2; break;
185 default: assert (0);
186 }
187 break;
188 case 2:
189 value = info->reglist.num_regs == 4 ? 0x3 : 0x8;
190 break;
191 case 3:
192 value = 0x4;
193 break;
194 case 4:
195 value = 0x0;
196 break;
197 default:
198 assert (0);
199 }
200 insert_field (FLD_opcode, code, value, 0);
201
202 return NULL;
203 }
204
205 /* Insert Rt and S fields for a register list operand, e.g. Vt in AdvSIMD load
206 single structure to all lanes instructions. */
207 const char *
208 aarch64_ins_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
209 const aarch64_opnd_info *info, aarch64_insn *code,
210 const aarch64_inst *inst)
211 {
212 aarch64_insn value;
213 /* The opcode dependent area stores the number of elements in
214 each structure to be loaded/stored. */
215 int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
216
217 /* Rt */
218 insert_field (FLD_Rt, code, info->reglist.first_regno, 0);
219 /* S */
220 value = (aarch64_insn) 0;
221 if (is_ld1r && info->reglist.num_regs == 2)
222 /* OP_LD1R does not have alternating variant, but have "two consecutive"
223 instead. */
224 value = (aarch64_insn) 1;
225 insert_field (FLD_S, code, value, 0);
226
227 return NULL;
228 }
229
230 /* Insert Q, opcode<2:1>, S, size and Rt fields for a register element list
231 operand e.g. Vt in AdvSIMD load/store single element instructions. */
232 const char *
233 aarch64_ins_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
234 const aarch64_opnd_info *info, aarch64_insn *code,
235 const aarch64_inst *inst ATTRIBUTE_UNUSED)
236 {
237 aarch64_field field = {0, 0};
238 aarch64_insn QSsize = 0; /* fields Q:S:size. */
239 aarch64_insn opcodeh2 = 0; /* opcode<2:1> */
240
241 assert (info->reglist.has_index);
242
243 /* Rt */
244 insert_field (FLD_Rt, code, info->reglist.first_regno, 0);
245 /* Encode the index, opcode<2:1> and size. */
246 switch (info->qualifier)
247 {
248 case AARCH64_OPND_QLF_S_B:
249 /* Index encoded in "Q:S:size". */
250 QSsize = info->reglist.index;
251 opcodeh2 = 0x0;
252 break;
253 case AARCH64_OPND_QLF_S_H:
254 /* Index encoded in "Q:S:size<1>". */
255 QSsize = info->reglist.index << 1;
256 opcodeh2 = 0x1;
257 break;
258 case AARCH64_OPND_QLF_S_S:
259 /* Index encoded in "Q:S". */
260 QSsize = info->reglist.index << 2;
261 opcodeh2 = 0x2;
262 break;
263 case AARCH64_OPND_QLF_S_D:
264 /* Index encoded in "Q". */
265 QSsize = info->reglist.index << 3 | 0x1;
266 opcodeh2 = 0x2;
267 break;
268 default:
269 assert (0);
270 }
271 insert_fields (code, QSsize, 0, 3, FLD_vldst_size, FLD_S, FLD_Q);
272 gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
273 insert_field_2 (&field, code, opcodeh2, 0);
274
275 return NULL;
276 }
277
278 /* Insert fields immh:immb and/or Q for e.g. the shift immediate in
279 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
280 or SSHR <V><d>, <V><n>, #<shift>. */
281 const char *
282 aarch64_ins_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
283 const aarch64_opnd_info *info,
284 aarch64_insn *code, const aarch64_inst *inst)
285 {
286 unsigned val = aarch64_get_qualifier_standard_value (info->qualifier);
287 aarch64_insn Q, imm;
288
289 if (inst->opcode->iclass == asimdshf)
290 {
291 /* Q
292 immh Q <T>
293 0000 x SEE AdvSIMD modified immediate
294 0001 0 8B
295 0001 1 16B
296 001x 0 4H
297 001x 1 8H
298 01xx 0 2S
299 01xx 1 4S
300 1xxx 0 RESERVED
301 1xxx 1 2D */
302 Q = (val & 0x1) ? 1 : 0;
303 insert_field (FLD_Q, code, Q, inst->opcode->mask);
304 val >>= 1;
305 }
306
307 assert (info->type == AARCH64_OPND_IMM_VLSR
308 || info->type == AARCH64_OPND_IMM_VLSL);
309
310 if (info->type == AARCH64_OPND_IMM_VLSR)
311 /* immh:immb
312 immh <shift>
313 0000 SEE AdvSIMD modified immediate
314 0001 (16-UInt(immh:immb))
315 001x (32-UInt(immh:immb))
316 01xx (64-UInt(immh:immb))
317 1xxx (128-UInt(immh:immb)) */
318 imm = (16 << (unsigned)val) - info->imm.value;
319 else
320 /* immh:immb
321 immh <shift>
322 0000 SEE AdvSIMD modified immediate
323 0001 (UInt(immh:immb)-8)
324 001x (UInt(immh:immb)-16)
325 01xx (UInt(immh:immb)-32)
326 1xxx (UInt(immh:immb)-64) */
327 imm = info->imm.value + (8 << (unsigned)val);
328 insert_fields (code, imm, 0, 2, FLD_immb, FLD_immh);
329
330 return NULL;
331 }
332
333 /* Insert fields for e.g. the immediate operands in
334 BFM <Wd>, <Wn>, #<immr>, #<imms>. */
335 const char *
336 aarch64_ins_imm (const aarch64_operand *self, const aarch64_opnd_info *info,
337 aarch64_insn *code,
338 const aarch64_inst *inst ATTRIBUTE_UNUSED)
339 {
340 int64_t imm;
341
342 imm = info->imm.value;
343 if (operand_need_shift_by_two (self))
344 imm >>= 2;
345 insert_all_fields (self, code, imm);
346 return NULL;
347 }
348
349 /* Insert immediate and its shift amount for e.g. the last operand in
350 MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
351 const char *
352 aarch64_ins_imm_half (const aarch64_operand *self, const aarch64_opnd_info *info,
353 aarch64_insn *code, const aarch64_inst *inst)
354 {
355 /* imm16 */
356 aarch64_ins_imm (self, info, code, inst);
357 /* hw */
358 insert_field (FLD_hw, code, info->shifter.amount >> 4, 0);
359 return NULL;
360 }
361
362 /* Insert cmode and "a:b:c:d:e:f:g:h" fields for e.g. the last operand in
363 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
364 const char *
365 aarch64_ins_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
366 const aarch64_opnd_info *info,
367 aarch64_insn *code,
368 const aarch64_inst *inst ATTRIBUTE_UNUSED)
369 {
370 enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
371 uint64_t imm = info->imm.value;
372 enum aarch64_modifier_kind kind = info->shifter.kind;
373 int amount = info->shifter.amount;
374 aarch64_field field = {0, 0};
375
376 /* a:b:c:d:e:f:g:h */
377 if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
378 {
379 /* Either MOVI <Dd>, #<imm>
380 or MOVI <Vd>.2D, #<imm>.
381 <imm> is a 64-bit immediate
382 "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
383 encoded in "a:b:c:d:e:f:g:h". */
384 imm = aarch64_shrink_expanded_imm8 (imm);
385 assert ((int)imm >= 0);
386 }
387 insert_fields (code, imm, 0, 2, FLD_defgh, FLD_abc);
388
389 if (kind == AARCH64_MOD_NONE)
390 return NULL;
391
392 /* shift amount partially in cmode */
393 assert (kind == AARCH64_MOD_LSL || kind == AARCH64_MOD_MSL);
394 if (kind == AARCH64_MOD_LSL)
395 {
396 /* AARCH64_MOD_LSL: shift zeros. */
397 int esize = aarch64_get_qualifier_esize (opnd0_qualifier);
398 assert (esize == 4 || esize == 2 || esize == 1);
399 /* For 8-bit move immediate, the optional LSL #0 does not require
400 encoding. */
401 if (esize == 1)
402 return NULL;
403 amount >>= 3;
404 if (esize == 4)
405 gen_sub_field (FLD_cmode, 1, 2, &field); /* per word */
406 else
407 gen_sub_field (FLD_cmode, 1, 1, &field); /* per halfword */
408 }
409 else
410 {
411 /* AARCH64_MOD_MSL: shift ones. */
412 amount >>= 4;
413 gen_sub_field (FLD_cmode, 0, 1, &field); /* per word */
414 }
415 insert_field_2 (&field, code, amount, 0);
416
417 return NULL;
418 }
419
420 /* Insert fields for an 8-bit floating-point immediate. */
421 const char *
422 aarch64_ins_fpimm (const aarch64_operand *self, const aarch64_opnd_info *info,
423 aarch64_insn *code,
424 const aarch64_inst *inst ATTRIBUTE_UNUSED)
425 {
426 insert_all_fields (self, code, info->imm.value);
427 return NULL;
428 }
429
430 /* Insert #<fbits> for the immediate operand in fp fix-point instructions,
431 e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
432 const char *
433 aarch64_ins_fbits (const aarch64_operand *self, const aarch64_opnd_info *info,
434 aarch64_insn *code,
435 const aarch64_inst *inst ATTRIBUTE_UNUSED)
436 {
437 insert_field (self->fields[0], code, 64 - info->imm.value, 0);
438 return NULL;
439 }
440
441 /* Insert arithmetic immediate for e.g. the last operand in
442 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
443 const char *
444 aarch64_ins_aimm (const aarch64_operand *self, const aarch64_opnd_info *info,
445 aarch64_insn *code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
446 {
447 /* shift */
448 aarch64_insn value = info->shifter.amount ? 1 : 0;
449 insert_field (self->fields[0], code, value, 0);
450 /* imm12 (unsigned) */
451 insert_field (self->fields[1], code, info->imm.value, 0);
452 return NULL;
453 }
454
455 /* Common routine shared by aarch64_ins{,_inv}_limm. INVERT_P says whether
456 the operand should be inverted before encoding. */
457 static const char *
458 aarch64_ins_limm_1 (const aarch64_operand *self,
459 const aarch64_opnd_info *info, aarch64_insn *code,
460 const aarch64_inst *inst, bfd_boolean invert_p)
461 {
462 aarch64_insn value;
463 uint64_t imm = info->imm.value;
464 int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
465
466 if (invert_p)
467 imm = ~imm;
468 if (aarch64_logical_immediate_p (imm, esize, &value) == FALSE)
469 /* The constraint check should have guaranteed this wouldn't happen. */
470 assert (0);
471
472 insert_fields (code, value, 0, 3, self->fields[2], self->fields[1],
473 self->fields[0]);
474 return NULL;
475 }
476
477 /* Insert logical/bitmask immediate for e.g. the last operand in
478 ORR <Wd|WSP>, <Wn>, #<imm>. */
479 const char *
480 aarch64_ins_limm (const aarch64_operand *self, const aarch64_opnd_info *info,
481 aarch64_insn *code, const aarch64_inst *inst)
482 {
483 return aarch64_ins_limm_1 (self, info, code, inst,
484 inst->opcode->op == OP_BIC);
485 }
486
487 /* Insert a logical/bitmask immediate for the BIC alias of AND (etc.). */
488 const char *
489 aarch64_ins_inv_limm (const aarch64_operand *self,
490 const aarch64_opnd_info *info, aarch64_insn *code,
491 const aarch64_inst *inst)
492 {
493 return aarch64_ins_limm_1 (self, info, code, inst, TRUE);
494 }
495
496 /* Encode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
497 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
498 const char *
499 aarch64_ins_ft (const aarch64_operand *self, const aarch64_opnd_info *info,
500 aarch64_insn *code, const aarch64_inst *inst)
501 {
502 aarch64_insn value = 0;
503
504 assert (info->idx == 0);
505
506 /* Rt */
507 aarch64_ins_regno (self, info, code, inst);
508 if (inst->opcode->iclass == ldstpair_indexed
509 || inst->opcode->iclass == ldstnapair_offs
510 || inst->opcode->iclass == ldstpair_off
511 || inst->opcode->iclass == loadlit)
512 {
513 /* size */
514 switch (info->qualifier)
515 {
516 case AARCH64_OPND_QLF_S_S: value = 0; break;
517 case AARCH64_OPND_QLF_S_D: value = 1; break;
518 case AARCH64_OPND_QLF_S_Q: value = 2; break;
519 default: assert (0);
520 }
521 insert_field (FLD_ldst_size, code, value, 0);
522 }
523 else
524 {
525 /* opc[1]:size */
526 value = aarch64_get_qualifier_standard_value (info->qualifier);
527 insert_fields (code, value, 0, 2, FLD_ldst_size, FLD_opc1);
528 }
529
530 return NULL;
531 }
532
533 /* Encode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
534 const char *
535 aarch64_ins_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
536 const aarch64_opnd_info *info, aarch64_insn *code,
537 const aarch64_inst *inst ATTRIBUTE_UNUSED)
538 {
539 /* Rn */
540 insert_field (FLD_Rn, code, info->addr.base_regno, 0);
541 return NULL;
542 }
543
544 /* Encode the address operand for e.g.
545 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
546 const char *
547 aarch64_ins_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
548 const aarch64_opnd_info *info, aarch64_insn *code,
549 const aarch64_inst *inst ATTRIBUTE_UNUSED)
550 {
551 aarch64_insn S;
552 enum aarch64_modifier_kind kind = info->shifter.kind;
553
554 /* Rn */
555 insert_field (FLD_Rn, code, info->addr.base_regno, 0);
556 /* Rm */
557 insert_field (FLD_Rm, code, info->addr.offset.regno, 0);
558 /* option */
559 if (kind == AARCH64_MOD_LSL)
560 kind = AARCH64_MOD_UXTX; /* Trick to enable the table-driven. */
561 insert_field (FLD_option, code, aarch64_get_operand_modifier_value (kind), 0);
562 /* S */
563 if (info->qualifier != AARCH64_OPND_QLF_S_B)
564 S = info->shifter.amount != 0;
565 else
566 /* For STR <Bt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}},
567 S <amount>
568 0 [absent]
569 1 #0
570 Must be #0 if <extend> is explicitly LSL. */
571 S = info->shifter.operator_present && info->shifter.amount_present;
572 insert_field (FLD_S, code, S, 0);
573
574 return NULL;
575 }
576
577 /* Encode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>, #<simm>]!. */
578 const char *
579 aarch64_ins_addr_simm (const aarch64_operand *self,
580 const aarch64_opnd_info *info,
581 aarch64_insn *code,
582 const aarch64_inst *inst ATTRIBUTE_UNUSED)
583 {
584 int imm;
585
586 /* Rn */
587 insert_field (FLD_Rn, code, info->addr.base_regno, 0);
588 /* simm (imm9 or imm7) */
589 imm = info->addr.offset.imm;
590 if (self->fields[0] == FLD_imm7)
591 /* scaled immediate in ld/st pair instructions.. */
592 imm >>= get_logsz (aarch64_get_qualifier_esize (info->qualifier));
593 insert_field (self->fields[0], code, imm, 0);
594 /* pre/post- index */
595 if (info->addr.writeback)
596 {
597 assert (inst->opcode->iclass != ldst_unscaled
598 && inst->opcode->iclass != ldstnapair_offs
599 && inst->opcode->iclass != ldstpair_off
600 && inst->opcode->iclass != ldst_unpriv);
601 assert (info->addr.preind != info->addr.postind);
602 if (info->addr.preind)
603 insert_field (self->fields[1], code, 1, 0);
604 }
605
606 return NULL;
607 }
608
609 /* Encode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]. */
610 const char *
611 aarch64_ins_addr_uimm12 (const aarch64_operand *self,
612 const aarch64_opnd_info *info,
613 aarch64_insn *code,
614 const aarch64_inst *inst ATTRIBUTE_UNUSED)
615 {
616 int shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
617
618 /* Rn */
619 insert_field (self->fields[0], code, info->addr.base_regno, 0);
620 /* uimm12 */
621 insert_field (self->fields[1], code,info->addr.offset.imm >> shift, 0);
622 return NULL;
623 }
624
625 /* Encode the address operand for e.g.
626 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
627 const char *
628 aarch64_ins_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
629 const aarch64_opnd_info *info, aarch64_insn *code,
630 const aarch64_inst *inst ATTRIBUTE_UNUSED)
631 {
632 /* Rn */
633 insert_field (FLD_Rn, code, info->addr.base_regno, 0);
634 /* Rm | #<amount> */
635 if (info->addr.offset.is_reg)
636 insert_field (FLD_Rm, code, info->addr.offset.regno, 0);
637 else
638 insert_field (FLD_Rm, code, 0x1f, 0);
639 return NULL;
640 }
641
642 /* Encode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
643 const char *
644 aarch64_ins_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
645 const aarch64_opnd_info *info, aarch64_insn *code,
646 const aarch64_inst *inst ATTRIBUTE_UNUSED)
647 {
648 /* cond */
649 insert_field (FLD_cond, code, info->cond->value, 0);
650 return NULL;
651 }
652
653 /* Encode the system register operand for e.g. MRS <Xt>, <systemreg>. */
654 const char *
655 aarch64_ins_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
656 const aarch64_opnd_info *info, aarch64_insn *code,
657 const aarch64_inst *inst ATTRIBUTE_UNUSED)
658 {
659 /* op0:op1:CRn:CRm:op2 */
660 insert_fields (code, info->sysreg, inst->opcode->mask, 5,
661 FLD_op2, FLD_CRm, FLD_CRn, FLD_op1, FLD_op0);
662 return NULL;
663 }
664
665 /* Encode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
666 const char *
667 aarch64_ins_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
668 const aarch64_opnd_info *info, aarch64_insn *code,
669 const aarch64_inst *inst ATTRIBUTE_UNUSED)
670 {
671 /* op1:op2 */
672 insert_fields (code, info->pstatefield, inst->opcode->mask, 2,
673 FLD_op2, FLD_op1);
674 return NULL;
675 }
676
677 /* Encode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
678 const char *
679 aarch64_ins_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
680 const aarch64_opnd_info *info, aarch64_insn *code,
681 const aarch64_inst *inst ATTRIBUTE_UNUSED)
682 {
683 /* op1:CRn:CRm:op2 */
684 insert_fields (code, info->sysins_op->value, inst->opcode->mask, 4,
685 FLD_op2, FLD_CRm, FLD_CRn, FLD_op1);
686 return NULL;
687 }
688
689 /* Encode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
690
691 const char *
692 aarch64_ins_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
693 const aarch64_opnd_info *info, aarch64_insn *code,
694 const aarch64_inst *inst ATTRIBUTE_UNUSED)
695 {
696 /* CRm */
697 insert_field (FLD_CRm, code, info->barrier->value, 0);
698 return NULL;
699 }
700
701 /* Encode the prefetch operation option operand for e.g.
702 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
703
704 const char *
705 aarch64_ins_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
706 const aarch64_opnd_info *info, aarch64_insn *code,
707 const aarch64_inst *inst ATTRIBUTE_UNUSED)
708 {
709 /* prfop in Rt */
710 insert_field (FLD_Rt, code, info->prfop->value, 0);
711 return NULL;
712 }
713
714 /* Encode the hint number for instructions that alias HINT but take an
715 operand. */
716
717 const char *
718 aarch64_ins_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
719 const aarch64_opnd_info *info, aarch64_insn *code,
720 const aarch64_inst *inst ATTRIBUTE_UNUSED)
721 {
722 /* CRm:op2. */
723 insert_fields (code, info->hint_option->value, 0, 2, FLD_op2, FLD_CRm);
724 return NULL;
725 }
726
727 /* Encode the extended register operand for e.g.
728 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
729 const char *
730 aarch64_ins_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
731 const aarch64_opnd_info *info, aarch64_insn *code,
732 const aarch64_inst *inst ATTRIBUTE_UNUSED)
733 {
734 enum aarch64_modifier_kind kind;
735
736 /* Rm */
737 insert_field (FLD_Rm, code, info->reg.regno, 0);
738 /* option */
739 kind = info->shifter.kind;
740 if (kind == AARCH64_MOD_LSL)
741 kind = info->qualifier == AARCH64_OPND_QLF_W
742 ? AARCH64_MOD_UXTW : AARCH64_MOD_UXTX;
743 insert_field (FLD_option, code, aarch64_get_operand_modifier_value (kind), 0);
744 /* imm3 */
745 insert_field (FLD_imm3, code, info->shifter.amount, 0);
746
747 return NULL;
748 }
749
750 /* Encode the shifted register operand for e.g.
751 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
752 const char *
753 aarch64_ins_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
754 const aarch64_opnd_info *info, aarch64_insn *code,
755 const aarch64_inst *inst ATTRIBUTE_UNUSED)
756 {
757 /* Rm */
758 insert_field (FLD_Rm, code, info->reg.regno, 0);
759 /* shift */
760 insert_field (FLD_shift, code,
761 aarch64_get_operand_modifier_value (info->shifter.kind), 0);
762 /* imm6 */
763 insert_field (FLD_imm6, code, info->shifter.amount, 0);
764
765 return NULL;
766 }
767
768 /* Encode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
769 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
770 SELF's operand-dependent value. fields[0] specifies the field that
771 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
772 const char *
773 aarch64_ins_sve_addr_ri_s4xvl (const aarch64_operand *self,
774 const aarch64_opnd_info *info,
775 aarch64_insn *code,
776 const aarch64_inst *inst ATTRIBUTE_UNUSED)
777 {
778 int factor = 1 + get_operand_specific_data (self);
779 insert_field (self->fields[0], code, info->addr.base_regno, 0);
780 insert_field (FLD_SVE_imm4, code, info->addr.offset.imm / factor, 0);
781 return NULL;
782 }
783
784 /* Encode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
785 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
786 SELF's operand-dependent value. fields[0] specifies the field that
787 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
788 const char *
789 aarch64_ins_sve_addr_ri_s6xvl (const aarch64_operand *self,
790 const aarch64_opnd_info *info,
791 aarch64_insn *code,
792 const aarch64_inst *inst ATTRIBUTE_UNUSED)
793 {
794 int factor = 1 + get_operand_specific_data (self);
795 insert_field (self->fields[0], code, info->addr.base_regno, 0);
796 insert_field (FLD_SVE_imm6, code, info->addr.offset.imm / factor, 0);
797 return NULL;
798 }
799
800 /* Encode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
801 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
802 SELF's operand-dependent value. fields[0] specifies the field that
803 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
804 and imm3 fields, with imm3 being the less-significant part. */
805 const char *
806 aarch64_ins_sve_addr_ri_s9xvl (const aarch64_operand *self,
807 const aarch64_opnd_info *info,
808 aarch64_insn *code,
809 const aarch64_inst *inst ATTRIBUTE_UNUSED)
810 {
811 int factor = 1 + get_operand_specific_data (self);
812 insert_field (self->fields[0], code, info->addr.base_regno, 0);
813 insert_fields (code, info->addr.offset.imm / factor, 0,
814 2, FLD_imm3, FLD_SVE_imm6);
815 return NULL;
816 }
817
818 /* Encode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
819 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
820 value. fields[0] specifies the base register field. */
821 const char *
822 aarch64_ins_sve_addr_ri_u6 (const aarch64_operand *self,
823 const aarch64_opnd_info *info, aarch64_insn *code,
824 const aarch64_inst *inst ATTRIBUTE_UNUSED)
825 {
826 int factor = 1 << get_operand_specific_data (self);
827 insert_field (self->fields[0], code, info->addr.base_regno, 0);
828 insert_field (FLD_SVE_imm6, code, info->addr.offset.imm / factor, 0);
829 return NULL;
830 }
831
832 /* Encode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
833 is SELF's operand-dependent value. fields[0] specifies the base
834 register field and fields[1] specifies the offset register field. */
835 const char *
836 aarch64_ins_sve_addr_rr_lsl (const aarch64_operand *self,
837 const aarch64_opnd_info *info, aarch64_insn *code,
838 const aarch64_inst *inst ATTRIBUTE_UNUSED)
839 {
840 insert_field (self->fields[0], code, info->addr.base_regno, 0);
841 insert_field (self->fields[1], code, info->addr.offset.regno, 0);
842 return NULL;
843 }
844
845 /* Encode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
846 <shift> is SELF's operand-dependent value. fields[0] specifies the
847 base register field, fields[1] specifies the offset register field and
848 fields[2] is a single-bit field that selects SXTW over UXTW. */
849 const char *
850 aarch64_ins_sve_addr_rz_xtw (const aarch64_operand *self,
851 const aarch64_opnd_info *info, aarch64_insn *code,
852 const aarch64_inst *inst ATTRIBUTE_UNUSED)
853 {
854 insert_field (self->fields[0], code, info->addr.base_regno, 0);
855 insert_field (self->fields[1], code, info->addr.offset.regno, 0);
856 if (info->shifter.kind == AARCH64_MOD_UXTW)
857 insert_field (self->fields[2], code, 0, 0);
858 else
859 insert_field (self->fields[2], code, 1, 0);
860 return NULL;
861 }
862
863 /* Encode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
864 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
865 fields[0] specifies the base register field. */
866 const char *
867 aarch64_ins_sve_addr_zi_u5 (const aarch64_operand *self,
868 const aarch64_opnd_info *info, aarch64_insn *code,
869 const aarch64_inst *inst ATTRIBUTE_UNUSED)
870 {
871 int factor = 1 << get_operand_specific_data (self);
872 insert_field (self->fields[0], code, info->addr.base_regno, 0);
873 insert_field (FLD_imm5, code, info->addr.offset.imm / factor, 0);
874 return NULL;
875 }
876
877 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
878 where <modifier> is fixed by the instruction and where <msz> is a
879 2-bit unsigned number. fields[0] specifies the base register field
880 and fields[1] specifies the offset register field. */
881 static const char *
882 aarch64_ext_sve_addr_zz (const aarch64_operand *self,
883 const aarch64_opnd_info *info, aarch64_insn *code)
884 {
885 insert_field (self->fields[0], code, info->addr.base_regno, 0);
886 insert_field (self->fields[1], code, info->addr.offset.regno, 0);
887 insert_field (FLD_SVE_msz, code, info->shifter.amount, 0);
888 return NULL;
889 }
890
891 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
892 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
893 field and fields[1] specifies the offset register field. */
894 const char *
895 aarch64_ins_sve_addr_zz_lsl (const aarch64_operand *self,
896 const aarch64_opnd_info *info, aarch64_insn *code,
897 const aarch64_inst *inst ATTRIBUTE_UNUSED)
898 {
899 return aarch64_ext_sve_addr_zz (self, info, code);
900 }
901
902 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
903 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
904 field and fields[1] specifies the offset register field. */
905 const char *
906 aarch64_ins_sve_addr_zz_sxtw (const aarch64_operand *self,
907 const aarch64_opnd_info *info,
908 aarch64_insn *code,
909 const aarch64_inst *inst ATTRIBUTE_UNUSED)
910 {
911 return aarch64_ext_sve_addr_zz (self, info, code);
912 }
913
914 /* Encode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
915 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
916 field and fields[1] specifies the offset register field. */
917 const char *
918 aarch64_ins_sve_addr_zz_uxtw (const aarch64_operand *self,
919 const aarch64_opnd_info *info,
920 aarch64_insn *code,
921 const aarch64_inst *inst ATTRIBUTE_UNUSED)
922 {
923 return aarch64_ext_sve_addr_zz (self, info, code);
924 }
925
926 /* Encode an SVE ADD/SUB immediate. */
927 const char *
928 aarch64_ins_sve_aimm (const aarch64_operand *self,
929 const aarch64_opnd_info *info, aarch64_insn *code,
930 const aarch64_inst *inst ATTRIBUTE_UNUSED)
931 {
932 if (info->shifter.amount == 8)
933 insert_all_fields (self, code, (info->imm.value & 0xff) | 256);
934 else if (info->imm.value != 0 && (info->imm.value & 0xff) == 0)
935 insert_all_fields (self, code, ((info->imm.value / 256) & 0xff) | 256);
936 else
937 insert_all_fields (self, code, info->imm.value & 0xff);
938 return NULL;
939 }
940
941 /* Encode an SVE CPY/DUP immediate. */
942 const char *
943 aarch64_ins_sve_asimm (const aarch64_operand *self,
944 const aarch64_opnd_info *info, aarch64_insn *code,
945 const aarch64_inst *inst)
946 {
947 return aarch64_ins_sve_aimm (self, info, code, inst);
948 }
949
950 /* Encode Zn[MM], where MM has a 7-bit triangular encoding. The fields
951 array specifies which field to use for Zn. MM is encoded in the
952 concatenation of imm5 and SVE_tszh, with imm5 being the less
953 significant part. */
954 const char *
955 aarch64_ins_sve_index (const aarch64_operand *self,
956 const aarch64_opnd_info *info, aarch64_insn *code,
957 const aarch64_inst *inst ATTRIBUTE_UNUSED)
958 {
959 unsigned int esize = aarch64_get_qualifier_esize (info->qualifier);
960 insert_field (self->fields[0], code, info->reglane.regno, 0);
961 insert_fields (code, (info->reglane.index * 2 + 1) * esize, 0,
962 2, FLD_imm5, FLD_SVE_tszh);
963 return NULL;
964 }
965
966 /* Encode a logical/bitmask immediate for the MOV alias of SVE DUPM. */
967 const char *
968 aarch64_ins_sve_limm_mov (const aarch64_operand *self,
969 const aarch64_opnd_info *info, aarch64_insn *code,
970 const aarch64_inst *inst)
971 {
972 return aarch64_ins_limm (self, info, code, inst);
973 }
974
975 /* Encode {Zn.<T> - Zm.<T>}. The fields array specifies which field
976 to use for Zn. */
977 const char *
978 aarch64_ins_sve_reglist (const aarch64_operand *self,
979 const aarch64_opnd_info *info, aarch64_insn *code,
980 const aarch64_inst *inst ATTRIBUTE_UNUSED)
981 {
982 insert_field (self->fields[0], code, info->reglist.first_regno, 0);
983 return NULL;
984 }
985
986 /* Encode <pattern>{, MUL #<amount>}. The fields array specifies which
987 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
988 field. */
989 const char *
990 aarch64_ins_sve_scale (const aarch64_operand *self,
991 const aarch64_opnd_info *info, aarch64_insn *code,
992 const aarch64_inst *inst ATTRIBUTE_UNUSED)
993 {
994 insert_all_fields (self, code, info->imm.value);
995 insert_field (FLD_SVE_imm4, code, info->shifter.amount - 1, 0);
996 return NULL;
997 }
998
999 /* Encode an SVE shift left immediate. */
1000 const char *
1001 aarch64_ins_sve_shlimm (const aarch64_operand *self,
1002 const aarch64_opnd_info *info, aarch64_insn *code,
1003 const aarch64_inst *inst)
1004 {
1005 const aarch64_opnd_info *prev_operand;
1006 unsigned int esize;
1007
1008 assert (info->idx > 0);
1009 prev_operand = &inst->operands[info->idx - 1];
1010 esize = aarch64_get_qualifier_esize (prev_operand->qualifier);
1011 insert_all_fields (self, code, 8 * esize + info->imm.value);
1012 return NULL;
1013 }
1014
1015 /* Encode an SVE shift right immediate. */
1016 const char *
1017 aarch64_ins_sve_shrimm (const aarch64_operand *self,
1018 const aarch64_opnd_info *info, aarch64_insn *code,
1019 const aarch64_inst *inst)
1020 {
1021 const aarch64_opnd_info *prev_operand;
1022 unsigned int esize;
1023
1024 assert (info->idx > 0);
1025 prev_operand = &inst->operands[info->idx - 1];
1026 esize = aarch64_get_qualifier_esize (prev_operand->qualifier);
1027 insert_all_fields (self, code, 16 * esize - info->imm.value);
1028 return NULL;
1029 }
1030
1031 /* Encode a single-bit immediate that selects between #0.5 and #1.0.
1032 The fields array specifies which field to use. */
1033 const char *
1034 aarch64_ins_sve_float_half_one (const aarch64_operand *self,
1035 const aarch64_opnd_info *info,
1036 aarch64_insn *code,
1037 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1038 {
1039 if (info->imm.value == 0x3f000000)
1040 insert_field (self->fields[0], code, 0, 0);
1041 else
1042 insert_field (self->fields[0], code, 1, 0);
1043 return NULL;
1044 }
1045
1046 /* Encode a single-bit immediate that selects between #0.5 and #2.0.
1047 The fields array specifies which field to use. */
1048 const char *
1049 aarch64_ins_sve_float_half_two (const aarch64_operand *self,
1050 const aarch64_opnd_info *info,
1051 aarch64_insn *code,
1052 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1053 {
1054 if (info->imm.value == 0x3f000000)
1055 insert_field (self->fields[0], code, 0, 0);
1056 else
1057 insert_field (self->fields[0], code, 1, 0);
1058 return NULL;
1059 }
1060
1061 /* Encode a single-bit immediate that selects between #0.0 and #1.0.
1062 The fields array specifies which field to use. */
1063 const char *
1064 aarch64_ins_sve_float_zero_one (const aarch64_operand *self,
1065 const aarch64_opnd_info *info,
1066 aarch64_insn *code,
1067 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1068 {
1069 if (info->imm.value == 0)
1070 insert_field (self->fields[0], code, 0, 0);
1071 else
1072 insert_field (self->fields[0], code, 1, 0);
1073 return NULL;
1074 }
1075
1076 /* Miscellaneous encoding functions. */
1077
1078 /* Encode size[0], i.e. bit 22, for
1079 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1080
1081 static void
1082 encode_asimd_fcvt (aarch64_inst *inst)
1083 {
1084 aarch64_insn value;
1085 aarch64_field field = {0, 0};
1086 enum aarch64_opnd_qualifier qualifier;
1087
1088 switch (inst->opcode->op)
1089 {
1090 case OP_FCVTN:
1091 case OP_FCVTN2:
1092 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1093 qualifier = inst->operands[1].qualifier;
1094 break;
1095 case OP_FCVTL:
1096 case OP_FCVTL2:
1097 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1098 qualifier = inst->operands[0].qualifier;
1099 break;
1100 default:
1101 assert (0);
1102 }
1103 assert (qualifier == AARCH64_OPND_QLF_V_4S
1104 || qualifier == AARCH64_OPND_QLF_V_2D);
1105 value = (qualifier == AARCH64_OPND_QLF_V_4S) ? 0 : 1;
1106 gen_sub_field (FLD_size, 0, 1, &field);
1107 insert_field_2 (&field, &inst->value, value, 0);
1108 }
1109
1110 /* Encode size[0], i.e. bit 22, for
1111 e.g. FCVTXN <Vb><d>, <Va><n>. */
1112
1113 static void
1114 encode_asisd_fcvtxn (aarch64_inst *inst)
1115 {
1116 aarch64_insn val = 1;
1117 aarch64_field field = {0, 0};
1118 assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_S_S);
1119 gen_sub_field (FLD_size, 0, 1, &field);
1120 insert_field_2 (&field, &inst->value, val, 0);
1121 }
1122
1123 /* Encode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1124 static void
1125 encode_fcvt (aarch64_inst *inst)
1126 {
1127 aarch64_insn val;
1128 const aarch64_field field = {15, 2};
1129
1130 /* opc dstsize */
1131 switch (inst->operands[0].qualifier)
1132 {
1133 case AARCH64_OPND_QLF_S_S: val = 0; break;
1134 case AARCH64_OPND_QLF_S_D: val = 1; break;
1135 case AARCH64_OPND_QLF_S_H: val = 3; break;
1136 default: abort ();
1137 }
1138 insert_field_2 (&field, &inst->value, val, 0);
1139
1140 return;
1141 }
1142
1143 /* Return the index in qualifiers_list that INST is using. Should only
1144 be called once the qualifiers are known to be valid. */
1145
1146 static int
1147 aarch64_get_variant (struct aarch64_inst *inst)
1148 {
1149 int i, nops, variant;
1150
1151 nops = aarch64_num_of_operands (inst->opcode);
1152 for (variant = 0; variant < AARCH64_MAX_QLF_SEQ_NUM; ++variant)
1153 {
1154 for (i = 0; i < nops; ++i)
1155 if (inst->opcode->qualifiers_list[variant][i]
1156 != inst->operands[i].qualifier)
1157 break;
1158 if (i == nops)
1159 return variant;
1160 }
1161 abort ();
1162 }
1163
1164 /* Do miscellaneous encodings that are not common enough to be driven by
1165 flags. */
1166
1167 static void
1168 do_misc_encoding (aarch64_inst *inst)
1169 {
1170 unsigned int value;
1171
1172 switch (inst->opcode->op)
1173 {
1174 case OP_FCVT:
1175 encode_fcvt (inst);
1176 break;
1177 case OP_FCVTN:
1178 case OP_FCVTN2:
1179 case OP_FCVTL:
1180 case OP_FCVTL2:
1181 encode_asimd_fcvt (inst);
1182 break;
1183 case OP_FCVTXN_S:
1184 encode_asisd_fcvtxn (inst);
1185 break;
1186 case OP_MOV_P_P:
1187 case OP_MOVS_P_P:
1188 /* Copy Pn to Pm and Pg. */
1189 value = extract_field (FLD_SVE_Pn, inst->value, 0);
1190 insert_field (FLD_SVE_Pm, &inst->value, value, 0);
1191 insert_field (FLD_SVE_Pg4_10, &inst->value, value, 0);
1192 break;
1193 case OP_MOV_Z_P_Z:
1194 /* Copy Zd to Zm. */
1195 value = extract_field (FLD_SVE_Zd, inst->value, 0);
1196 insert_field (FLD_SVE_Zm_16, &inst->value, value, 0);
1197 break;
1198 case OP_MOV_Z_V:
1199 /* Fill in the zero immediate. */
1200 insert_field (FLD_SVE_tsz, &inst->value,
1201 1 << aarch64_get_variant (inst), 0);
1202 break;
1203 case OP_MOV_Z_Z:
1204 /* Copy Zn to Zm. */
1205 value = extract_field (FLD_SVE_Zn, inst->value, 0);
1206 insert_field (FLD_SVE_Zm_16, &inst->value, value, 0);
1207 break;
1208 case OP_MOV_Z_Zi:
1209 break;
1210 case OP_MOVM_P_P_P:
1211 /* Copy Pd to Pm. */
1212 value = extract_field (FLD_SVE_Pd, inst->value, 0);
1213 insert_field (FLD_SVE_Pm, &inst->value, value, 0);
1214 break;
1215 case OP_MOVZS_P_P_P:
1216 case OP_MOVZ_P_P_P:
1217 /* Copy Pn to Pm. */
1218 value = extract_field (FLD_SVE_Pn, inst->value, 0);
1219 insert_field (FLD_SVE_Pm, &inst->value, value, 0);
1220 break;
1221 case OP_NOTS_P_P_P_Z:
1222 case OP_NOT_P_P_P_Z:
1223 /* Copy Pg to Pm. */
1224 value = extract_field (FLD_SVE_Pg4_10, inst->value, 0);
1225 insert_field (FLD_SVE_Pm, &inst->value, value, 0);
1226 break;
1227 default: break;
1228 }
1229 }
1230
1231 /* Encode the 'size' and 'Q' field for e.g. SHADD. */
1232 static void
1233 encode_sizeq (aarch64_inst *inst)
1234 {
1235 aarch64_insn sizeq;
1236 enum aarch64_field_kind kind;
1237 int idx;
1238
1239 /* Get the index of the operand whose information we are going to use
1240 to encode the size and Q fields.
1241 This is deduced from the possible valid qualifier lists. */
1242 idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
1243 DEBUG_TRACE ("idx: %d; qualifier: %s", idx,
1244 aarch64_get_qualifier_name (inst->operands[idx].qualifier));
1245 sizeq = aarch64_get_qualifier_standard_value (inst->operands[idx].qualifier);
1246 /* Q */
1247 insert_field (FLD_Q, &inst->value, sizeq & 0x1, inst->opcode->mask);
1248 /* size */
1249 if (inst->opcode->iclass == asisdlse
1250 || inst->opcode->iclass == asisdlsep
1251 || inst->opcode->iclass == asisdlso
1252 || inst->opcode->iclass == asisdlsop)
1253 kind = FLD_vldst_size;
1254 else
1255 kind = FLD_size;
1256 insert_field (kind, &inst->value, (sizeq >> 1) & 0x3, inst->opcode->mask);
1257 }
1258
1259 /* Opcodes that have fields shared by multiple operands are usually flagged
1260 with flags. In this function, we detect such flags and use the
1261 information in one of the related operands to do the encoding. The 'one'
1262 operand is not any operand but one of the operands that has the enough
1263 information for such an encoding. */
1264
1265 static void
1266 do_special_encoding (struct aarch64_inst *inst)
1267 {
1268 int idx;
1269 aarch64_insn value = 0;
1270
1271 DEBUG_TRACE ("enter with coding 0x%x", (uint32_t) inst->value);
1272
1273 /* Condition for truly conditional executed instructions, e.g. b.cond. */
1274 if (inst->opcode->flags & F_COND)
1275 {
1276 insert_field (FLD_cond2, &inst->value, inst->cond->value, 0);
1277 }
1278 if (inst->opcode->flags & F_SF)
1279 {
1280 idx = select_operand_for_sf_field_coding (inst->opcode);
1281 value = (inst->operands[idx].qualifier == AARCH64_OPND_QLF_X
1282 || inst->operands[idx].qualifier == AARCH64_OPND_QLF_SP)
1283 ? 1 : 0;
1284 insert_field (FLD_sf, &inst->value, value, 0);
1285 if (inst->opcode->flags & F_N)
1286 insert_field (FLD_N, &inst->value, value, inst->opcode->mask);
1287 }
1288 if (inst->opcode->flags & F_LSE_SZ)
1289 {
1290 idx = select_operand_for_sf_field_coding (inst->opcode);
1291 value = (inst->operands[idx].qualifier == AARCH64_OPND_QLF_X
1292 || inst->operands[idx].qualifier == AARCH64_OPND_QLF_SP)
1293 ? 1 : 0;
1294 insert_field (FLD_lse_sz, &inst->value, value, 0);
1295 }
1296 if (inst->opcode->flags & F_SIZEQ)
1297 encode_sizeq (inst);
1298 if (inst->opcode->flags & F_FPTYPE)
1299 {
1300 idx = select_operand_for_fptype_field_coding (inst->opcode);
1301 switch (inst->operands[idx].qualifier)
1302 {
1303 case AARCH64_OPND_QLF_S_S: value = 0; break;
1304 case AARCH64_OPND_QLF_S_D: value = 1; break;
1305 case AARCH64_OPND_QLF_S_H: value = 3; break;
1306 default: assert (0);
1307 }
1308 insert_field (FLD_type, &inst->value, value, 0);
1309 }
1310 if (inst->opcode->flags & F_SSIZE)
1311 {
1312 enum aarch64_opnd_qualifier qualifier;
1313 idx = select_operand_for_scalar_size_field_coding (inst->opcode);
1314 qualifier = inst->operands[idx].qualifier;
1315 assert (qualifier >= AARCH64_OPND_QLF_S_B
1316 && qualifier <= AARCH64_OPND_QLF_S_Q);
1317 value = aarch64_get_qualifier_standard_value (qualifier);
1318 insert_field (FLD_size, &inst->value, value, inst->opcode->mask);
1319 }
1320 if (inst->opcode->flags & F_T)
1321 {
1322 int num; /* num of consecutive '0's on the right side of imm5<3:0>. */
1323 aarch64_field field = {0, 0};
1324 enum aarch64_opnd_qualifier qualifier;
1325
1326 idx = 0;
1327 qualifier = inst->operands[idx].qualifier;
1328 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1329 == AARCH64_OPND_CLASS_SIMD_REG
1330 && qualifier >= AARCH64_OPND_QLF_V_8B
1331 && qualifier <= AARCH64_OPND_QLF_V_2D);
1332 /* imm5<3:0> q <t>
1333 0000 x reserved
1334 xxx1 0 8b
1335 xxx1 1 16b
1336 xx10 0 4h
1337 xx10 1 8h
1338 x100 0 2s
1339 x100 1 4s
1340 1000 0 reserved
1341 1000 1 2d */
1342 value = aarch64_get_qualifier_standard_value (qualifier);
1343 insert_field (FLD_Q, &inst->value, value & 0x1, inst->opcode->mask);
1344 num = (int) value >> 1;
1345 assert (num >= 0 && num <= 3);
1346 gen_sub_field (FLD_imm5, 0, num + 1, &field);
1347 insert_field_2 (&field, &inst->value, 1 << num, inst->opcode->mask);
1348 }
1349 if (inst->opcode->flags & F_GPRSIZE_IN_Q)
1350 {
1351 /* Use Rt to encode in the case of e.g.
1352 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
1353 enum aarch64_opnd_qualifier qualifier;
1354 idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
1355 if (idx == -1)
1356 /* Otherwise use the result operand, which has to be a integer
1357 register. */
1358 idx = 0;
1359 assert (idx == 0 || idx == 1);
1360 assert (aarch64_get_operand_class (inst->opcode->operands[idx])
1361 == AARCH64_OPND_CLASS_INT_REG);
1362 qualifier = inst->operands[idx].qualifier;
1363 insert_field (FLD_Q, &inst->value,
1364 aarch64_get_qualifier_standard_value (qualifier), 0);
1365 }
1366 if (inst->opcode->flags & F_LDS_SIZE)
1367 {
1368 /* e.g. LDRSB <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1369 enum aarch64_opnd_qualifier qualifier;
1370 aarch64_field field = {0, 0};
1371 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1372 == AARCH64_OPND_CLASS_INT_REG);
1373 gen_sub_field (FLD_opc, 0, 1, &field);
1374 qualifier = inst->operands[0].qualifier;
1375 insert_field_2 (&field, &inst->value,
1376 1 - aarch64_get_qualifier_standard_value (qualifier), 0);
1377 }
1378 /* Miscellaneous encoding as the last step. */
1379 if (inst->opcode->flags & F_MISC)
1380 do_misc_encoding (inst);
1381
1382 DEBUG_TRACE ("exit with coding 0x%x", (uint32_t) inst->value);
1383 }
1384
1385 /* Some instructions (including all SVE ones) use the instruction class
1386 to describe how a qualifiers_list index is represented in the instruction
1387 encoding. If INST is such an instruction, encode the chosen qualifier
1388 variant. */
1389
1390 static void
1391 aarch64_encode_variant_using_iclass (struct aarch64_inst *inst)
1392 {
1393 switch (inst->opcode->iclass)
1394 {
1395 case sve_cpy:
1396 insert_fields (&inst->value, aarch64_get_variant (inst),
1397 0, 2, FLD_SVE_M_14, FLD_size);
1398 break;
1399
1400 case sve_index:
1401 case sve_shift_pred:
1402 case sve_shift_unpred:
1403 /* For indices and shift amounts, the variant is encoded as
1404 part of the immediate. */
1405 break;
1406
1407 case sve_limm:
1408 /* For sve_limm, the .B, .H, and .S forms are just a convenience
1409 and depend on the immediate. They don't have a separate
1410 encoding. */
1411 break;
1412
1413 case sve_misc:
1414 /* sve_misc instructions have only a single variant. */
1415 break;
1416
1417 case sve_movprfx:
1418 insert_fields (&inst->value, aarch64_get_variant (inst),
1419 0, 2, FLD_SVE_M_16, FLD_size);
1420 break;
1421
1422 case sve_pred_zm:
1423 insert_field (FLD_SVE_M_4, &inst->value, aarch64_get_variant (inst), 0);
1424 break;
1425
1426 case sve_size_bhs:
1427 case sve_size_bhsd:
1428 insert_field (FLD_size, &inst->value, aarch64_get_variant (inst), 0);
1429 break;
1430
1431 case sve_size_hsd:
1432 insert_field (FLD_size, &inst->value, aarch64_get_variant (inst) + 1, 0);
1433 break;
1434
1435 case sve_size_sd:
1436 insert_field (FLD_SVE_sz, &inst->value, aarch64_get_variant (inst), 0);
1437 break;
1438
1439 default:
1440 break;
1441 }
1442 }
1443
1444 /* Converters converting an alias opcode instruction to its real form. */
1445
1446 /* ROR <Wd>, <Ws>, #<shift>
1447 is equivalent to:
1448 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
1449 static void
1450 convert_ror_to_extr (aarch64_inst *inst)
1451 {
1452 copy_operand_info (inst, 3, 2);
1453 copy_operand_info (inst, 2, 1);
1454 }
1455
1456 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
1457 is equivalent to:
1458 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
1459 static void
1460 convert_xtl_to_shll (aarch64_inst *inst)
1461 {
1462 inst->operands[2].qualifier = inst->operands[1].qualifier;
1463 inst->operands[2].imm.value = 0;
1464 }
1465
1466 /* Convert
1467 LSR <Xd>, <Xn>, #<shift>
1468 to
1469 UBFM <Xd>, <Xn>, #<shift>, #63. */
1470 static void
1471 convert_sr_to_bfm (aarch64_inst *inst)
1472 {
1473 inst->operands[3].imm.value =
1474 inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
1475 }
1476
1477 /* Convert MOV to ORR. */
1478 static void
1479 convert_mov_to_orr (aarch64_inst *inst)
1480 {
1481 /* MOV <Vd>.<T>, <Vn>.<T>
1482 is equivalent to:
1483 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
1484 copy_operand_info (inst, 2, 1);
1485 }
1486
1487 /* When <imms> >= <immr>, the instruction written:
1488 SBFX <Xd>, <Xn>, #<lsb>, #<width>
1489 is equivalent to:
1490 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
1491
1492 static void
1493 convert_bfx_to_bfm (aarch64_inst *inst)
1494 {
1495 int64_t lsb, width;
1496
1497 /* Convert the operand. */
1498 lsb = inst->operands[2].imm.value;
1499 width = inst->operands[3].imm.value;
1500 inst->operands[2].imm.value = lsb;
1501 inst->operands[3].imm.value = lsb + width - 1;
1502 }
1503
1504 /* When <imms> < <immr>, the instruction written:
1505 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
1506 is equivalent to:
1507 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
1508
1509 static void
1510 convert_bfi_to_bfm (aarch64_inst *inst)
1511 {
1512 int64_t lsb, width;
1513
1514 /* Convert the operand. */
1515 lsb = inst->operands[2].imm.value;
1516 width = inst->operands[3].imm.value;
1517 if (inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31)
1518 {
1519 inst->operands[2].imm.value = (32 - lsb) & 0x1f;
1520 inst->operands[3].imm.value = width - 1;
1521 }
1522 else
1523 {
1524 inst->operands[2].imm.value = (64 - lsb) & 0x3f;
1525 inst->operands[3].imm.value = width - 1;
1526 }
1527 }
1528
1529 /* The instruction written:
1530 BFC <Xd>, #<lsb>, #<width>
1531 is equivalent to:
1532 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
1533
1534 static void
1535 convert_bfc_to_bfm (aarch64_inst *inst)
1536 {
1537 int64_t lsb, width;
1538
1539 /* Insert XZR. */
1540 copy_operand_info (inst, 3, 2);
1541 copy_operand_info (inst, 2, 1);
1542 copy_operand_info (inst, 0, 0);
1543 inst->operands[1].reg.regno = 0x1f;
1544
1545 /* Convert the immedate operand. */
1546 lsb = inst->operands[2].imm.value;
1547 width = inst->operands[3].imm.value;
1548 if (inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31)
1549 {
1550 inst->operands[2].imm.value = (32 - lsb) & 0x1f;
1551 inst->operands[3].imm.value = width - 1;
1552 }
1553 else
1554 {
1555 inst->operands[2].imm.value = (64 - lsb) & 0x3f;
1556 inst->operands[3].imm.value = width - 1;
1557 }
1558 }
1559
1560 /* The instruction written:
1561 LSL <Xd>, <Xn>, #<shift>
1562 is equivalent to:
1563 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
1564
1565 static void
1566 convert_lsl_to_ubfm (aarch64_inst *inst)
1567 {
1568 int64_t shift = inst->operands[2].imm.value;
1569
1570 if (inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31)
1571 {
1572 inst->operands[2].imm.value = (32 - shift) & 0x1f;
1573 inst->operands[3].imm.value = 31 - shift;
1574 }
1575 else
1576 {
1577 inst->operands[2].imm.value = (64 - shift) & 0x3f;
1578 inst->operands[3].imm.value = 63 - shift;
1579 }
1580 }
1581
1582 /* CINC <Wd>, <Wn>, <cond>
1583 is equivalent to:
1584 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>). */
1585
1586 static void
1587 convert_to_csel (aarch64_inst *inst)
1588 {
1589 copy_operand_info (inst, 3, 2);
1590 copy_operand_info (inst, 2, 1);
1591 inst->operands[3].cond = get_inverted_cond (inst->operands[3].cond);
1592 }
1593
1594 /* CSET <Wd>, <cond>
1595 is equivalent to:
1596 CSINC <Wd>, WZR, WZR, invert(<cond>). */
1597
1598 static void
1599 convert_cset_to_csinc (aarch64_inst *inst)
1600 {
1601 copy_operand_info (inst, 3, 1);
1602 copy_operand_info (inst, 2, 0);
1603 copy_operand_info (inst, 1, 0);
1604 inst->operands[1].reg.regno = 0x1f;
1605 inst->operands[2].reg.regno = 0x1f;
1606 inst->operands[3].cond = get_inverted_cond (inst->operands[3].cond);
1607 }
1608
1609 /* MOV <Wd>, #<imm>
1610 is equivalent to:
1611 MOVZ <Wd>, #<imm16>, LSL #<shift>. */
1612
1613 static void
1614 convert_mov_to_movewide (aarch64_inst *inst)
1615 {
1616 int is32;
1617 uint32_t shift_amount;
1618 uint64_t value;
1619
1620 switch (inst->opcode->op)
1621 {
1622 case OP_MOV_IMM_WIDE:
1623 value = inst->operands[1].imm.value;
1624 break;
1625 case OP_MOV_IMM_WIDEN:
1626 value = ~inst->operands[1].imm.value;
1627 break;
1628 default:
1629 assert (0);
1630 }
1631 inst->operands[1].type = AARCH64_OPND_HALF;
1632 is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
1633 if (! aarch64_wide_constant_p (value, is32, &shift_amount))
1634 /* The constraint check should have guaranteed this wouldn't happen. */
1635 assert (0);
1636 value >>= shift_amount;
1637 value &= 0xffff;
1638 inst->operands[1].imm.value = value;
1639 inst->operands[1].shifter.kind = AARCH64_MOD_LSL;
1640 inst->operands[1].shifter.amount = shift_amount;
1641 }
1642
1643 /* MOV <Wd>, #<imm>
1644 is equivalent to:
1645 ORR <Wd>, WZR, #<imm>. */
1646
1647 static void
1648 convert_mov_to_movebitmask (aarch64_inst *inst)
1649 {
1650 copy_operand_info (inst, 2, 1);
1651 inst->operands[1].reg.regno = 0x1f;
1652 inst->operands[1].skip = 0;
1653 }
1654
1655 /* Some alias opcodes are assembled by being converted to their real-form. */
1656
1657 static void
1658 convert_to_real (aarch64_inst *inst, const aarch64_opcode *real)
1659 {
1660 const aarch64_opcode *alias = inst->opcode;
1661
1662 if ((alias->flags & F_CONV) == 0)
1663 goto convert_to_real_return;
1664
1665 switch (alias->op)
1666 {
1667 case OP_ASR_IMM:
1668 case OP_LSR_IMM:
1669 convert_sr_to_bfm (inst);
1670 break;
1671 case OP_LSL_IMM:
1672 convert_lsl_to_ubfm (inst);
1673 break;
1674 case OP_CINC:
1675 case OP_CINV:
1676 case OP_CNEG:
1677 convert_to_csel (inst);
1678 break;
1679 case OP_CSET:
1680 case OP_CSETM:
1681 convert_cset_to_csinc (inst);
1682 break;
1683 case OP_UBFX:
1684 case OP_BFXIL:
1685 case OP_SBFX:
1686 convert_bfx_to_bfm (inst);
1687 break;
1688 case OP_SBFIZ:
1689 case OP_BFI:
1690 case OP_UBFIZ:
1691 convert_bfi_to_bfm (inst);
1692 break;
1693 case OP_BFC:
1694 convert_bfc_to_bfm (inst);
1695 break;
1696 case OP_MOV_V:
1697 convert_mov_to_orr (inst);
1698 break;
1699 case OP_MOV_IMM_WIDE:
1700 case OP_MOV_IMM_WIDEN:
1701 convert_mov_to_movewide (inst);
1702 break;
1703 case OP_MOV_IMM_LOG:
1704 convert_mov_to_movebitmask (inst);
1705 break;
1706 case OP_ROR_IMM:
1707 convert_ror_to_extr (inst);
1708 break;
1709 case OP_SXTL:
1710 case OP_SXTL2:
1711 case OP_UXTL:
1712 case OP_UXTL2:
1713 convert_xtl_to_shll (inst);
1714 break;
1715 default:
1716 break;
1717 }
1718
1719 convert_to_real_return:
1720 aarch64_replace_opcode (inst, real);
1721 }
1722
1723 /* Encode *INST_ORI of the opcode code OPCODE.
1724 Return the encoded result in *CODE and if QLF_SEQ is not NULL, return the
1725 matched operand qualifier sequence in *QLF_SEQ. */
1726
1727 int
1728 aarch64_opcode_encode (const aarch64_opcode *opcode,
1729 const aarch64_inst *inst_ori, aarch64_insn *code,
1730 aarch64_opnd_qualifier_t *qlf_seq,
1731 aarch64_operand_error *mismatch_detail)
1732 {
1733 int i;
1734 const aarch64_opcode *aliased;
1735 aarch64_inst copy, *inst;
1736
1737 DEBUG_TRACE ("enter with %s", opcode->name);
1738
1739 /* Create a copy of *INST_ORI, so that we can do any change we want. */
1740 copy = *inst_ori;
1741 inst = &copy;
1742
1743 assert (inst->opcode == NULL || inst->opcode == opcode);
1744 if (inst->opcode == NULL)
1745 inst->opcode = opcode;
1746
1747 /* Constrain the operands.
1748 After passing this, the encoding is guaranteed to succeed. */
1749 if (aarch64_match_operands_constraint (inst, mismatch_detail) == 0)
1750 {
1751 DEBUG_TRACE ("FAIL since operand constraint not met");
1752 return 0;
1753 }
1754
1755 /* Get the base value.
1756 Note: this has to be before the aliasing handling below in order to
1757 get the base value from the alias opcode before we move on to the
1758 aliased opcode for encoding. */
1759 inst->value = opcode->opcode;
1760
1761 /* No need to do anything else if the opcode does not have any operand. */
1762 if (aarch64_num_of_operands (opcode) == 0)
1763 goto encoding_exit;
1764
1765 /* Assign operand indexes and check types. Also put the matched
1766 operand qualifiers in *QLF_SEQ to return. */
1767 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
1768 {
1769 assert (opcode->operands[i] == inst->operands[i].type);
1770 inst->operands[i].idx = i;
1771 if (qlf_seq != NULL)
1772 *qlf_seq = inst->operands[i].qualifier;
1773 }
1774
1775 aliased = aarch64_find_real_opcode (opcode);
1776 /* If the opcode is an alias and it does not ask for direct encoding by
1777 itself, the instruction will be transformed to the form of real opcode
1778 and the encoding will be carried out using the rules for the aliased
1779 opcode. */
1780 if (aliased != NULL && (opcode->flags & F_CONV))
1781 {
1782 DEBUG_TRACE ("real opcode '%s' has been found for the alias %s",
1783 aliased->name, opcode->name);
1784 /* Convert the operands to the form of the real opcode. */
1785 convert_to_real (inst, aliased);
1786 opcode = aliased;
1787 }
1788
1789 aarch64_opnd_info *info = inst->operands;
1790
1791 /* Call the inserter of each operand. */
1792 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++info)
1793 {
1794 const aarch64_operand *opnd;
1795 enum aarch64_opnd type = opcode->operands[i];
1796 if (type == AARCH64_OPND_NIL)
1797 break;
1798 if (info->skip)
1799 {
1800 DEBUG_TRACE ("skip the incomplete operand %d", i);
1801 continue;
1802 }
1803 opnd = &aarch64_operands[type];
1804 if (operand_has_inserter (opnd))
1805 aarch64_insert_operand (opnd, info, &inst->value, inst);
1806 }
1807
1808 /* Call opcode encoders indicated by flags. */
1809 if (opcode_has_special_coder (opcode))
1810 do_special_encoding (inst);
1811
1812 /* Possibly use the instruction class to encode the chosen qualifier
1813 variant. */
1814 aarch64_encode_variant_using_iclass (inst);
1815
1816 encoding_exit:
1817 DEBUG_TRACE ("exit with %s", opcode->name);
1818
1819 *code = inst->value;
1820
1821 return 1;
1822 }
This page took 0.064578 seconds and 3 git commands to generate.