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