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