/src/binutils-gdb/opcodes/aarch64-opc.h
Line | Count | Source |
1 | | /* aarch64-opc.h -- Header file for aarch64-opc.c and aarch64-opc-2.c. |
2 | | Copyright (C) 2012-2026 Free Software Foundation, Inc. |
3 | | Contributed by ARM Ltd. |
4 | | |
5 | | This file is part of the GNU opcodes library. |
6 | | |
7 | | This library is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3, or (at your option) |
10 | | any later version. |
11 | | |
12 | | It is distributed in the hope that it will be useful, but WITHOUT |
13 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
14 | | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
15 | | License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; see the file COPYING3. If not, |
19 | | see <http://www.gnu.org/licenses/>. */ |
20 | | |
21 | | #ifndef OPCODES_AARCH64_OPC_H |
22 | | #define OPCODES_AARCH64_OPC_H |
23 | | |
24 | | #include <string.h> |
25 | | #include "opcode/aarch64.h" |
26 | | |
27 | | /* Instruction fields. |
28 | | Keep this sorted alphanumerically and synced with the fields array |
29 | | in aarch64-opc.c. */ |
30 | | enum aarch64_field_kind |
31 | | { |
32 | | FLD_NIL, |
33 | | FLD_CONST_0, |
34 | | FLD_CONST_00, |
35 | | FLD_CONST_01, |
36 | | FLD_CONST_1, |
37 | | FLD_CRm, |
38 | | FLD_CRm_dsb_nxs, |
39 | | FLD_CRn, |
40 | | FLD_CSSC_imm8, |
41 | | FLD_H, |
42 | | FLD_L, |
43 | | FLD_LSE128_Rt, |
44 | | FLD_LSE128_Rt2, |
45 | | FLD_M, |
46 | | FLD_N, |
47 | | FLD_Q, |
48 | | FLD_Ra, |
49 | | FLD_Rd, |
50 | | FLD_Rm, |
51 | | FLD_Rn, |
52 | | FLD_Rs, |
53 | | FLD_Rt, |
54 | | FLD_Rt2, |
55 | | FLD_S, |
56 | | FLD_SM3_imm2, |
57 | | FLD_SME_Pdx2, |
58 | | FLD_SME_Pm, |
59 | | FLD_SME_PNd3, |
60 | | FLD_SME_PNn3, |
61 | | FLD_SME_Q, |
62 | | FLD_SME_Rm, |
63 | | FLD_SME_Rv, |
64 | | FLD_SME_V, |
65 | | FLD_SME_VL_10, |
66 | | FLD_SME_VL_13, |
67 | | FLD_SME_ZAda_1b, |
68 | | FLD_SME_ZAda_2b, |
69 | | FLD_SME_ZAda_3b, |
70 | | FLD_SME_Zdn2, |
71 | | FLD_SME_Zdn4, |
72 | | FLD_SME_Zm, |
73 | | FLD_SME_Zm17_3, |
74 | | FLD_SME_Zm2, |
75 | | FLD_SME_Zm4, |
76 | | FLD_SME_Zn2, |
77 | | FLD_SME_Zn4, |
78 | | FLD_SME_Zn6_3, |
79 | | FLD_SME_ZtT, |
80 | | FLD_SME_Zt3, |
81 | | FLD_SME_Zt2, |
82 | | FLD_SME_i1, |
83 | | FLD_SME_size_12, |
84 | | FLD_SME_size_22, |
85 | | FLD_SME_sz_23, |
86 | | FLD_SME_tszh, |
87 | | FLD_SME_tszl, |
88 | | FLD_SME_zero_mask, |
89 | | FLD_SVE_M_4, |
90 | | FLD_SVE_M_14, |
91 | | FLD_SVE_M_16, |
92 | | FLD_SVE_N, |
93 | | FLD_SVE_Pd, |
94 | | FLD_SVE_Pg3, |
95 | | FLD_SVE_Pg4_5, |
96 | | FLD_SVE_Pg4_10, |
97 | | FLD_SVE_Pg4_16, |
98 | | FLD_SVE_Pm, |
99 | | FLD_SVE_Pn, |
100 | | FLD_SVE_Pt, |
101 | | FLD_SVE_Rm, |
102 | | FLD_SVE_Rn, |
103 | | FLD_SVE_Vd, |
104 | | FLD_SVE_Vm, |
105 | | FLD_SVE_Vn, |
106 | | FLD_SVE_Za_5, |
107 | | FLD_SVE_Za_16, |
108 | | FLD_SVE_Zd, |
109 | | FLD_SVE_Zm_5, |
110 | | FLD_SVE_Zm_16, |
111 | | FLD_SVE_Zn, |
112 | | FLD_SVE_Zt, |
113 | | FLD_SVE_i1, |
114 | | FLD_SVE_i1_23, |
115 | | FLD_SVE_i2, |
116 | | FLD_SVE_i2h, |
117 | | FLD_SVE_i3h, |
118 | | FLD_SVE_i3h2, |
119 | | FLD_SVE_i3h3, |
120 | | FLD_SVE_i3l, |
121 | | FLD_SVE_i3l2, |
122 | | FLD_SVE_i4l2, |
123 | | FLD_SVE_imm3, |
124 | | FLD_SVE_imm4, |
125 | | FLD_SVE_imm5, |
126 | | FLD_SVE_imm5b, |
127 | | FLD_SVE_imm6, |
128 | | FLD_SVE_imm7, |
129 | | FLD_SVE_imm8, |
130 | | FLD_SVE_imm9, |
131 | | FLD_SVE_immr, |
132 | | FLD_SVE_imms, |
133 | | FLD_SVE_msz, |
134 | | FLD_SVE_pattern, |
135 | | FLD_SVE_prfop, |
136 | | FLD_SVE_rot1, |
137 | | FLD_SVE_rot2, |
138 | | FLD_SVE_rot3, |
139 | | FLD_SVE_size, |
140 | | FLD_SVE_sz, |
141 | | FLD_SVE_sz2, |
142 | | FLD_SVE_sz3, |
143 | | FLD_SVE_sz4, |
144 | | FLD_SVE_tsz, |
145 | | FLD_SVE_tszh, |
146 | | FLD_SVE_tszl_8, |
147 | | FLD_SVE_tszl_19, |
148 | | FLD_SVE_xs_14, |
149 | | FLD_SVE_xs_22, |
150 | | FLD_S_imm10, |
151 | | FLD_abc, |
152 | | FLD_asisdlso_opcode, |
153 | | FLD_b40, |
154 | | FLD_b5, |
155 | | FLD_cmode, |
156 | | FLD_cond, |
157 | | FLD_cond2, |
158 | | FLD_defgh, |
159 | | FLD_hw, |
160 | | FLD_imm1_0, |
161 | | FLD_imm1_2, |
162 | | FLD_imm1_3, |
163 | | FLD_imm1_8, |
164 | | FLD_imm1_10, |
165 | | FLD_imm1_14, |
166 | | FLD_imm1_15, |
167 | | FLD_imm1_16, |
168 | | FLD_imm1_22, |
169 | | FLD_imm2_0, |
170 | | FLD_imm2_1, |
171 | | FLD_imm2_2, |
172 | | FLD_imm2_4, |
173 | | FLD_imm2_8, |
174 | | FLD_imm2_10, |
175 | | FLD_imm2_12, |
176 | | FLD_imm2_13, |
177 | | FLD_imm2_15, |
178 | | FLD_imm2_16, |
179 | | FLD_imm2_19, |
180 | | FLD_imm3_0, |
181 | | FLD_imm3_5, |
182 | | FLD_imm3_10, |
183 | | FLD_imm3_12, |
184 | | FLD_imm3_14, |
185 | | FLD_imm3_15, |
186 | | FLD_imm3_19, |
187 | | FLD_imm4_0, |
188 | | FLD_imm4_5, |
189 | | FLD_imm4_10, |
190 | | FLD_imm4_11, |
191 | | FLD_imm4_14, |
192 | | FLD_imm5, |
193 | | FLD_imm6_10, |
194 | | FLD_imm6_15, |
195 | | FLD_imm7, |
196 | | FLD_imm8, |
197 | | FLD_imm9, |
198 | | FLD_imm9_5, |
199 | | FLD_imm12, |
200 | | FLD_imm14, |
201 | | FLD_imm16_0, |
202 | | FLD_imm16_5, |
203 | | FLD_imm17_1, |
204 | | FLD_imm17_2, |
205 | | FLD_imm19, |
206 | | FLD_imm26, |
207 | | FLD_immb, |
208 | | FLD_immh, |
209 | | FLD_immhi, |
210 | | FLD_immlo, |
211 | | FLD_immr, |
212 | | FLD_imms, |
213 | | FLD_index, |
214 | | FLD_index2, |
215 | | FLD_ldst_size, |
216 | | FLD_len, |
217 | | FLD_lse_sz, |
218 | | FLD_nzcv, |
219 | | FLD_op, |
220 | | FLD_op0, |
221 | | FLD_op1, |
222 | | FLD_op2, |
223 | | FLD_opc, |
224 | | FLD_opc1, |
225 | | FLD_opcode, |
226 | | FLD_option, |
227 | | FLD_rotate1, |
228 | | FLD_rotate2, |
229 | | FLD_rotate3, |
230 | | FLD_scale, |
231 | | FLD_sf, |
232 | | FLD_shift, |
233 | | FLD_size, |
234 | | FLD_sz, |
235 | | FLD_type, |
236 | | FLD_vldst_size, |
237 | | FLD_off3, |
238 | | FLD_off2, |
239 | | FLD_ZAn_1, |
240 | | FLD_ol, |
241 | | FLD_ZAn_2, |
242 | | FLD_ZAn_3, |
243 | | FLD_ZAn, |
244 | | FLD_opc2, |
245 | | FLD_rcpc3_size, |
246 | | FLD_brbop, |
247 | | FLD_ZA8_1, |
248 | | FLD_ZA7_2, |
249 | | FLD_ZA6_3, |
250 | | FLD_ZA5_4, |
251 | | }; |
252 | | |
253 | | /* Field description. |
254 | | |
255 | | If is_const is false, this identifies a bitfield in an instruction encoding |
256 | | that has size WIDTH and has its least significant bit at position NUM. |
257 | | |
258 | | If is_const is true, this represents the constant bit string of size WIDTH |
259 | | bits stored in the least significant bits of NUM. In this case, the |
260 | | leading 8-WIDTH bits of VALUE must be zero. |
261 | | |
262 | | A sequence of fields can be used to describe how instruction operands are |
263 | | represented in the 32-bit instruction encoding. |
264 | | |
265 | | For example, consider an instruction operand Zd that is an even numbered |
266 | | register in z16-z30, with the middle three bits of the register number |
267 | | stored in bits [19:17] of the encoding. The register number can then be |
268 | | constructed by concatenating: |
269 | | - a constant bit '1' (represented here as {1, 1, true}), |
270 | | - bits [19:17] of the encoding (represented here as {3, 17, false}), and |
271 | | - a constant bit '0' (represented here as {1, 0, true}). |
272 | | This sequence of fields fully describes both the constraints on which |
273 | | register numbers are valid, and how valid register numbers are represented |
274 | | in the instruction encoding. */ |
275 | | struct aarch64_field |
276 | | { |
277 | | unsigned int width:8; |
278 | | unsigned int num:7; |
279 | | bool is_const:1; |
280 | | }; |
281 | | |
282 | | typedef struct aarch64_field aarch64_field; |
283 | | |
284 | 295 | #define AARCH64_FIELD(lsb, width) {width, lsb, false} |
285 | | #define AARCH64_FIELD_CONST(val, width) {width, val, true} |
286 | 49.3k | #define AARCH64_FIELD_NIL {0, 0, false} |
287 | | |
288 | | extern const aarch64_field aarch64_fields[]; |
289 | | |
290 | | /* Operand description. */ |
291 | | |
292 | | struct aarch64_operand |
293 | | { |
294 | | enum aarch64_operand_class op_class; |
295 | | |
296 | | /* Name of the operand code; used mainly for the purpose of internal |
297 | | debugging. */ |
298 | | const char *name; |
299 | | |
300 | | unsigned int flags; |
301 | | |
302 | | /* The associated instruction bit-fields; no operand has more than 5 |
303 | | bit-fields */ |
304 | | enum aarch64_field_kind fields[6]; |
305 | | |
306 | | /* Brief description */ |
307 | | const char *desc; |
308 | | }; |
309 | | |
310 | | typedef struct aarch64_operand aarch64_operand; |
311 | | |
312 | | extern const aarch64_operand aarch64_operands[]; |
313 | | |
314 | | enum err_type |
315 | | verify_constraints (const struct aarch64_inst *, const aarch64_insn, bfd_vma, |
316 | | bool, aarch64_operand_error *, aarch64_instr_sequence*); |
317 | | |
318 | | /* Operand flags. */ |
319 | | |
320 | | #define OPD_F_HAS_INSERTER 0x00000001 |
321 | 13.0M | #define OPD_F_HAS_EXTRACTOR 0x00000002 |
322 | 2.68M | #define OPD_F_SEXT 0x00000004 /* Require sign-extension. */ |
323 | 3.57M | #define OPD_F_SHIFT_BY_2 0x00000008 /* Need to left shift the field |
324 | | value by 2 to get the value |
325 | | of an immediate operand. */ |
326 | 125k | #define OPD_F_MAYBE_SP 0x00000010 /* May potentially be SP. */ |
327 | 667k | #define OPD_F_OD_MASK 0x000001e0 /* Operand-dependent data. */ |
328 | 667k | #define OPD_F_OD_LSB 5 |
329 | 164k | #define OPD_F_NO_ZR 0x00000200 /* ZR index not allowed. */ |
330 | 2.01M | #define OPD_F_SHIFT_BY_3 0x00000400 /* Need to left shift the field |
331 | | value by 3 to get the value |
332 | | of an immediate operand. */ |
333 | 2.01M | #define OPD_F_SHIFT_BY_4 0x00000800 /* Need to left shift the field |
334 | | value by 4 to get the value |
335 | | of an immediate operand. */ |
336 | 898k | #define OPD_F_UNSIGNED 0x00001000 /* Expect an unsigned value. */ |
337 | | |
338 | | |
339 | | /* Register flags. */ |
340 | | |
341 | | #undef F_DEPRECATED |
342 | 1.06k | #define F_DEPRECATED (1 << 0) /* Deprecated system register. */ |
343 | | |
344 | | /* (1 << 1) Unused. */ |
345 | | |
346 | | #undef F_HASXT |
347 | 440 | #define F_HASXT (1 << 2) /* System instruction register <Xt> |
348 | | operand. */ |
349 | | |
350 | | #undef F_REG_READ |
351 | 6.10k | #define F_REG_READ (1 << 3) /* Register can only be used to read values |
352 | | out of. */ |
353 | | |
354 | | #undef F_REG_WRITE |
355 | 6.37k | #define F_REG_WRITE (1 << 4) /* Register can only be written to but not |
356 | | read from. */ |
357 | | |
358 | | #undef F_REG_IN_CRM |
359 | 504 | #define F_REG_IN_CRM (1 << 5) /* Register extra encoding in CRm. */ |
360 | | |
361 | | #undef F_REG_ALIAS |
362 | 1.06k | #define F_REG_ALIAS (1 << 6) /* Register name aliases another. */ |
363 | | |
364 | | #undef F_REG_128 |
365 | 0 | #define F_REG_128 (1 << 7) /* System register implementable as 128-bit wide. */ |
366 | | |
367 | | #undef F_TLBID_XT |
368 | 308 | #define F_TLBID_XT (1 << 8) /* System instruction register <Xt> as optional operand. */ |
369 | | |
370 | | |
371 | | /* PSTATE field name for the MSR instruction this is encoded in "op1:op2:CRm". |
372 | | Part of CRm can be used to encode <pstatefield>. E.g. CRm[3:1] for SME. |
373 | | In order to set/get full PSTATE field name use flag F_REG_IN_CRM and below |
374 | | macros to encode and decode CRm encoding. |
375 | | */ |
376 | | #define PSTATE_ENCODE_CRM(val) (val << 6) |
377 | 126 | #define PSTATE_DECODE_CRM(flags) ((flags >> 6) & 0x0f) |
378 | | |
379 | | #undef F_IMM_IN_CRM |
380 | 150 | #define F_IMM_IN_CRM (1 << 10) /* Immediate extra encoding in CRm. */ |
381 | | |
382 | | /* Also CRm may contain, in addition to <pstatefield> immediate. |
383 | | E.g. CRm[0] <imm1> at bit 0 for SME. Use below macros to encode and decode |
384 | | immediate mask. |
385 | | */ |
386 | | #define PSTATE_ENCODE_CRM_IMM(mask) (mask << 11) |
387 | 0 | #define PSTATE_DECODE_CRM_IMM(mask) ((mask >> 11) & 0x0f) |
388 | | |
389 | | /* Helper macro to ENCODE CRm and its immediate. */ |
390 | | #define PSTATE_ENCODE_CRM_AND_IMM(CVAL,IMASK) \ |
391 | | (F_REG_IN_CRM | PSTATE_ENCODE_CRM(CVAL) \ |
392 | | | F_IMM_IN_CRM | PSTATE_ENCODE_CRM_IMM(IMASK)) |
393 | | |
394 | | /* Bits [15, 18] contain the maximum value for an immediate MSR. */ |
395 | | #define F_REG_MAX_VALUE(X) ((X) << 15) |
396 | 150 | #define F_GET_REG_MAX_VALUE(X) (((X) >> 15) & 0x0f) |
397 | | |
398 | | static inline bool |
399 | | operand_has_inserter (const aarch64_operand *operand) |
400 | 0 | { |
401 | 0 | return (operand->flags & OPD_F_HAS_INSERTER) != 0; |
402 | 0 | } Unexecuted instantiation: aarch64-dis.c:operand_has_inserter Unexecuted instantiation: aarch64-dis-2.c:operand_has_inserter Unexecuted instantiation: aarch64-opc.c:operand_has_inserter Unexecuted instantiation: aarch64-opc-2.c:operand_has_inserter |
403 | | |
404 | | static inline bool |
405 | | operand_has_extractor (const aarch64_operand *operand) |
406 | 13.0M | { |
407 | 13.0M | return (operand->flags & OPD_F_HAS_EXTRACTOR) != 0; |
408 | 13.0M | } aarch64-dis.c:operand_has_extractor Line | Count | Source | 406 | 13.0M | { | 407 | 13.0M | return (operand->flags & OPD_F_HAS_EXTRACTOR) != 0; | 408 | 13.0M | } |
Unexecuted instantiation: aarch64-dis-2.c:operand_has_extractor Unexecuted instantiation: aarch64-opc.c:operand_has_extractor Unexecuted instantiation: aarch64-opc-2.c:operand_has_extractor |
409 | | |
410 | | static inline bool |
411 | | operand_need_sign_extension (const aarch64_operand *operand) |
412 | 2.68M | { |
413 | 2.68M | return (operand->flags & OPD_F_SEXT) != 0; |
414 | 2.68M | } aarch64-dis.c:operand_need_sign_extension Line | Count | Source | 412 | 2.68M | { | 413 | 2.68M | return (operand->flags & OPD_F_SEXT) != 0; | 414 | 2.68M | } |
Unexecuted instantiation: aarch64-dis-2.c:operand_need_sign_extension Unexecuted instantiation: aarch64-opc.c:operand_need_sign_extension Unexecuted instantiation: aarch64-opc-2.c:operand_need_sign_extension |
415 | | |
416 | | static inline bool |
417 | | operand_need_shift_by_two (const aarch64_operand *operand) |
418 | 3.57M | { |
419 | 3.57M | return (operand->flags & OPD_F_SHIFT_BY_2) != 0; |
420 | 3.57M | } aarch64-dis.c:operand_need_shift_by_two Line | Count | Source | 418 | 2.68M | { | 419 | 2.68M | return (operand->flags & OPD_F_SHIFT_BY_2) != 0; | 420 | 2.68M | } |
Unexecuted instantiation: aarch64-dis-2.c:operand_need_shift_by_two aarch64-opc.c:operand_need_shift_by_two Line | Count | Source | 418 | 898k | { | 419 | 898k | return (operand->flags & OPD_F_SHIFT_BY_2) != 0; | 420 | 898k | } |
Unexecuted instantiation: aarch64-opc-2.c:operand_need_shift_by_two |
421 | | |
422 | | static inline bool |
423 | | operand_need_shift_by_three (const aarch64_operand *operand) |
424 | 2.01M | { |
425 | 2.01M | return (operand->flags & OPD_F_SHIFT_BY_3) != 0; |
426 | 2.01M | } aarch64-dis.c:operand_need_shift_by_three Line | Count | Source | 424 | 2.01M | { | 425 | 2.01M | return (operand->flags & OPD_F_SHIFT_BY_3) != 0; | 426 | 2.01M | } |
Unexecuted instantiation: aarch64-dis-2.c:operand_need_shift_by_three Unexecuted instantiation: aarch64-opc.c:operand_need_shift_by_three Unexecuted instantiation: aarch64-opc-2.c:operand_need_shift_by_three |
427 | | |
428 | | static inline bool |
429 | | operand_need_shift_by_four (const aarch64_operand *operand) |
430 | 2.01M | { |
431 | 2.01M | return (operand->flags & OPD_F_SHIFT_BY_4) != 0; |
432 | 2.01M | } aarch64-dis.c:operand_need_shift_by_four Line | Count | Source | 430 | 2.01M | { | 431 | 2.01M | return (operand->flags & OPD_F_SHIFT_BY_4) != 0; | 432 | 2.01M | } |
Unexecuted instantiation: aarch64-dis-2.c:operand_need_shift_by_four Unexecuted instantiation: aarch64-opc.c:operand_need_shift_by_four Unexecuted instantiation: aarch64-opc-2.c:operand_need_shift_by_four |
433 | | |
434 | | static inline bool |
435 | | operand_need_unsigned_offset (const aarch64_operand *operand) |
436 | 898k | { |
437 | 898k | return (operand->flags & OPD_F_UNSIGNED) != 0; |
438 | 898k | } Unexecuted instantiation: aarch64-dis.c:operand_need_unsigned_offset Unexecuted instantiation: aarch64-dis-2.c:operand_need_unsigned_offset aarch64-opc.c:operand_need_unsigned_offset Line | Count | Source | 436 | 898k | { | 437 | 898k | return (operand->flags & OPD_F_UNSIGNED) != 0; | 438 | 898k | } |
Unexecuted instantiation: aarch64-opc-2.c:operand_need_unsigned_offset |
439 | | |
440 | | static inline bool |
441 | | operand_maybe_stack_pointer (const aarch64_operand *operand) |
442 | 125k | { |
443 | 125k | return (operand->flags & OPD_F_MAYBE_SP) != 0; |
444 | 125k | } Unexecuted instantiation: aarch64-dis.c:operand_maybe_stack_pointer Unexecuted instantiation: aarch64-dis-2.c:operand_maybe_stack_pointer aarch64-opc.c:operand_maybe_stack_pointer Line | Count | Source | 442 | 125k | { | 443 | 125k | return (operand->flags & OPD_F_MAYBE_SP) != 0; | 444 | 125k | } |
Unexecuted instantiation: aarch64-opc-2.c:operand_maybe_stack_pointer |
445 | | |
446 | | /* Return the value of the operand-specific data field (OPD_F_OD_MASK). */ |
447 | | static inline unsigned int |
448 | | get_operand_specific_data (const aarch64_operand *operand) |
449 | 667k | { |
450 | 667k | return (operand->flags & OPD_F_OD_MASK) >> OPD_F_OD_LSB; |
451 | 667k | } aarch64-dis.c:get_operand_specific_data Line | Count | Source | 449 | 356k | { | 450 | 356k | return (operand->flags & OPD_F_OD_MASK) >> OPD_F_OD_LSB; | 451 | 356k | } |
Unexecuted instantiation: aarch64-dis-2.c:get_operand_specific_data aarch64-opc.c:get_operand_specific_data Line | Count | Source | 449 | 311k | { | 450 | 311k | return (operand->flags & OPD_F_OD_MASK) >> OPD_F_OD_LSB; | 451 | 311k | } |
Unexecuted instantiation: aarch64-opc-2.c:get_operand_specific_data |
452 | | |
453 | | /* Return the width of field number N of operand *OPERAND. */ |
454 | | static inline unsigned |
455 | | get_operand_field_width (const aarch64_operand *operand, unsigned n) |
456 | 533 | { |
457 | 533 | assert (operand->fields[n] != FLD_NIL); |
458 | 533 | return aarch64_fields[operand->fields[n]].width; |
459 | 533 | } aarch64-dis.c:get_operand_field_width Line | Count | Source | 456 | 400 | { | 457 | 400 | assert (operand->fields[n] != FLD_NIL); | 458 | 400 | return aarch64_fields[operand->fields[n]].width; | 459 | 400 | } |
Unexecuted instantiation: aarch64-dis-2.c:get_operand_field_width aarch64-opc.c:get_operand_field_width Line | Count | Source | 456 | 133 | { | 457 | 133 | assert (operand->fields[n] != FLD_NIL); | 458 | 133 | return aarch64_fields[operand->fields[n]].width; | 459 | 133 | } |
Unexecuted instantiation: aarch64-opc-2.c:get_operand_field_width |
460 | | |
461 | | /* Return the total width of the operand *OPERAND. */ |
462 | | static inline unsigned |
463 | | get_operand_fields_width (const aarch64_operand *operand) |
464 | 3.30M | { |
465 | 3.30M | int i = 0; |
466 | 3.30M | unsigned width = 0; |
467 | 7.29M | while (operand->fields[i] != FLD_NIL) |
468 | 3.99M | width += aarch64_fields[operand->fields[i++]].width; |
469 | 3.30M | assert (width > 0 && width < 32); |
470 | 3.30M | return width; |
471 | 3.30M | } aarch64-dis.c:get_operand_fields_width Line | Count | Source | 464 | 1.01M | { | 465 | 1.01M | int i = 0; | 466 | 1.01M | unsigned width = 0; | 467 | 2.36M | while (operand->fields[i] != FLD_NIL) | 468 | 1.35M | width += aarch64_fields[operand->fields[i++]].width; | 469 | 1.01M | assert (width > 0 && width < 32); | 470 | 1.01M | return width; | 471 | 1.01M | } |
Unexecuted instantiation: aarch64-dis-2.c:get_operand_fields_width aarch64-opc.c:get_operand_fields_width Line | Count | Source | 464 | 2.28M | { | 465 | 2.28M | int i = 0; | 466 | 2.28M | unsigned width = 0; | 467 | 4.92M | while (operand->fields[i] != FLD_NIL) | 468 | 2.64M | width += aarch64_fields[operand->fields[i++]].width; | 469 | 2.28M | assert (width > 0 && width < 32); | 470 | 2.28M | return width; | 471 | 2.28M | } |
Unexecuted instantiation: aarch64-opc-2.c:get_operand_fields_width |
472 | | |
473 | | static inline const aarch64_operand * |
474 | | get_operand_from_code (enum aarch64_opnd code) |
475 | 3.18M | { |
476 | 3.18M | return aarch64_operands + code; |
477 | 3.18M | } Unexecuted instantiation: aarch64-dis.c:get_operand_from_code Unexecuted instantiation: aarch64-dis-2.c:get_operand_from_code aarch64-opc.c:get_operand_from_code Line | Count | Source | 475 | 3.18M | { | 476 | 3.18M | return aarch64_operands + code; | 477 | 3.18M | } |
Unexecuted instantiation: aarch64-opc-2.c:get_operand_from_code |
478 | | |
479 | | /* Operand qualifier and operand constraint checking. */ |
480 | | |
481 | | bool aarch64_match_operands_constraint (aarch64_inst *, |
482 | | aarch64_operand_error *); |
483 | | |
484 | | /* Operand qualifier related functions. */ |
485 | | const char* aarch64_get_qualifier_name (aarch64_opnd_qualifier_t); |
486 | | unsigned char aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t); |
487 | | aarch64_insn aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t); |
488 | | int aarch64_find_best_match (const aarch64_inst *, |
489 | | const aarch64_opnd_qualifier_seq_t *, |
490 | | int, aarch64_opnd_qualifier_t *, int *); |
491 | | |
492 | | static inline void |
493 | | reset_operand_qualifier (aarch64_inst *inst, int idx) |
494 | 42.6k | { |
495 | 42.6k | assert (idx >=0 && idx < aarch64_num_of_operands (inst->opcode)); |
496 | 42.6k | inst->operands[idx].qualifier = AARCH64_OPND_QLF_NIL; |
497 | 42.6k | } aarch64-dis.c:reset_operand_qualifier Line | Count | Source | 494 | 42.6k | { | 495 | 42.6k | assert (idx >=0 && idx < aarch64_num_of_operands (inst->opcode)); | 496 | 42.6k | inst->operands[idx].qualifier = AARCH64_OPND_QLF_NIL; | 497 | 42.6k | } |
Unexecuted instantiation: aarch64-dis-2.c:reset_operand_qualifier Unexecuted instantiation: aarch64-opc.c:reset_operand_qualifier Unexecuted instantiation: aarch64-opc-2.c:reset_operand_qualifier |
498 | | |
499 | | /* Inline functions operating on instruction bit-field(s). */ |
500 | | |
501 | | /* Generate a mask that has WIDTH number of consecutive 1s. */ |
502 | | |
503 | | static inline aarch64_insn |
504 | | gen_mask (int width) |
505 | 21.8M | { |
506 | 21.8M | return ((aarch64_insn) 1 << width) - 1; |
507 | 21.8M | } Line | Count | Source | 505 | 21.8M | { | 506 | 21.8M | return ((aarch64_insn) 1 << width) - 1; | 507 | 21.8M | } |
Unexecuted instantiation: aarch64-dis-2.c:gen_mask Unexecuted instantiation: aarch64-opc.c:gen_mask Unexecuted instantiation: aarch64-opc-2.c:gen_mask |
508 | | |
509 | | /* LSB_REL is the relative location of the lsb in the sub field, starting from 0. */ |
510 | | static inline int |
511 | | gen_sub_field (enum aarch64_field_kind kind, int lsb_rel, int width, aarch64_field *ret) |
512 | 46.7k | { |
513 | 46.7k | const aarch64_field *field = &aarch64_fields[kind]; |
514 | 46.7k | if (lsb_rel < 0 || width <= 0 || lsb_rel + width > field->width) |
515 | 84 | return 0; |
516 | 46.6k | ret->num = field->num + lsb_rel; |
517 | 46.6k | ret->width = width; |
518 | 46.6k | return 1; |
519 | 46.7k | } aarch64-dis.c:gen_sub_field Line | Count | Source | 512 | 46.7k | { | 513 | 46.7k | const aarch64_field *field = &aarch64_fields[kind]; | 514 | 46.7k | if (lsb_rel < 0 || width <= 0 || lsb_rel + width > field->width) | 515 | 84 | return 0; | 516 | 46.6k | ret->num = field->num + lsb_rel; | 517 | 46.6k | ret->width = width; | 518 | 46.6k | return 1; | 519 | 46.7k | } |
Unexecuted instantiation: aarch64-dis-2.c:gen_sub_field Unexecuted instantiation: aarch64-opc.c:gen_sub_field Unexecuted instantiation: aarch64-opc-2.c:gen_sub_field |
520 | | |
521 | | /* Insert VALUE into FIELD of CODE. MASK can be zero or the base mask |
522 | | of the opcode. */ |
523 | | |
524 | | static inline void |
525 | | insert_field_2 (const aarch64_field *field, aarch64_insn *code, |
526 | | aarch64_insn value, aarch64_insn mask) |
527 | 0 | { |
528 | 0 | assert (field->width < 32 && field->width >= 1 |
529 | 0 | && (field->is_const ? (field->num < 1 << field->width) |
530 | 0 | : (field->num + field->width <= 32))); |
531 | 0 | value &= gen_mask (field->width); |
532 | 0 | if (field->is_const) |
533 | 0 | { |
534 | 0 | assert (value == field->num); |
535 | 0 | return; |
536 | 0 | } |
537 | 0 | value <<= field->num; |
538 | 0 | /* In some opcodes, field can be part of the base opcode, e.g. the size |
539 | 0 | field in FADD. The following helps avoid corrupt the base opcode. */ |
540 | 0 | value &= ~mask; |
541 | 0 | *code |= value; |
542 | 0 | } Unexecuted instantiation: aarch64-dis.c:insert_field_2 Unexecuted instantiation: aarch64-dis-2.c:insert_field_2 Unexecuted instantiation: aarch64-opc.c:insert_field_2 Unexecuted instantiation: aarch64-opc-2.c:insert_field_2 |
543 | | |
544 | | /* Extract FIELD of CODE and return the value. MASK can be zero or the base |
545 | | mask of the opcode. */ |
546 | | |
547 | | static inline aarch64_insn |
548 | | extract_field_2 (const aarch64_field *field, aarch64_insn code, |
549 | | aarch64_insn mask) |
550 | 21.9M | { |
551 | 21.9M | aarch64_insn value; |
552 | | /* Check for constant field. */ |
553 | 21.9M | if (field->is_const) |
554 | 110k | return field->num; |
555 | | |
556 | | /* Clear any bit that is a part of the base opcode. */ |
557 | 21.8M | code &= ~mask; |
558 | 21.8M | value = (code >> field->num) & gen_mask (field->width); |
559 | 21.8M | return value; |
560 | 21.9M | } aarch64-dis.c:extract_field_2 Line | Count | Source | 550 | 21.9M | { | 551 | 21.9M | aarch64_insn value; | 552 | | /* Check for constant field. */ | 553 | 21.9M | if (field->is_const) | 554 | 110k | return field->num; | 555 | | | 556 | | /* Clear any bit that is a part of the base opcode. */ | 557 | 21.8M | code &= ~mask; | 558 | 21.8M | value = (code >> field->num) & gen_mask (field->width); | 559 | 21.8M | return value; | 560 | 21.9M | } |
Unexecuted instantiation: aarch64-dis-2.c:extract_field_2 Unexecuted instantiation: aarch64-opc.c:extract_field_2 Unexecuted instantiation: aarch64-opc-2.c:extract_field_2 |
561 | | |
562 | | /* Insert VALUE into field KIND of CODE. MASK can be zero or the base mask |
563 | | of the opcode. */ |
564 | | |
565 | | static inline void |
566 | | insert_field (enum aarch64_field_kind kind, aarch64_insn *code, |
567 | | aarch64_insn value, aarch64_insn mask) |
568 | 0 | { |
569 | 0 | insert_field_2 (&aarch64_fields[kind], code, value, mask); |
570 | 0 | } Unexecuted instantiation: aarch64-dis.c:insert_field Unexecuted instantiation: aarch64-dis-2.c:insert_field Unexecuted instantiation: aarch64-opc.c:insert_field Unexecuted instantiation: aarch64-opc-2.c:insert_field |
571 | | |
572 | | /* Extract field KIND of CODE and return the value. MASK can be zero or the |
573 | | base mask of the opcode. */ |
574 | | |
575 | | static inline aarch64_insn |
576 | | extract_field (enum aarch64_field_kind kind, aarch64_insn code, |
577 | | aarch64_insn mask) |
578 | 21.8M | { |
579 | 21.8M | return extract_field_2 (&aarch64_fields[kind], code, mask); |
580 | 21.8M | } aarch64-dis.c:extract_field Line | Count | Source | 578 | 21.8M | { | 579 | 21.8M | return extract_field_2 (&aarch64_fields[kind], code, mask); | 580 | 21.8M | } |
Unexecuted instantiation: aarch64-dis-2.c:extract_field Unexecuted instantiation: aarch64-opc.c:extract_field Unexecuted instantiation: aarch64-opc-2.c:extract_field |
581 | | |
582 | | extern aarch64_insn |
583 | | extract_fields (aarch64_insn code, aarch64_insn mask, ...); |
584 | | |
585 | | /* Inline functions selecting operand to do the encoding/decoding for a |
586 | | certain instruction bit-field. */ |
587 | | |
588 | | /* Select the operand to do the encoding/decoding of the 'sf' field. |
589 | | The heuristic-based rule is that the result operand is respected more. */ |
590 | | |
591 | | static inline int |
592 | | select_operand_for_sf_field_coding (const aarch64_opcode *opcode) |
593 | 1.57M | { |
594 | 1.57M | int idx = -1; |
595 | 1.57M | if (opcode->iclass == fprcvtfloat2int) |
596 | 858 | return 0; |
597 | 1.56M | else if (opcode->iclass == fprcvtint2float) |
598 | 195 | return 1; |
599 | | |
600 | 1.56M | if (aarch64_get_operand_class (opcode->operands[0]) |
601 | 1.56M | == AARCH64_OPND_CLASS_INT_REG) |
602 | | /* normal case. */ |
603 | 1.56M | idx = 0; |
604 | 997 | else if (aarch64_get_operand_class (opcode->operands[1]) |
605 | 997 | == AARCH64_OPND_CLASS_INT_REG) |
606 | | /* e.g. float2fix. */ |
607 | 997 | idx = 1; |
608 | 0 | else |
609 | 0 | { assert (0); abort (); } |
610 | 1.56M | return idx; |
611 | 1.56M | } aarch64-dis.c:select_operand_for_sf_field_coding Line | Count | Source | 593 | 1.57M | { | 594 | 1.57M | int idx = -1; | 595 | 1.57M | if (opcode->iclass == fprcvtfloat2int) | 596 | 858 | return 0; | 597 | 1.56M | else if (opcode->iclass == fprcvtint2float) | 598 | 195 | return 1; | 599 | | | 600 | 1.56M | if (aarch64_get_operand_class (opcode->operands[0]) | 601 | 1.56M | == AARCH64_OPND_CLASS_INT_REG) | 602 | | /* normal case. */ | 603 | 1.56M | idx = 0; | 604 | 997 | else if (aarch64_get_operand_class (opcode->operands[1]) | 605 | 997 | == AARCH64_OPND_CLASS_INT_REG) | 606 | | /* e.g. float2fix. */ | 607 | 997 | idx = 1; | 608 | 0 | else | 609 | 0 | { assert (0); abort (); } | 610 | 1.56M | return idx; | 611 | 1.56M | } |
Unexecuted instantiation: aarch64-dis-2.c:select_operand_for_sf_field_coding Unexecuted instantiation: aarch64-opc.c:select_operand_for_sf_field_coding Unexecuted instantiation: aarch64-opc-2.c:select_operand_for_sf_field_coding |
612 | | |
613 | | /* Select the operand to do the encoding/decoding of the 'type' field in |
614 | | the floating-point instructions. |
615 | | The heuristic-based rule is that the source operand is respected more. */ |
616 | | |
617 | | static inline int |
618 | | select_operand_for_fptype_field_coding (const aarch64_opcode *opcode) |
619 | 46.3k | { |
620 | 46.3k | int idx; |
621 | 46.3k | if (opcode->iclass == fprcvtfloat2int) |
622 | 858 | return 1; |
623 | 45.5k | else if (opcode->iclass == fprcvtint2float) |
624 | 195 | return 0; |
625 | | |
626 | 45.3k | if (aarch64_get_operand_class (opcode->operands[1]) |
627 | 45.3k | == AARCH64_OPND_CLASS_FP_REG) |
628 | | /* normal case. */ |
629 | 44.0k | idx = 1; |
630 | 1.22k | else if (aarch64_get_operand_class (opcode->operands[0]) |
631 | 1.22k | == AARCH64_OPND_CLASS_FP_REG) |
632 | | /* e.g. float2fix. */ |
633 | 1.22k | idx = 0; |
634 | 0 | else |
635 | 0 | { assert (0); abort (); } |
636 | 45.3k | return idx; |
637 | 45.3k | } aarch64-dis.c:select_operand_for_fptype_field_coding Line | Count | Source | 619 | 46.3k | { | 620 | 46.3k | int idx; | 621 | 46.3k | if (opcode->iclass == fprcvtfloat2int) | 622 | 858 | return 1; | 623 | 45.5k | else if (opcode->iclass == fprcvtint2float) | 624 | 195 | return 0; | 625 | | | 626 | 45.3k | if (aarch64_get_operand_class (opcode->operands[1]) | 627 | 45.3k | == AARCH64_OPND_CLASS_FP_REG) | 628 | | /* normal case. */ | 629 | 44.0k | idx = 1; | 630 | 1.22k | else if (aarch64_get_operand_class (opcode->operands[0]) | 631 | 1.22k | == AARCH64_OPND_CLASS_FP_REG) | 632 | | /* e.g. float2fix. */ | 633 | 1.22k | idx = 0; | 634 | 0 | else | 635 | 0 | { assert (0); abort (); } | 636 | 45.3k | return idx; | 637 | 45.3k | } |
Unexecuted instantiation: aarch64-dis-2.c:select_operand_for_fptype_field_coding Unexecuted instantiation: aarch64-opc.c:select_operand_for_fptype_field_coding Unexecuted instantiation: aarch64-opc-2.c:select_operand_for_fptype_field_coding |
638 | | |
639 | | /* Select the operand to do the encoding/decoding of the 'size' field in |
640 | | the AdvSIMD scalar instructions. |
641 | | The heuristic-based rule is that the destination operand is respected |
642 | | more. */ |
643 | | |
644 | | static inline int |
645 | | select_operand_for_scalar_size_field_coding (const aarch64_opcode *opcode) |
646 | 12.9k | { |
647 | 12.9k | int src_size = 0, dst_size = 0; |
648 | 12.9k | if (aarch64_get_operand_class (opcode->operands[0]) |
649 | 12.9k | == AARCH64_OPND_CLASS_SISD_REG) |
650 | 12.9k | dst_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][0]); |
651 | 12.9k | if (aarch64_get_operand_class (opcode->operands[1]) |
652 | 12.9k | == AARCH64_OPND_CLASS_SISD_REG) |
653 | 12.9k | src_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][1]); |
654 | 12.9k | if (src_size == dst_size && src_size == 0) |
655 | 0 | { assert (0); abort (); } |
656 | | /* When the result is not a sisd register or it is a long operation. */ |
657 | 12.9k | if (dst_size == 0 || dst_size == src_size << 1) |
658 | 2.28k | return 1; |
659 | 10.6k | else |
660 | 10.6k | return 0; |
661 | 12.9k | } aarch64-dis.c:select_operand_for_scalar_size_field_coding Line | Count | Source | 646 | 12.9k | { | 647 | 12.9k | int src_size = 0, dst_size = 0; | 648 | 12.9k | if (aarch64_get_operand_class (opcode->operands[0]) | 649 | 12.9k | == AARCH64_OPND_CLASS_SISD_REG) | 650 | 12.9k | dst_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][0]); | 651 | 12.9k | if (aarch64_get_operand_class (opcode->operands[1]) | 652 | 12.9k | == AARCH64_OPND_CLASS_SISD_REG) | 653 | 12.9k | src_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][1]); | 654 | 12.9k | if (src_size == dst_size && src_size == 0) | 655 | 0 | { assert (0); abort (); } | 656 | | /* When the result is not a sisd register or it is a long operation. */ | 657 | 12.9k | if (dst_size == 0 || dst_size == src_size << 1) | 658 | 2.28k | return 1; | 659 | 10.6k | else | 660 | 10.6k | return 0; | 661 | 12.9k | } |
Unexecuted instantiation: aarch64-dis-2.c:select_operand_for_scalar_size_field_coding Unexecuted instantiation: aarch64-opc.c:select_operand_for_scalar_size_field_coding Unexecuted instantiation: aarch64-opc-2.c:select_operand_for_scalar_size_field_coding |
662 | | |
663 | | /* Select the operand to do the encoding/decoding of the 'size:Q' fields in |
664 | | the AdvSIMD instructions. */ |
665 | | |
666 | | int aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *); |
667 | | |
668 | | /* Miscellaneous. */ |
669 | | |
670 | | aarch64_insn aarch64_get_operand_modifier_value (enum aarch64_modifier_kind); |
671 | | enum aarch64_modifier_kind |
672 | | aarch64_get_operand_modifier_from_value (aarch64_insn, bool); |
673 | | |
674 | | |
675 | | bool aarch64_wide_constant_p (uint64_t, int, unsigned int *); |
676 | | bool aarch64_logical_immediate_p (uint64_t, int, aarch64_insn *); |
677 | | int aarch64_shrink_expanded_imm8 (uint64_t); |
678 | | |
679 | | /* Copy the content of INST->OPERANDS[SRC] to INST->OPERANDS[DST]. */ |
680 | | static inline void |
681 | | copy_operand_info (aarch64_inst *inst, int dst, int src) |
682 | 1.51k | { |
683 | 1.51k | assert (dst >= 0 && src >= 0 && dst < AARCH64_MAX_OPND_NUM |
684 | 1.51k | && src < AARCH64_MAX_OPND_NUM); |
685 | 1.51k | memcpy (&inst->operands[dst], &inst->operands[src], |
686 | 1.51k | sizeof (aarch64_opnd_info)); |
687 | 1.51k | inst->operands[dst].idx = dst; |
688 | 1.51k | } aarch64-dis.c:copy_operand_info Line | Count | Source | 682 | 1.51k | { | 683 | 1.51k | assert (dst >= 0 && src >= 0 && dst < AARCH64_MAX_OPND_NUM | 684 | 1.51k | && src < AARCH64_MAX_OPND_NUM); | 685 | 1.51k | memcpy (&inst->operands[dst], &inst->operands[src], | 686 | 1.51k | sizeof (aarch64_opnd_info)); | 687 | 1.51k | inst->operands[dst].idx = dst; | 688 | 1.51k | } |
Unexecuted instantiation: aarch64-dis-2.c:copy_operand_info Unexecuted instantiation: aarch64-opc.c:copy_operand_info Unexecuted instantiation: aarch64-opc-2.c:copy_operand_info |
689 | | |
690 | | /* A primitive log caculator. */ |
691 | | |
692 | | static inline unsigned int |
693 | | get_logsz (unsigned int size) |
694 | 233k | { |
695 | 233k | const unsigned char ls[16] = |
696 | 233k | {0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4}; |
697 | 233k | if (size > 16) |
698 | 0 | { |
699 | 0 | assert (0); |
700 | 0 | return -1; |
701 | 0 | } |
702 | 233k | assert (ls[size - 1] != (unsigned char)-1); |
703 | 233k | return ls[size - 1]; |
704 | 233k | } Line | Count | Source | 694 | 205k | { | 695 | 205k | const unsigned char ls[16] = | 696 | 205k | {0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4}; | 697 | 205k | if (size > 16) | 698 | 0 | { | 699 | 0 | assert (0); | 700 | 0 | return -1; | 701 | 0 | } | 702 | 205k | assert (ls[size - 1] != (unsigned char)-1); | 703 | 205k | return ls[size - 1]; | 704 | 205k | } |
Unexecuted instantiation: aarch64-dis-2.c:get_logsz Line | Count | Source | 694 | 27.8k | { | 695 | 27.8k | const unsigned char ls[16] = | 696 | 27.8k | {0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4}; | 697 | 27.8k | if (size > 16) | 698 | 0 | { | 699 | 0 | assert (0); | 700 | 0 | return -1; | 701 | 0 | } | 702 | 27.8k | assert (ls[size - 1] != (unsigned char)-1); | 703 | 27.8k | return ls[size - 1]; | 704 | 27.8k | } |
Unexecuted instantiation: aarch64-opc-2.c:get_logsz |
705 | | |
706 | | #endif /* OPCODES_AARCH64_OPC_H */ |