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