aarch64-opc.c revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls /* aarch64-opc.c -- AArch64 opcode support.
2 1.1.1.1.8.2 tls Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
3 1.1.1.1.8.2 tls Contributed by ARM Ltd.
4 1.1.1.1.8.2 tls
5 1.1.1.1.8.2 tls This file is part of the GNU opcodes library.
6 1.1.1.1.8.2 tls
7 1.1.1.1.8.2 tls This library is free software; you can redistribute it and/or modify
8 1.1.1.1.8.2 tls it under the terms of the GNU General Public License as published by
9 1.1.1.1.8.2 tls the Free Software Foundation; either version 3, or (at your option)
10 1.1.1.1.8.2 tls any later version.
11 1.1.1.1.8.2 tls
12 1.1.1.1.8.2 tls It is distributed in the hope that it will be useful, but WITHOUT
13 1.1.1.1.8.2 tls ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1.1.1.8.2 tls or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 1.1.1.1.8.2 tls License for more details.
16 1.1.1.1.8.2 tls
17 1.1.1.1.8.2 tls You should have received a copy of the GNU General Public License
18 1.1.1.1.8.2 tls along with this program; see the file COPYING3. If not,
19 1.1.1.1.8.2 tls see <http://www.gnu.org/licenses/>. */
20 1.1.1.1.8.2 tls
21 1.1.1.1.8.2 tls #include "sysdep.h"
22 1.1.1.1.8.2 tls #include <assert.h>
23 1.1.1.1.8.2 tls #include <stdlib.h>
24 1.1.1.1.8.2 tls #include <stdio.h>
25 1.1.1.1.8.2 tls #include <stdint.h>
26 1.1.1.1.8.2 tls #include <stdarg.h>
27 1.1.1.1.8.2 tls #include <inttypes.h>
28 1.1.1.1.8.2 tls
29 1.1.1.1.8.2 tls #include "opintl.h"
30 1.1.1.1.8.2 tls
31 1.1.1.1.8.2 tls #include "aarch64-opc.h"
32 1.1.1.1.8.2 tls
33 1.1.1.1.8.2 tls #ifdef DEBUG_AARCH64
34 1.1.1.1.8.2 tls int debug_dump = FALSE;
35 1.1.1.1.8.2 tls #endif /* DEBUG_AARCH64 */
36 1.1.1.1.8.2 tls
37 1.1.1.1.8.2 tls /* Helper functions to determine which operand to be used to encode/decode
38 1.1.1.1.8.2 tls the size:Q fields for AdvSIMD instructions. */
39 1.1.1.1.8.2 tls
40 1.1.1.1.8.2 tls static inline bfd_boolean
41 1.1.1.1.8.2 tls vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
42 1.1.1.1.8.2 tls {
43 1.1.1.1.8.2 tls return ((qualifier >= AARCH64_OPND_QLF_V_8B
44 1.1.1.1.8.2 tls && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
45 1.1.1.1.8.2 tls : FALSE);
46 1.1.1.1.8.2 tls }
47 1.1.1.1.8.2 tls
48 1.1.1.1.8.2 tls static inline bfd_boolean
49 1.1.1.1.8.2 tls fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
50 1.1.1.1.8.2 tls {
51 1.1.1.1.8.2 tls return ((qualifier >= AARCH64_OPND_QLF_S_B
52 1.1.1.1.8.2 tls && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
53 1.1.1.1.8.2 tls : FALSE);
54 1.1.1.1.8.2 tls }
55 1.1.1.1.8.2 tls
56 1.1.1.1.8.2 tls enum data_pattern
57 1.1.1.1.8.2 tls {
58 1.1.1.1.8.2 tls DP_UNKNOWN,
59 1.1.1.1.8.2 tls DP_VECTOR_3SAME,
60 1.1.1.1.8.2 tls DP_VECTOR_LONG,
61 1.1.1.1.8.2 tls DP_VECTOR_WIDE,
62 1.1.1.1.8.2 tls DP_VECTOR_ACROSS_LANES,
63 1.1.1.1.8.2 tls };
64 1.1.1.1.8.2 tls
65 1.1.1.1.8.2 tls static const char significant_operand_index [] =
66 1.1.1.1.8.2 tls {
67 1.1.1.1.8.2 tls 0, /* DP_UNKNOWN, by default using operand 0. */
68 1.1.1.1.8.2 tls 0, /* DP_VECTOR_3SAME */
69 1.1.1.1.8.2 tls 1, /* DP_VECTOR_LONG */
70 1.1.1.1.8.2 tls 2, /* DP_VECTOR_WIDE */
71 1.1.1.1.8.2 tls 1, /* DP_VECTOR_ACROSS_LANES */
72 1.1.1.1.8.2 tls };
73 1.1.1.1.8.2 tls
74 1.1.1.1.8.2 tls /* Given a sequence of qualifiers in QUALIFIERS, determine and return
75 1.1.1.1.8.2 tls the data pattern.
76 1.1.1.1.8.2 tls N.B. QUALIFIERS is a possible sequence of qualifiers each of which
77 1.1.1.1.8.2 tls corresponds to one of a sequence of operands. */
78 1.1.1.1.8.2 tls
79 1.1.1.1.8.2 tls static enum data_pattern
80 1.1.1.1.8.2 tls get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
81 1.1.1.1.8.2 tls {
82 1.1.1.1.8.2 tls if (vector_qualifier_p (qualifiers[0]) == TRUE)
83 1.1.1.1.8.2 tls {
84 1.1.1.1.8.2 tls /* e.g. v.4s, v.4s, v.4s
85 1.1.1.1.8.2 tls or v.4h, v.4h, v.h[3]. */
86 1.1.1.1.8.2 tls if (qualifiers[0] == qualifiers[1]
87 1.1.1.1.8.2 tls && vector_qualifier_p (qualifiers[2]) == TRUE
88 1.1.1.1.8.2 tls && (aarch64_get_qualifier_esize (qualifiers[0])
89 1.1.1.1.8.2 tls == aarch64_get_qualifier_esize (qualifiers[1]))
90 1.1.1.1.8.2 tls && (aarch64_get_qualifier_esize (qualifiers[0])
91 1.1.1.1.8.2 tls == aarch64_get_qualifier_esize (qualifiers[2])))
92 1.1.1.1.8.2 tls return DP_VECTOR_3SAME;
93 1.1.1.1.8.2 tls /* e.g. v.8h, v.8b, v.8b.
94 1.1.1.1.8.2 tls or v.4s, v.4h, v.h[2].
95 1.1.1.1.8.2 tls or v.8h, v.16b. */
96 1.1.1.1.8.2 tls if (vector_qualifier_p (qualifiers[1]) == TRUE
97 1.1.1.1.8.2 tls && aarch64_get_qualifier_esize (qualifiers[0]) != 0
98 1.1.1.1.8.2 tls && (aarch64_get_qualifier_esize (qualifiers[0])
99 1.1.1.1.8.2 tls == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
100 1.1.1.1.8.2 tls return DP_VECTOR_LONG;
101 1.1.1.1.8.2 tls /* e.g. v.8h, v.8h, v.8b. */
102 1.1.1.1.8.2 tls if (qualifiers[0] == qualifiers[1]
103 1.1.1.1.8.2 tls && vector_qualifier_p (qualifiers[2]) == TRUE
104 1.1.1.1.8.2 tls && aarch64_get_qualifier_esize (qualifiers[0]) != 0
105 1.1.1.1.8.2 tls && (aarch64_get_qualifier_esize (qualifiers[0])
106 1.1.1.1.8.2 tls == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
107 1.1.1.1.8.2 tls && (aarch64_get_qualifier_esize (qualifiers[0])
108 1.1.1.1.8.2 tls == aarch64_get_qualifier_esize (qualifiers[1])))
109 1.1.1.1.8.2 tls return DP_VECTOR_WIDE;
110 1.1.1.1.8.2 tls }
111 1.1.1.1.8.2 tls else if (fp_qualifier_p (qualifiers[0]) == TRUE)
112 1.1.1.1.8.2 tls {
113 1.1.1.1.8.2 tls /* e.g. SADDLV <V><d>, <Vn>.<T>. */
114 1.1.1.1.8.2 tls if (vector_qualifier_p (qualifiers[1]) == TRUE
115 1.1.1.1.8.2 tls && qualifiers[2] == AARCH64_OPND_QLF_NIL)
116 1.1.1.1.8.2 tls return DP_VECTOR_ACROSS_LANES;
117 1.1.1.1.8.2 tls }
118 1.1.1.1.8.2 tls
119 1.1.1.1.8.2 tls return DP_UNKNOWN;
120 1.1.1.1.8.2 tls }
121 1.1.1.1.8.2 tls
122 1.1.1.1.8.2 tls /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
123 1.1.1.1.8.2 tls the AdvSIMD instructions. */
124 1.1.1.1.8.2 tls /* N.B. it is possible to do some optimization that doesn't call
125 1.1.1.1.8.2 tls get_data_pattern each time when we need to select an operand. We can
126 1.1.1.1.8.2 tls either buffer the caculated the result or statically generate the data,
127 1.1.1.1.8.2 tls however, it is not obvious that the optimization will bring significant
128 1.1.1.1.8.2 tls benefit. */
129 1.1.1.1.8.2 tls
130 1.1.1.1.8.2 tls int
131 1.1.1.1.8.2 tls aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
132 1.1.1.1.8.2 tls {
133 1.1.1.1.8.2 tls return
134 1.1.1.1.8.2 tls significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
135 1.1.1.1.8.2 tls }
136 1.1.1.1.8.2 tls
137 1.1.1.1.8.2 tls const aarch64_field fields[] =
139 1.1.1.1.8.2 tls {
140 1.1.1.1.8.2 tls { 0, 0 }, /* NIL. */
141 1.1.1.1.8.2 tls { 0, 4 }, /* cond2: condition in truly conditional-executed inst. */
142 1.1.1.1.8.2 tls { 0, 4 }, /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
143 1.1.1.1.8.2 tls { 5, 5 }, /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
144 1.1.1.1.8.2 tls { 16, 3 }, /* abc: a:b:c bits in AdvSIMD modified immediate. */
145 1.1.1.1.8.2 tls { 5, 19 }, /* imm19: e.g. in CBZ. */
146 1.1.1.1.8.2 tls { 5, 19 }, /* immhi: e.g. in ADRP. */
147 1.1.1.1.8.2 tls { 29, 2 }, /* immlo: e.g. in ADRP. */
148 1.1.1.1.8.2 tls { 22, 2 }, /* size: in most AdvSIMD and floating-point instructions. */
149 1.1.1.1.8.2 tls { 10, 2 }, /* vldst_size: size field in the AdvSIMD load/store inst. */
150 1.1.1.1.8.2 tls { 29, 1 }, /* op: in AdvSIMD modified immediate instructions. */
151 1.1.1.1.8.2 tls { 30, 1 }, /* Q: in most AdvSIMD instructions. */
152 1.1.1.1.8.2 tls { 0, 5 }, /* Rt: in load/store instructions. */
153 1.1.1.1.8.2 tls { 0, 5 }, /* Rd: in many integer instructions. */
154 1.1.1.1.8.2 tls { 5, 5 }, /* Rn: in many integer instructions. */
155 1.1.1.1.8.2 tls { 10, 5 }, /* Rt2: in load/store pair instructions. */
156 1.1.1.1.8.2 tls { 10, 5 }, /* Ra: in fp instructions. */
157 1.1.1.1.8.2 tls { 5, 3 }, /* op2: in the system instructions. */
158 1.1.1.1.8.2 tls { 8, 4 }, /* CRm: in the system instructions. */
159 1.1.1.1.8.2 tls { 12, 4 }, /* CRn: in the system instructions. */
160 1.1.1.1.8.2 tls { 16, 3 }, /* op1: in the system instructions. */
161 1.1.1.1.8.2 tls { 19, 2 }, /* op0: in the system instructions. */
162 1.1.1.1.8.2 tls { 10, 3 }, /* imm3: in add/sub extended reg instructions. */
163 1.1.1.1.8.2 tls { 12, 4 }, /* cond: condition flags as a source operand. */
164 1.1.1.1.8.2 tls { 12, 4 }, /* opcode: in advsimd load/store instructions. */
165 1.1.1.1.8.2 tls { 12, 4 }, /* cmode: in advsimd modified immediate instructions. */
166 1.1.1.1.8.2 tls { 13, 3 }, /* asisdlso_opcode: opcode in advsimd ld/st single element. */
167 1.1.1.1.8.2 tls { 13, 2 }, /* len: in advsimd tbl/tbx instructions. */
168 1.1.1.1.8.2 tls { 16, 5 }, /* Rm: in ld/st reg offset and some integer inst. */
169 1.1.1.1.8.2 tls { 16, 5 }, /* Rs: in load/store exclusive instructions. */
170 1.1.1.1.8.2 tls { 13, 3 }, /* option: in ld/st reg offset + add/sub extended reg inst. */
171 1.1.1.1.8.2 tls { 12, 1 }, /* S: in load/store reg offset instructions. */
172 1.1.1.1.8.2 tls { 21, 2 }, /* hw: in move wide constant instructions. */
173 1.1.1.1.8.2 tls { 22, 2 }, /* opc: in load/store reg offset instructions. */
174 1.1.1.1.8.2 tls { 23, 1 }, /* opc1: in load/store reg offset instructions. */
175 1.1.1.1.8.2 tls { 22, 2 }, /* shift: in add/sub reg/imm shifted instructions. */
176 1.1.1.1.8.2 tls { 22, 2 }, /* type: floating point type field in fp data inst. */
177 1.1.1.1.8.2 tls { 30, 2 }, /* ldst_size: size field in ld/st reg offset inst. */
178 1.1.1.1.8.2 tls { 10, 6 }, /* imm6: in add/sub reg shifted instructions. */
179 1.1.1.1.8.2 tls { 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
180 1.1.1.1.8.2 tls { 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
181 1.1.1.1.8.2 tls { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
182 1.1.1.1.8.2 tls { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
183 1.1.1.1.8.2 tls { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
184 1.1.1.1.8.2 tls { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
185 1.1.1.1.8.2 tls { 5, 14 }, /* imm14: in test bit and branch instructions. */
186 1.1.1.1.8.2 tls { 5, 16 }, /* imm16: in exception instructions. */
187 1.1.1.1.8.2 tls { 0, 26 }, /* imm26: in unconditional branch instructions. */
188 1.1.1.1.8.2 tls { 10, 6 }, /* imms: in bitfield and logical immediate instructions. */
189 1.1.1.1.8.2 tls { 16, 6 }, /* immr: in bitfield and logical immediate instructions. */
190 1.1.1.1.8.2 tls { 16, 3 }, /* immb: in advsimd shift by immediate instructions. */
191 1.1.1.1.8.2 tls { 19, 4 }, /* immh: in advsimd shift by immediate instructions. */
192 1.1.1.1.8.2 tls { 22, 1 }, /* N: in logical (immediate) instructions. */
193 1.1.1.1.8.2 tls { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
194 1.1.1.1.8.2 tls { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
195 1.1.1.1.8.2 tls { 31, 1 }, /* sf: in integer data processing instructions. */
196 1.1.1.1.8.2 tls { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
197 1.1.1.1.8.2 tls { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
198 1.1.1.1.8.2 tls { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
199 1.1.1.1.8.2 tls { 31, 1 }, /* b5: in the test bit and branch instructions. */
200 1.1.1.1.8.2 tls { 19, 5 }, /* b40: in the test bit and branch instructions. */
201 1.1.1.1.8.2 tls { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
202 1.1.1.1.8.2 tls };
203 1.1.1.1.8.2 tls
204 1.1.1.1.8.2 tls enum aarch64_operand_class
205 1.1.1.1.8.2 tls aarch64_get_operand_class (enum aarch64_opnd type)
206 1.1.1.1.8.2 tls {
207 1.1.1.1.8.2 tls return aarch64_operands[type].op_class;
208 1.1.1.1.8.2 tls }
209 1.1.1.1.8.2 tls
210 1.1.1.1.8.2 tls const char*
211 1.1.1.1.8.2 tls aarch64_get_operand_name (enum aarch64_opnd type)
212 1.1.1.1.8.2 tls {
213 1.1.1.1.8.2 tls return aarch64_operands[type].name;
214 1.1.1.1.8.2 tls }
215 1.1.1.1.8.2 tls
216 1.1.1.1.8.2 tls /* Get operand description string.
217 1.1.1.1.8.2 tls This is usually for the diagnosis purpose. */
218 1.1.1.1.8.2 tls const char*
219 1.1.1.1.8.2 tls aarch64_get_operand_desc (enum aarch64_opnd type)
220 1.1.1.1.8.2 tls {
221 1.1.1.1.8.2 tls return aarch64_operands[type].desc;
222 1.1.1.1.8.2 tls }
223 1.1.1.1.8.2 tls
224 1.1.1.1.8.2 tls /* Table of all conditional affixes. */
225 1.1.1.1.8.2 tls const aarch64_cond aarch64_conds[16] =
226 1.1.1.1.8.2 tls {
227 1.1.1.1.8.2 tls {{"eq"}, 0x0},
228 1.1.1.1.8.2 tls {{"ne"}, 0x1},
229 1.1.1.1.8.2 tls {{"cs", "hs"}, 0x2},
230 1.1.1.1.8.2 tls {{"cc", "lo", "ul"}, 0x3},
231 1.1.1.1.8.2 tls {{"mi"}, 0x4},
232 1.1.1.1.8.2 tls {{"pl"}, 0x5},
233 1.1.1.1.8.2 tls {{"vs"}, 0x6},
234 1.1.1.1.8.2 tls {{"vc"}, 0x7},
235 1.1.1.1.8.2 tls {{"hi"}, 0x8},
236 1.1.1.1.8.2 tls {{"ls"}, 0x9},
237 1.1.1.1.8.2 tls {{"ge"}, 0xa},
238 1.1.1.1.8.2 tls {{"lt"}, 0xb},
239 1.1.1.1.8.2 tls {{"gt"}, 0xc},
240 1.1.1.1.8.2 tls {{"le"}, 0xd},
241 1.1.1.1.8.2 tls {{"al"}, 0xe},
242 1.1.1.1.8.2 tls {{"nv"}, 0xf},
243 1.1.1.1.8.2 tls };
244 1.1.1.1.8.2 tls
245 1.1.1.1.8.2 tls const aarch64_cond*
246 1.1.1.1.8.2 tls get_cond_from_value (aarch64_insn value)
247 1.1.1.1.8.2 tls {
248 1.1.1.1.8.2 tls assert (value < 16);
249 1.1.1.1.8.2 tls return &aarch64_conds[(unsigned int) value];
250 1.1.1.1.8.2 tls }
251 1.1.1.1.8.2 tls
252 1.1.1.1.8.2 tls const aarch64_cond*
253 1.1.1.1.8.2 tls get_inverted_cond (const aarch64_cond *cond)
254 1.1.1.1.8.2 tls {
255 1.1.1.1.8.2 tls return &aarch64_conds[cond->value ^ 0x1];
256 1.1.1.1.8.2 tls }
257 1.1.1.1.8.2 tls
258 1.1.1.1.8.2 tls /* Table describing the operand extension/shifting operators; indexed by
259 1.1.1.1.8.2 tls enum aarch64_modifier_kind.
260 1.1.1.1.8.2 tls
261 1.1.1.1.8.2 tls The value column provides the most common values for encoding modifiers,
262 1.1.1.1.8.2 tls which enables table-driven encoding/decoding for the modifiers. */
263 1.1.1.1.8.2 tls const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
264 1.1.1.1.8.2 tls {
265 1.1.1.1.8.2 tls {"none", 0x0},
266 1.1.1.1.8.2 tls {"msl", 0x0},
267 1.1.1.1.8.2 tls {"ror", 0x3},
268 1.1.1.1.8.2 tls {"asr", 0x2},
269 1.1.1.1.8.2 tls {"lsr", 0x1},
270 1.1.1.1.8.2 tls {"lsl", 0x0},
271 1.1.1.1.8.2 tls {"uxtb", 0x0},
272 1.1.1.1.8.2 tls {"uxth", 0x1},
273 1.1.1.1.8.2 tls {"uxtw", 0x2},
274 1.1.1.1.8.2 tls {"uxtx", 0x3},
275 1.1.1.1.8.2 tls {"sxtb", 0x4},
276 1.1.1.1.8.2 tls {"sxth", 0x5},
277 1.1.1.1.8.2 tls {"sxtw", 0x6},
278 1.1.1.1.8.2 tls {"sxtx", 0x7},
279 1.1.1.1.8.2 tls {NULL, 0},
280 1.1.1.1.8.2 tls };
281 1.1.1.1.8.2 tls
282 1.1.1.1.8.2 tls enum aarch64_modifier_kind
283 1.1.1.1.8.2 tls aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
284 1.1.1.1.8.2 tls {
285 1.1.1.1.8.2 tls return desc - aarch64_operand_modifiers;
286 1.1.1.1.8.2 tls }
287 1.1.1.1.8.2 tls
288 1.1.1.1.8.2 tls aarch64_insn
289 1.1.1.1.8.2 tls aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
290 1.1.1.1.8.2 tls {
291 1.1.1.1.8.2 tls return aarch64_operand_modifiers[kind].value;
292 1.1.1.1.8.2 tls }
293 1.1.1.1.8.2 tls
294 1.1.1.1.8.2 tls enum aarch64_modifier_kind
295 1.1.1.1.8.2 tls aarch64_get_operand_modifier_from_value (aarch64_insn value,
296 1.1.1.1.8.2 tls bfd_boolean extend_p)
297 1.1.1.1.8.2 tls {
298 1.1.1.1.8.2 tls if (extend_p == TRUE)
299 1.1.1.1.8.2 tls return AARCH64_MOD_UXTB + value;
300 1.1.1.1.8.2 tls else
301 1.1.1.1.8.2 tls return AARCH64_MOD_LSL - value;
302 1.1.1.1.8.2 tls }
303 1.1.1.1.8.2 tls
304 1.1.1.1.8.2 tls bfd_boolean
305 1.1.1.1.8.2 tls aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
306 1.1.1.1.8.2 tls {
307 1.1.1.1.8.2 tls return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
308 1.1.1.1.8.2 tls ? TRUE : FALSE;
309 1.1.1.1.8.2 tls }
310 1.1.1.1.8.2 tls
311 1.1.1.1.8.2 tls static inline bfd_boolean
312 1.1.1.1.8.2 tls aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
313 1.1.1.1.8.2 tls {
314 1.1.1.1.8.2 tls return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
315 1.1.1.1.8.2 tls ? TRUE : FALSE;
316 1.1.1.1.8.2 tls }
317 1.1.1.1.8.2 tls
318 1.1.1.1.8.2 tls const struct aarch64_name_value_pair aarch64_barrier_options[16] =
319 1.1.1.1.8.2 tls {
320 1.1.1.1.8.2 tls { "#0x00", 0x0 },
321 1.1.1.1.8.2 tls { "oshld", 0x1 },
322 1.1.1.1.8.2 tls { "oshst", 0x2 },
323 1.1.1.1.8.2 tls { "osh", 0x3 },
324 1.1.1.1.8.2 tls { "#0x04", 0x4 },
325 1.1.1.1.8.2 tls { "nshld", 0x5 },
326 1.1.1.1.8.2 tls { "nshst", 0x6 },
327 1.1.1.1.8.2 tls { "nsh", 0x7 },
328 1.1.1.1.8.2 tls { "#0x08", 0x8 },
329 1.1.1.1.8.2 tls { "ishld", 0x9 },
330 1.1.1.1.8.2 tls { "ishst", 0xa },
331 1.1.1.1.8.2 tls { "ish", 0xb },
332 1.1.1.1.8.2 tls { "#0x0c", 0xc },
333 1.1.1.1.8.2 tls { "ld", 0xd },
334 1.1.1.1.8.2 tls { "st", 0xe },
335 1.1.1.1.8.2 tls { "sy", 0xf },
336 1.1.1.1.8.2 tls };
337 1.1.1.1.8.2 tls
338 1.1.1.1.8.2 tls /* op -> op: load = 0 instruction = 1 store = 2
339 1.1.1.1.8.2 tls l -> level: 1-3
340 1.1.1.1.8.2 tls t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
341 1.1.1.1.8.2 tls #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
342 1.1.1.1.8.2 tls const struct aarch64_name_value_pair aarch64_prfops[32] =
343 1.1.1.1.8.2 tls {
344 1.1.1.1.8.2 tls { "pldl1keep", B(0, 1, 0) },
345 1.1.1.1.8.2 tls { "pldl1strm", B(0, 1, 1) },
346 1.1.1.1.8.2 tls { "pldl2keep", B(0, 2, 0) },
347 1.1.1.1.8.2 tls { "pldl2strm", B(0, 2, 1) },
348 1.1.1.1.8.2 tls { "pldl3keep", B(0, 3, 0) },
349 1.1.1.1.8.2 tls { "pldl3strm", B(0, 3, 1) },
350 1.1.1.1.8.2 tls { NULL, 0x06 },
351 1.1.1.1.8.2 tls { NULL, 0x07 },
352 1.1.1.1.8.2 tls { "plil1keep", B(1, 1, 0) },
353 1.1.1.1.8.2 tls { "plil1strm", B(1, 1, 1) },
354 1.1.1.1.8.2 tls { "plil2keep", B(1, 2, 0) },
355 1.1.1.1.8.2 tls { "plil2strm", B(1, 2, 1) },
356 1.1.1.1.8.2 tls { "plil3keep", B(1, 3, 0) },
357 1.1.1.1.8.2 tls { "plil3strm", B(1, 3, 1) },
358 1.1.1.1.8.2 tls { NULL, 0x0e },
359 1.1.1.1.8.2 tls { NULL, 0x0f },
360 1.1.1.1.8.2 tls { "pstl1keep", B(2, 1, 0) },
361 1.1.1.1.8.2 tls { "pstl1strm", B(2, 1, 1) },
362 1.1.1.1.8.2 tls { "pstl2keep", B(2, 2, 0) },
363 1.1.1.1.8.2 tls { "pstl2strm", B(2, 2, 1) },
364 1.1.1.1.8.2 tls { "pstl3keep", B(2, 3, 0) },
365 1.1.1.1.8.2 tls { "pstl3strm", B(2, 3, 1) },
366 1.1.1.1.8.2 tls { NULL, 0x16 },
367 1.1.1.1.8.2 tls { NULL, 0x17 },
368 1.1.1.1.8.2 tls { NULL, 0x18 },
369 1.1.1.1.8.2 tls { NULL, 0x19 },
370 1.1.1.1.8.2 tls { NULL, 0x1a },
371 1.1.1.1.8.2 tls { NULL, 0x1b },
372 1.1.1.1.8.2 tls { NULL, 0x1c },
373 1.1.1.1.8.2 tls { NULL, 0x1d },
374 1.1.1.1.8.2 tls { NULL, 0x1e },
375 1.1.1.1.8.2 tls { NULL, 0x1f },
376 1.1.1.1.8.2 tls };
377 1.1.1.1.8.2 tls #undef B
378 1.1.1.1.8.2 tls
379 1.1.1.1.8.2 tls /* Utilities on value constraint. */
381 1.1.1.1.8.2 tls
382 1.1.1.1.8.2 tls static inline int
383 1.1.1.1.8.2 tls value_in_range_p (int64_t value, int low, int high)
384 1.1.1.1.8.2 tls {
385 1.1.1.1.8.2 tls return (value >= low && value <= high) ? 1 : 0;
386 1.1.1.1.8.2 tls }
387 1.1.1.1.8.2 tls
388 1.1.1.1.8.2 tls static inline int
389 1.1.1.1.8.2 tls value_aligned_p (int64_t value, int align)
390 1.1.1.1.8.2 tls {
391 1.1.1.1.8.2 tls return ((value & (align - 1)) == 0) ? 1 : 0;
392 1.1.1.1.8.2 tls }
393 1.1.1.1.8.2 tls
394 1.1.1.1.8.2 tls /* A signed value fits in a field. */
395 1.1.1.1.8.2 tls static inline int
396 1.1.1.1.8.2 tls value_fit_signed_field_p (int64_t value, unsigned width)
397 1.1.1.1.8.2 tls {
398 1.1.1.1.8.2 tls assert (width < 32);
399 1.1.1.1.8.2 tls if (width < sizeof (value) * 8)
400 1.1.1.1.8.2 tls {
401 1.1.1.1.8.2 tls int64_t lim = (int64_t)1 << (width - 1);
402 1.1.1.1.8.2 tls if (value >= -lim && value < lim)
403 1.1.1.1.8.2 tls return 1;
404 1.1.1.1.8.2 tls }
405 1.1.1.1.8.2 tls return 0;
406 1.1.1.1.8.2 tls }
407 1.1.1.1.8.2 tls
408 1.1.1.1.8.2 tls /* An unsigned value fits in a field. */
409 1.1.1.1.8.2 tls static inline int
410 1.1.1.1.8.2 tls value_fit_unsigned_field_p (int64_t value, unsigned width)
411 1.1.1.1.8.2 tls {
412 1.1.1.1.8.2 tls assert (width < 32);
413 1.1.1.1.8.2 tls if (width < sizeof (value) * 8)
414 1.1.1.1.8.2 tls {
415 1.1.1.1.8.2 tls int64_t lim = (int64_t)1 << width;
416 1.1.1.1.8.2 tls if (value >= 0 && value < lim)
417 1.1.1.1.8.2 tls return 1;
418 1.1.1.1.8.2 tls }
419 1.1.1.1.8.2 tls return 0;
420 1.1.1.1.8.2 tls }
421 1.1.1.1.8.2 tls
422 1.1.1.1.8.2 tls /* Return 1 if OPERAND is SP or WSP. */
423 1.1.1.1.8.2 tls int
424 1.1.1.1.8.2 tls aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
425 1.1.1.1.8.2 tls {
426 1.1.1.1.8.2 tls return ((aarch64_get_operand_class (operand->type)
427 1.1.1.1.8.2 tls == AARCH64_OPND_CLASS_INT_REG)
428 1.1.1.1.8.2 tls && operand_maybe_stack_pointer (aarch64_operands + operand->type)
429 1.1.1.1.8.2 tls && operand->reg.regno == 31);
430 1.1.1.1.8.2 tls }
431 1.1.1.1.8.2 tls
432 1.1.1.1.8.2 tls /* Return 1 if OPERAND is XZR or WZP. */
433 1.1.1.1.8.2 tls int
434 1.1.1.1.8.2 tls aarch64_zero_register_p (const aarch64_opnd_info *operand)
435 1.1.1.1.8.2 tls {
436 1.1.1.1.8.2 tls return ((aarch64_get_operand_class (operand->type)
437 1.1.1.1.8.2 tls == AARCH64_OPND_CLASS_INT_REG)
438 1.1.1.1.8.2 tls && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
439 1.1.1.1.8.2 tls && operand->reg.regno == 31);
440 1.1.1.1.8.2 tls }
441 1.1.1.1.8.2 tls
442 1.1.1.1.8.2 tls /* Return true if the operand *OPERAND that has the operand code
443 1.1.1.1.8.2 tls OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
444 1.1.1.1.8.2 tls qualified by the qualifier TARGET. */
445 1.1.1.1.8.2 tls
446 1.1.1.1.8.2 tls static inline int
447 1.1.1.1.8.2 tls operand_also_qualified_p (const struct aarch64_opnd_info *operand,
448 1.1.1.1.8.2 tls aarch64_opnd_qualifier_t target)
449 1.1.1.1.8.2 tls {
450 1.1.1.1.8.2 tls switch (operand->qualifier)
451 1.1.1.1.8.2 tls {
452 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_W:
453 1.1.1.1.8.2 tls if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
454 1.1.1.1.8.2 tls return 1;
455 1.1.1.1.8.2 tls break;
456 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_X:
457 1.1.1.1.8.2 tls if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
458 1.1.1.1.8.2 tls return 1;
459 1.1.1.1.8.2 tls break;
460 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_WSP:
461 1.1.1.1.8.2 tls if (target == AARCH64_OPND_QLF_W
462 1.1.1.1.8.2 tls && operand_maybe_stack_pointer (aarch64_operands + operand->type))
463 1.1.1.1.8.2 tls return 1;
464 1.1.1.1.8.2 tls break;
465 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_SP:
466 1.1.1.1.8.2 tls if (target == AARCH64_OPND_QLF_X
467 1.1.1.1.8.2 tls && operand_maybe_stack_pointer (aarch64_operands + operand->type))
468 1.1.1.1.8.2 tls return 1;
469 1.1.1.1.8.2 tls break;
470 1.1.1.1.8.2 tls default:
471 1.1.1.1.8.2 tls break;
472 1.1.1.1.8.2 tls }
473 1.1.1.1.8.2 tls
474 1.1.1.1.8.2 tls return 0;
475 1.1.1.1.8.2 tls }
476 1.1.1.1.8.2 tls
477 1.1.1.1.8.2 tls /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
478 1.1.1.1.8.2 tls for operand KNOWN_IDX, return the expected qualifier for operand IDX.
479 1.1.1.1.8.2 tls
480 1.1.1.1.8.2 tls Return NIL if more than one expected qualifiers are found. */
481 1.1.1.1.8.2 tls
482 1.1.1.1.8.2 tls aarch64_opnd_qualifier_t
483 1.1.1.1.8.2 tls aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
484 1.1.1.1.8.2 tls int idx,
485 1.1.1.1.8.2 tls const aarch64_opnd_qualifier_t known_qlf,
486 1.1.1.1.8.2 tls int known_idx)
487 1.1.1.1.8.2 tls {
488 1.1.1.1.8.2 tls int i, saved_i;
489 1.1.1.1.8.2 tls
490 1.1.1.1.8.2 tls /* Special case.
491 1.1.1.1.8.2 tls
492 1.1.1.1.8.2 tls When the known qualifier is NIL, we have to assume that there is only
493 1.1.1.1.8.2 tls one qualifier sequence in the *QSEQ_LIST and return the corresponding
494 1.1.1.1.8.2 tls qualifier directly. One scenario is that for instruction
495 1.1.1.1.8.2 tls PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
496 1.1.1.1.8.2 tls which has only one possible valid qualifier sequence
497 1.1.1.1.8.2 tls NIL, S_D
498 1.1.1.1.8.2 tls the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
499 1.1.1.1.8.2 tls determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
500 1.1.1.1.8.2 tls
501 1.1.1.1.8.2 tls Because the qualifier NIL has dual roles in the qualifier sequence:
502 1.1.1.1.8.2 tls it can mean no qualifier for the operand, or the qualifer sequence is
503 1.1.1.1.8.2 tls not in use (when all qualifiers in the sequence are NILs), we have to
504 1.1.1.1.8.2 tls handle this special case here. */
505 1.1.1.1.8.2 tls if (known_qlf == AARCH64_OPND_NIL)
506 1.1.1.1.8.2 tls {
507 1.1.1.1.8.2 tls assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
508 1.1.1.1.8.2 tls return qseq_list[0][idx];
509 1.1.1.1.8.2 tls }
510 1.1.1.1.8.2 tls
511 1.1.1.1.8.2 tls for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
512 1.1.1.1.8.2 tls {
513 1.1.1.1.8.2 tls if (qseq_list[i][known_idx] == known_qlf)
514 1.1.1.1.8.2 tls {
515 1.1.1.1.8.2 tls if (saved_i != -1)
516 1.1.1.1.8.2 tls /* More than one sequences are found to have KNOWN_QLF at
517 1.1.1.1.8.2 tls KNOWN_IDX. */
518 1.1.1.1.8.2 tls return AARCH64_OPND_NIL;
519 1.1.1.1.8.2 tls saved_i = i;
520 1.1.1.1.8.2 tls }
521 1.1.1.1.8.2 tls }
522 1.1.1.1.8.2 tls
523 1.1.1.1.8.2 tls return qseq_list[saved_i][idx];
524 1.1.1.1.8.2 tls }
525 1.1.1.1.8.2 tls
526 1.1.1.1.8.2 tls enum operand_qualifier_kind
527 1.1.1.1.8.2 tls {
528 1.1.1.1.8.2 tls OQK_NIL,
529 1.1.1.1.8.2 tls OQK_OPD_VARIANT,
530 1.1.1.1.8.2 tls OQK_VALUE_IN_RANGE,
531 1.1.1.1.8.2 tls OQK_MISC,
532 1.1.1.1.8.2 tls };
533 1.1.1.1.8.2 tls
534 1.1.1.1.8.2 tls /* Operand qualifier description. */
535 1.1.1.1.8.2 tls struct operand_qualifier_data
536 1.1.1.1.8.2 tls {
537 1.1.1.1.8.2 tls /* The usage of the three data fields depends on the qualifier kind. */
538 1.1.1.1.8.2 tls int data0;
539 1.1.1.1.8.2 tls int data1;
540 1.1.1.1.8.2 tls int data2;
541 1.1.1.1.8.2 tls /* Description. */
542 1.1.1.1.8.2 tls const char *desc;
543 1.1.1.1.8.2 tls /* Kind. */
544 1.1.1.1.8.2 tls enum operand_qualifier_kind kind;
545 1.1.1.1.8.2 tls };
546 1.1.1.1.8.2 tls
547 1.1.1.1.8.2 tls /* Indexed by the operand qualifier enumerators. */
548 1.1.1.1.8.2 tls struct operand_qualifier_data aarch64_opnd_qualifiers[] =
549 1.1.1.1.8.2 tls {
550 1.1.1.1.8.2 tls {0, 0, 0, "NIL", OQK_NIL},
551 1.1.1.1.8.2 tls
552 1.1.1.1.8.2 tls /* Operand variant qualifiers.
553 1.1.1.1.8.2 tls First 3 fields:
554 1.1.1.1.8.2 tls element size, number of elements and common value for encoding. */
555 1.1.1.1.8.2 tls
556 1.1.1.1.8.2 tls {4, 1, 0x0, "w", OQK_OPD_VARIANT},
557 1.1.1.1.8.2 tls {8, 1, 0x1, "x", OQK_OPD_VARIANT},
558 1.1.1.1.8.2 tls {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
559 1.1.1.1.8.2 tls {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
560 1.1.1.1.8.2 tls
561 1.1.1.1.8.2 tls {1, 1, 0x0, "b", OQK_OPD_VARIANT},
562 1.1.1.1.8.2 tls {2, 1, 0x1, "h", OQK_OPD_VARIANT},
563 1.1.1.1.8.2 tls {4, 1, 0x2, "s", OQK_OPD_VARIANT},
564 1.1.1.1.8.2 tls {8, 1, 0x3, "d", OQK_OPD_VARIANT},
565 1.1.1.1.8.2 tls {16, 1, 0x4, "q", OQK_OPD_VARIANT},
566 1.1.1.1.8.2 tls
567 1.1.1.1.8.2 tls {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
568 1.1.1.1.8.2 tls {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
569 1.1.1.1.8.2 tls {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
570 1.1.1.1.8.2 tls {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
571 1.1.1.1.8.2 tls {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
572 1.1.1.1.8.2 tls {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
573 1.1.1.1.8.2 tls {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
574 1.1.1.1.8.2 tls {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
575 1.1.1.1.8.2 tls {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
576 1.1.1.1.8.2 tls
577 1.1.1.1.8.2 tls /* Qualifiers constraining the value range.
578 1.1.1.1.8.2 tls First 3 fields:
579 1.1.1.1.8.2 tls Lower bound, higher bound, unused. */
580 1.1.1.1.8.2 tls
581 1.1.1.1.8.2 tls {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
582 1.1.1.1.8.2 tls {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
583 1.1.1.1.8.2 tls {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
584 1.1.1.1.8.2 tls {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
585 1.1.1.1.8.2 tls {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
586 1.1.1.1.8.2 tls {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
587 1.1.1.1.8.2 tls
588 1.1.1.1.8.2 tls /* Qualifiers for miscellaneous purpose.
589 1.1.1.1.8.2 tls First 3 fields:
590 1.1.1.1.8.2 tls unused, unused and unused. */
591 1.1.1.1.8.2 tls
592 1.1.1.1.8.2 tls {0, 0, 0, "lsl", 0},
593 1.1.1.1.8.2 tls {0, 0, 0, "msl", 0},
594 1.1.1.1.8.2 tls
595 1.1.1.1.8.2 tls {0, 0, 0, "retrieving", 0},
596 1.1.1.1.8.2 tls };
597 1.1.1.1.8.2 tls
598 1.1.1.1.8.2 tls static inline bfd_boolean
599 1.1.1.1.8.2 tls operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
600 1.1.1.1.8.2 tls {
601 1.1.1.1.8.2 tls return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
602 1.1.1.1.8.2 tls ? TRUE : FALSE;
603 1.1.1.1.8.2 tls }
604 1.1.1.1.8.2 tls
605 1.1.1.1.8.2 tls static inline bfd_boolean
606 1.1.1.1.8.2 tls qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
607 1.1.1.1.8.2 tls {
608 1.1.1.1.8.2 tls return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
609 1.1.1.1.8.2 tls ? TRUE : FALSE;
610 1.1.1.1.8.2 tls }
611 1.1.1.1.8.2 tls
612 1.1.1.1.8.2 tls const char*
613 1.1.1.1.8.2 tls aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
614 1.1.1.1.8.2 tls {
615 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].desc;
616 1.1.1.1.8.2 tls }
617 1.1.1.1.8.2 tls
618 1.1.1.1.8.2 tls /* Given an operand qualifier, return the expected data element size
619 1.1.1.1.8.2 tls of a qualified operand. */
620 1.1.1.1.8.2 tls unsigned char
621 1.1.1.1.8.2 tls aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
622 1.1.1.1.8.2 tls {
623 1.1.1.1.8.2 tls assert (operand_variant_qualifier_p (qualifier) == TRUE);
624 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].data0;
625 1.1.1.1.8.2 tls }
626 1.1.1.1.8.2 tls
627 1.1.1.1.8.2 tls unsigned char
628 1.1.1.1.8.2 tls aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
629 1.1.1.1.8.2 tls {
630 1.1.1.1.8.2 tls assert (operand_variant_qualifier_p (qualifier) == TRUE);
631 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].data1;
632 1.1.1.1.8.2 tls }
633 1.1.1.1.8.2 tls
634 1.1.1.1.8.2 tls aarch64_insn
635 1.1.1.1.8.2 tls aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
636 1.1.1.1.8.2 tls {
637 1.1.1.1.8.2 tls assert (operand_variant_qualifier_p (qualifier) == TRUE);
638 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].data2;
639 1.1.1.1.8.2 tls }
640 1.1.1.1.8.2 tls
641 1.1.1.1.8.2 tls static int
642 1.1.1.1.8.2 tls get_lower_bound (aarch64_opnd_qualifier_t qualifier)
643 1.1.1.1.8.2 tls {
644 1.1.1.1.8.2 tls assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
645 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].data0;
646 1.1.1.1.8.2 tls }
647 1.1.1.1.8.2 tls
648 1.1.1.1.8.2 tls static int
649 1.1.1.1.8.2 tls get_upper_bound (aarch64_opnd_qualifier_t qualifier)
650 1.1.1.1.8.2 tls {
651 1.1.1.1.8.2 tls assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
652 1.1.1.1.8.2 tls return aarch64_opnd_qualifiers[qualifier].data1;
653 1.1.1.1.8.2 tls }
654 1.1.1.1.8.2 tls
655 1.1.1.1.8.2 tls #ifdef DEBUG_AARCH64
656 1.1.1.1.8.2 tls void
657 1.1.1.1.8.2 tls aarch64_verbose (const char *str, ...)
658 1.1.1.1.8.2 tls {
659 1.1.1.1.8.2 tls va_list ap;
660 1.1.1.1.8.2 tls va_start (ap, str);
661 1.1.1.1.8.2 tls printf ("#### ");
662 1.1.1.1.8.2 tls vprintf (str, ap);
663 1.1.1.1.8.2 tls printf ("\n");
664 1.1.1.1.8.2 tls va_end (ap);
665 1.1.1.1.8.2 tls }
666 1.1.1.1.8.2 tls
667 1.1.1.1.8.2 tls static inline void
668 1.1.1.1.8.2 tls dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
669 1.1.1.1.8.2 tls {
670 1.1.1.1.8.2 tls int i;
671 1.1.1.1.8.2 tls printf ("#### \t");
672 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
673 1.1.1.1.8.2 tls printf ("%s,", aarch64_get_qualifier_name (*qualifier));
674 1.1.1.1.8.2 tls printf ("\n");
675 1.1.1.1.8.2 tls }
676 1.1.1.1.8.2 tls
677 1.1.1.1.8.2 tls static void
678 1.1.1.1.8.2 tls dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
679 1.1.1.1.8.2 tls const aarch64_opnd_qualifier_t *qualifier)
680 1.1.1.1.8.2 tls {
681 1.1.1.1.8.2 tls int i;
682 1.1.1.1.8.2 tls aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
683 1.1.1.1.8.2 tls
684 1.1.1.1.8.2 tls aarch64_verbose ("dump_match_qualifiers:");
685 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
686 1.1.1.1.8.2 tls curr[i] = opnd[i].qualifier;
687 1.1.1.1.8.2 tls dump_qualifier_sequence (curr);
688 1.1.1.1.8.2 tls aarch64_verbose ("against");
689 1.1.1.1.8.2 tls dump_qualifier_sequence (qualifier);
690 1.1.1.1.8.2 tls }
691 1.1.1.1.8.2 tls #endif /* DEBUG_AARCH64 */
692 1.1.1.1.8.2 tls
693 1.1.1.1.8.2 tls /* TODO improve this, we can have an extra field at the runtime to
694 1.1.1.1.8.2 tls store the number of operands rather than calculating it every time. */
695 1.1.1.1.8.2 tls
696 1.1.1.1.8.2 tls int
697 1.1.1.1.8.2 tls aarch64_num_of_operands (const aarch64_opcode *opcode)
698 1.1.1.1.8.2 tls {
699 1.1.1.1.8.2 tls int i = 0;
700 1.1.1.1.8.2 tls const enum aarch64_opnd *opnds = opcode->operands;
701 1.1.1.1.8.2 tls while (opnds[i++] != AARCH64_OPND_NIL)
702 1.1.1.1.8.2 tls ;
703 1.1.1.1.8.2 tls --i;
704 1.1.1.1.8.2 tls assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
705 1.1.1.1.8.2 tls return i;
706 1.1.1.1.8.2 tls }
707 1.1.1.1.8.2 tls
708 1.1.1.1.8.2 tls /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
709 1.1.1.1.8.2 tls If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
710 1.1.1.1.8.2 tls
711 1.1.1.1.8.2 tls N.B. on the entry, it is very likely that only some operands in *INST
712 1.1.1.1.8.2 tls have had their qualifiers been established.
713 1.1.1.1.8.2 tls
714 1.1.1.1.8.2 tls If STOP_AT is not -1, the function will only try to match
715 1.1.1.1.8.2 tls the qualifier sequence for operands before and including the operand
716 1.1.1.1.8.2 tls of index STOP_AT; and on success *RET will only be filled with the first
717 1.1.1.1.8.2 tls (STOP_AT+1) qualifiers.
718 1.1.1.1.8.2 tls
719 1.1.1.1.8.2 tls A couple examples of the matching algorithm:
720 1.1.1.1.8.2 tls
721 1.1.1.1.8.2 tls X,W,NIL should match
722 1.1.1.1.8.2 tls X,W,NIL
723 1.1.1.1.8.2 tls
724 1.1.1.1.8.2 tls NIL,NIL should match
725 1.1.1.1.8.2 tls X ,NIL
726 1.1.1.1.8.2 tls
727 1.1.1.1.8.2 tls Apart from serving the main encoding routine, this can also be called
728 1.1.1.1.8.2 tls during or after the operand decoding. */
729 1.1.1.1.8.2 tls
730 1.1.1.1.8.2 tls int
731 1.1.1.1.8.2 tls aarch64_find_best_match (const aarch64_inst *inst,
732 1.1.1.1.8.2 tls const aarch64_opnd_qualifier_seq_t *qualifiers_list,
733 1.1.1.1.8.2 tls int stop_at, aarch64_opnd_qualifier_t *ret)
734 1.1.1.1.8.2 tls {
735 1.1.1.1.8.2 tls int found = 0;
736 1.1.1.1.8.2 tls int i, num_opnds;
737 1.1.1.1.8.2 tls const aarch64_opnd_qualifier_t *qualifiers;
738 1.1.1.1.8.2 tls
739 1.1.1.1.8.2 tls num_opnds = aarch64_num_of_operands (inst->opcode);
740 1.1.1.1.8.2 tls if (num_opnds == 0)
741 1.1.1.1.8.2 tls {
742 1.1.1.1.8.2 tls DEBUG_TRACE ("SUCCEED: no operand");
743 1.1.1.1.8.2 tls return 1;
744 1.1.1.1.8.2 tls }
745 1.1.1.1.8.2 tls
746 1.1.1.1.8.2 tls if (stop_at < 0 || stop_at >= num_opnds)
747 1.1.1.1.8.2 tls stop_at = num_opnds - 1;
748 1.1.1.1.8.2 tls
749 1.1.1.1.8.2 tls /* For each pattern. */
750 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
751 1.1.1.1.8.2 tls {
752 1.1.1.1.8.2 tls int j;
753 1.1.1.1.8.2 tls qualifiers = *qualifiers_list;
754 1.1.1.1.8.2 tls
755 1.1.1.1.8.2 tls /* Start as positive. */
756 1.1.1.1.8.2 tls found = 1;
757 1.1.1.1.8.2 tls
758 1.1.1.1.8.2 tls DEBUG_TRACE ("%d", i);
759 1.1.1.1.8.2 tls #ifdef DEBUG_AARCH64
760 1.1.1.1.8.2 tls if (debug_dump)
761 1.1.1.1.8.2 tls dump_match_qualifiers (inst->operands, qualifiers);
762 1.1.1.1.8.2 tls #endif
763 1.1.1.1.8.2 tls
764 1.1.1.1.8.2 tls /* Most opcodes has much fewer patterns in the list.
765 1.1.1.1.8.2 tls First NIL qualifier indicates the end in the list. */
766 1.1.1.1.8.2 tls if (empty_qualifier_sequence_p (qualifiers) == TRUE)
767 1.1.1.1.8.2 tls {
768 1.1.1.1.8.2 tls DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
769 1.1.1.1.8.2 tls if (i)
770 1.1.1.1.8.2 tls found = 0;
771 1.1.1.1.8.2 tls break;
772 1.1.1.1.8.2 tls }
773 1.1.1.1.8.2 tls
774 1.1.1.1.8.2 tls for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
775 1.1.1.1.8.2 tls {
776 1.1.1.1.8.2 tls if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
777 1.1.1.1.8.2 tls {
778 1.1.1.1.8.2 tls /* Either the operand does not have qualifier, or the qualifier
779 1.1.1.1.8.2 tls for the operand needs to be deduced from the qualifier
780 1.1.1.1.8.2 tls sequence.
781 1.1.1.1.8.2 tls In the latter case, any constraint checking related with
782 1.1.1.1.8.2 tls the obtained qualifier should be done later in
783 1.1.1.1.8.2 tls operand_general_constraint_met_p. */
784 1.1.1.1.8.2 tls continue;
785 1.1.1.1.8.2 tls }
786 1.1.1.1.8.2 tls else if (*qualifiers != inst->operands[j].qualifier)
787 1.1.1.1.8.2 tls {
788 1.1.1.1.8.2 tls /* Unless the target qualifier can also qualify the operand
789 1.1.1.1.8.2 tls (which has already had a non-nil qualifier), non-equal
790 1.1.1.1.8.2 tls qualifiers are generally un-matched. */
791 1.1.1.1.8.2 tls if (operand_also_qualified_p (inst->operands + j, *qualifiers))
792 1.1.1.1.8.2 tls continue;
793 1.1.1.1.8.2 tls else
794 1.1.1.1.8.2 tls {
795 1.1.1.1.8.2 tls found = 0;
796 1.1.1.1.8.2 tls break;
797 1.1.1.1.8.2 tls }
798 1.1.1.1.8.2 tls }
799 1.1.1.1.8.2 tls else
800 1.1.1.1.8.2 tls continue; /* Equal qualifiers are certainly matched. */
801 1.1.1.1.8.2 tls }
802 1.1.1.1.8.2 tls
803 1.1.1.1.8.2 tls /* Qualifiers established. */
804 1.1.1.1.8.2 tls if (found == 1)
805 1.1.1.1.8.2 tls break;
806 1.1.1.1.8.2 tls }
807 1.1.1.1.8.2 tls
808 1.1.1.1.8.2 tls if (found == 1)
809 1.1.1.1.8.2 tls {
810 1.1.1.1.8.2 tls /* Fill the result in *RET. */
811 1.1.1.1.8.2 tls int j;
812 1.1.1.1.8.2 tls qualifiers = *qualifiers_list;
813 1.1.1.1.8.2 tls
814 1.1.1.1.8.2 tls DEBUG_TRACE ("complete qualifiers using list %d", i);
815 1.1.1.1.8.2 tls #ifdef DEBUG_AARCH64
816 1.1.1.1.8.2 tls if (debug_dump)
817 1.1.1.1.8.2 tls dump_qualifier_sequence (qualifiers);
818 1.1.1.1.8.2 tls #endif
819 1.1.1.1.8.2 tls
820 1.1.1.1.8.2 tls for (j = 0; j <= stop_at; ++j, ++qualifiers)
821 1.1.1.1.8.2 tls ret[j] = *qualifiers;
822 1.1.1.1.8.2 tls for (; j < AARCH64_MAX_OPND_NUM; ++j)
823 1.1.1.1.8.2 tls ret[j] = AARCH64_OPND_QLF_NIL;
824 1.1.1.1.8.2 tls
825 1.1.1.1.8.2 tls DEBUG_TRACE ("SUCCESS");
826 1.1.1.1.8.2 tls return 1;
827 1.1.1.1.8.2 tls }
828 1.1.1.1.8.2 tls
829 1.1.1.1.8.2 tls DEBUG_TRACE ("FAIL");
830 1.1.1.1.8.2 tls return 0;
831 1.1.1.1.8.2 tls }
832 1.1.1.1.8.2 tls
833 1.1.1.1.8.2 tls /* Operand qualifier matching and resolving.
834 1.1.1.1.8.2 tls
835 1.1.1.1.8.2 tls Return 1 if the operand qualifier(s) in *INST match one of the qualifier
836 1.1.1.1.8.2 tls sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
837 1.1.1.1.8.2 tls
838 1.1.1.1.8.2 tls if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
839 1.1.1.1.8.2 tls succeeds. */
840 1.1.1.1.8.2 tls
841 1.1.1.1.8.2 tls static int
842 1.1.1.1.8.2 tls match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
843 1.1.1.1.8.2 tls {
844 1.1.1.1.8.2 tls int i;
845 1.1.1.1.8.2 tls aarch64_opnd_qualifier_seq_t qualifiers;
846 1.1.1.1.8.2 tls
847 1.1.1.1.8.2 tls if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
848 1.1.1.1.8.2 tls qualifiers))
849 1.1.1.1.8.2 tls {
850 1.1.1.1.8.2 tls DEBUG_TRACE ("matching FAIL");
851 1.1.1.1.8.2 tls return 0;
852 1.1.1.1.8.2 tls }
853 1.1.1.1.8.2 tls
854 1.1.1.1.8.2 tls /* Update the qualifiers. */
855 1.1.1.1.8.2 tls if (update_p == TRUE)
856 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
857 1.1.1.1.8.2 tls {
858 1.1.1.1.8.2 tls if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
859 1.1.1.1.8.2 tls break;
860 1.1.1.1.8.2 tls DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
861 1.1.1.1.8.2 tls "update %s with %s for operand %d",
862 1.1.1.1.8.2 tls aarch64_get_qualifier_name (inst->operands[i].qualifier),
863 1.1.1.1.8.2 tls aarch64_get_qualifier_name (qualifiers[i]), i);
864 1.1.1.1.8.2 tls inst->operands[i].qualifier = qualifiers[i];
865 1.1.1.1.8.2 tls }
866 1.1.1.1.8.2 tls
867 1.1.1.1.8.2 tls DEBUG_TRACE ("matching SUCCESS");
868 1.1.1.1.8.2 tls return 1;
869 1.1.1.1.8.2 tls }
870 1.1.1.1.8.2 tls
871 1.1.1.1.8.2 tls /* Return TRUE if VALUE is a wide constant that can be moved into a general
872 1.1.1.1.8.2 tls register by MOVZ.
873 1.1.1.1.8.2 tls
874 1.1.1.1.8.2 tls IS32 indicates whether value is a 32-bit immediate or not.
875 1.1.1.1.8.2 tls If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
876 1.1.1.1.8.2 tls amount will be returned in *SHIFT_AMOUNT. */
877 1.1.1.1.8.2 tls
878 1.1.1.1.8.2 tls bfd_boolean
879 1.1.1.1.8.2 tls aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
880 1.1.1.1.8.2 tls {
881 1.1.1.1.8.2 tls int amount;
882 1.1.1.1.8.2 tls
883 1.1.1.1.8.2 tls DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
884 1.1.1.1.8.2 tls
885 1.1.1.1.8.2 tls if (is32)
886 1.1.1.1.8.2 tls {
887 1.1.1.1.8.2 tls /* Allow all zeros or all ones in top 32-bits, so that
888 1.1.1.1.8.2 tls 32-bit constant expressions like ~0x80000000 are
889 1.1.1.1.8.2 tls permitted. */
890 1.1.1.1.8.2 tls uint64_t ext = value;
891 1.1.1.1.8.2 tls if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
892 1.1.1.1.8.2 tls /* Immediate out of range. */
893 1.1.1.1.8.2 tls return FALSE;
894 1.1.1.1.8.2 tls value &= (int64_t) 0xffffffff;
895 1.1.1.1.8.2 tls }
896 1.1.1.1.8.2 tls
897 1.1.1.1.8.2 tls /* first, try movz then movn */
898 1.1.1.1.8.2 tls amount = -1;
899 1.1.1.1.8.2 tls if ((value & ((int64_t) 0xffff << 0)) == value)
900 1.1.1.1.8.2 tls amount = 0;
901 1.1.1.1.8.2 tls else if ((value & ((int64_t) 0xffff << 16)) == value)
902 1.1.1.1.8.2 tls amount = 16;
903 1.1.1.1.8.2 tls else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
904 1.1.1.1.8.2 tls amount = 32;
905 1.1.1.1.8.2 tls else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
906 1.1.1.1.8.2 tls amount = 48;
907 1.1.1.1.8.2 tls
908 1.1.1.1.8.2 tls if (amount == -1)
909 1.1.1.1.8.2 tls {
910 1.1.1.1.8.2 tls DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
911 1.1.1.1.8.2 tls return FALSE;
912 1.1.1.1.8.2 tls }
913 1.1.1.1.8.2 tls
914 1.1.1.1.8.2 tls if (shift_amount != NULL)
915 1.1.1.1.8.2 tls *shift_amount = amount;
916 1.1.1.1.8.2 tls
917 1.1.1.1.8.2 tls DEBUG_TRACE ("exit TRUE with amount %d", amount);
918 1.1.1.1.8.2 tls
919 1.1.1.1.8.2 tls return TRUE;
920 1.1.1.1.8.2 tls }
921 1.1.1.1.8.2 tls
922 1.1.1.1.8.2 tls /* Build the accepted values for immediate logical SIMD instructions.
923 1.1.1.1.8.2 tls
924 1.1.1.1.8.2 tls The standard encodings of the immediate value are:
925 1.1.1.1.8.2 tls N imms immr SIMD size R S
926 1.1.1.1.8.2 tls 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
927 1.1.1.1.8.2 tls 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
928 1.1.1.1.8.2 tls 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
929 1.1.1.1.8.2 tls 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
930 1.1.1.1.8.2 tls 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
931 1.1.1.1.8.2 tls 0 11110s 00000r 2 UInt(r) UInt(s)
932 1.1.1.1.8.2 tls where all-ones value of S is reserved.
933 1.1.1.1.8.2 tls
934 1.1.1.1.8.2 tls Let's call E the SIMD size.
935 1.1.1.1.8.2 tls
936 1.1.1.1.8.2 tls The immediate value is: S+1 bits '1' rotated to the right by R.
937 1.1.1.1.8.2 tls
938 1.1.1.1.8.2 tls The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
939 1.1.1.1.8.2 tls (remember S != E - 1). */
940 1.1.1.1.8.2 tls
941 1.1.1.1.8.2 tls #define TOTAL_IMM_NB 5334
942 1.1.1.1.8.2 tls
943 1.1.1.1.8.2 tls typedef struct
944 1.1.1.1.8.2 tls {
945 1.1.1.1.8.2 tls uint64_t imm;
946 1.1.1.1.8.2 tls aarch64_insn encoding;
947 1.1.1.1.8.2 tls } simd_imm_encoding;
948 1.1.1.1.8.2 tls
949 1.1.1.1.8.2 tls static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
950 1.1.1.1.8.2 tls
951 1.1.1.1.8.2 tls static int
952 1.1.1.1.8.2 tls simd_imm_encoding_cmp(const void *i1, const void *i2)
953 1.1.1.1.8.2 tls {
954 1.1.1.1.8.2 tls const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
955 1.1.1.1.8.2 tls const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
956 1.1.1.1.8.2 tls
957 1.1.1.1.8.2 tls if (imm1->imm < imm2->imm)
958 1.1.1.1.8.2 tls return -1;
959 1.1.1.1.8.2 tls if (imm1->imm > imm2->imm)
960 1.1.1.1.8.2 tls return +1;
961 1.1.1.1.8.2 tls return 0;
962 1.1.1.1.8.2 tls }
963 1.1.1.1.8.2 tls
964 1.1.1.1.8.2 tls /* immediate bitfield standard encoding
965 1.1.1.1.8.2 tls imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
966 1.1.1.1.8.2 tls 1 ssssss rrrrrr 64 rrrrrr ssssss
967 1.1.1.1.8.2 tls 0 0sssss 0rrrrr 32 rrrrr sssss
968 1.1.1.1.8.2 tls 0 10ssss 00rrrr 16 rrrr ssss
969 1.1.1.1.8.2 tls 0 110sss 000rrr 8 rrr sss
970 1.1.1.1.8.2 tls 0 1110ss 0000rr 4 rr ss
971 1.1.1.1.8.2 tls 0 11110s 00000r 2 r s */
972 1.1.1.1.8.2 tls static inline int
973 1.1.1.1.8.2 tls encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
974 1.1.1.1.8.2 tls {
975 1.1.1.1.8.2 tls return (is64 << 12) | (r << 6) | s;
976 1.1.1.1.8.2 tls }
977 1.1.1.1.8.2 tls
978 1.1.1.1.8.2 tls static void
979 1.1.1.1.8.2 tls build_immediate_table (void)
980 1.1.1.1.8.2 tls {
981 1.1.1.1.8.2 tls uint32_t log_e, e, s, r, s_mask;
982 1.1.1.1.8.2 tls uint64_t mask, imm;
983 1.1.1.1.8.2 tls int nb_imms;
984 1.1.1.1.8.2 tls int is64;
985 1.1.1.1.8.2 tls
986 1.1.1.1.8.2 tls nb_imms = 0;
987 1.1.1.1.8.2 tls for (log_e = 1; log_e <= 6; log_e++)
988 1.1.1.1.8.2 tls {
989 1.1.1.1.8.2 tls /* Get element size. */
990 1.1.1.1.8.2 tls e = 1u << log_e;
991 1.1.1.1.8.2 tls if (log_e == 6)
992 1.1.1.1.8.2 tls {
993 1.1.1.1.8.2 tls is64 = 1;
994 1.1.1.1.8.2 tls mask = 0xffffffffffffffffull;
995 1.1.1.1.8.2 tls s_mask = 0;
996 1.1.1.1.8.2 tls }
997 1.1.1.1.8.2 tls else
998 1.1.1.1.8.2 tls {
999 1.1.1.1.8.2 tls is64 = 0;
1000 1.1.1.1.8.2 tls mask = (1ull << e) - 1;
1001 1.1.1.1.8.2 tls /* log_e s_mask
1002 1.1.1.1.8.2 tls 1 ((1 << 4) - 1) << 2 = 111100
1003 1.1.1.1.8.2 tls 2 ((1 << 3) - 1) << 3 = 111000
1004 1.1.1.1.8.2 tls 3 ((1 << 2) - 1) << 4 = 110000
1005 1.1.1.1.8.2 tls 4 ((1 << 1) - 1) << 5 = 100000
1006 1.1.1.1.8.2 tls 5 ((1 << 0) - 1) << 6 = 000000 */
1007 1.1.1.1.8.2 tls s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1008 1.1.1.1.8.2 tls }
1009 1.1.1.1.8.2 tls for (s = 0; s < e - 1; s++)
1010 1.1.1.1.8.2 tls for (r = 0; r < e; r++)
1011 1.1.1.1.8.2 tls {
1012 1.1.1.1.8.2 tls /* s+1 consecutive bits to 1 (s < 63) */
1013 1.1.1.1.8.2 tls imm = (1ull << (s + 1)) - 1;
1014 1.1.1.1.8.2 tls /* rotate right by r */
1015 1.1.1.1.8.2 tls if (r != 0)
1016 1.1.1.1.8.2 tls imm = (imm >> r) | ((imm << (e - r)) & mask);
1017 1.1.1.1.8.2 tls /* replicate the constant depending on SIMD size */
1018 1.1.1.1.8.2 tls switch (log_e)
1019 1.1.1.1.8.2 tls {
1020 1.1.1.1.8.2 tls case 1: imm = (imm << 2) | imm;
1021 1.1.1.1.8.2 tls case 2: imm = (imm << 4) | imm;
1022 1.1.1.1.8.2 tls case 3: imm = (imm << 8) | imm;
1023 1.1.1.1.8.2 tls case 4: imm = (imm << 16) | imm;
1024 1.1.1.1.8.2 tls case 5: imm = (imm << 32) | imm;
1025 1.1.1.1.8.2 tls case 6: break;
1026 1.1.1.1.8.2 tls default: abort ();
1027 1.1.1.1.8.2 tls }
1028 1.1.1.1.8.2 tls simd_immediates[nb_imms].imm = imm;
1029 1.1.1.1.8.2 tls simd_immediates[nb_imms].encoding =
1030 1.1.1.1.8.2 tls encode_immediate_bitfield(is64, s | s_mask, r);
1031 1.1.1.1.8.2 tls nb_imms++;
1032 1.1.1.1.8.2 tls }
1033 1.1.1.1.8.2 tls }
1034 1.1.1.1.8.2 tls assert (nb_imms == TOTAL_IMM_NB);
1035 1.1.1.1.8.2 tls qsort(simd_immediates, nb_imms,
1036 1.1.1.1.8.2 tls sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1037 1.1.1.1.8.2 tls }
1038 1.1.1.1.8.2 tls
1039 1.1.1.1.8.2 tls /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1040 1.1.1.1.8.2 tls be accepted by logical (immediate) instructions
1041 1.1.1.1.8.2 tls e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1042 1.1.1.1.8.2 tls
1043 1.1.1.1.8.2 tls IS32 indicates whether or not VALUE is a 32-bit immediate.
1044 1.1.1.1.8.2 tls If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1045 1.1.1.1.8.2 tls VALUE will be returned in *ENCODING. */
1046 1.1.1.1.8.2 tls
1047 1.1.1.1.8.2 tls bfd_boolean
1048 1.1.1.1.8.2 tls aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
1049 1.1.1.1.8.2 tls {
1050 1.1.1.1.8.2 tls simd_imm_encoding imm_enc;
1051 1.1.1.1.8.2 tls const simd_imm_encoding *imm_encoding;
1052 1.1.1.1.8.2 tls static bfd_boolean initialized = FALSE;
1053 1.1.1.1.8.2 tls
1054 1.1.1.1.8.2 tls DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
1055 1.1.1.1.8.2 tls value, is32);
1056 1.1.1.1.8.2 tls
1057 1.1.1.1.8.2 tls if (initialized == FALSE)
1058 1.1.1.1.8.2 tls {
1059 1.1.1.1.8.2 tls build_immediate_table ();
1060 1.1.1.1.8.2 tls initialized = TRUE;
1061 1.1.1.1.8.2 tls }
1062 1.1.1.1.8.2 tls
1063 1.1.1.1.8.2 tls if (is32)
1064 1.1.1.1.8.2 tls {
1065 1.1.1.1.8.2 tls /* Allow all zeros or all ones in top 32-bits, so that
1066 1.1.1.1.8.2 tls constant expressions like ~1 are permitted. */
1067 1.1.1.1.8.2 tls if (value >> 32 != 0 && value >> 32 != 0xffffffff)
1068 1.1.1.1.8.2 tls return 0xffffffff;
1069 1.1.1.1.8.2 tls /* Replicate the 32 lower bits to the 32 upper bits. */
1070 1.1.1.1.8.2 tls value &= 0xffffffff;
1071 1.1.1.1.8.2 tls value |= value << 32;
1072 1.1.1.1.8.2 tls }
1073 1.1.1.1.8.2 tls
1074 1.1.1.1.8.2 tls imm_enc.imm = value;
1075 1.1.1.1.8.2 tls imm_encoding = (const simd_imm_encoding *)
1076 1.1.1.1.8.2 tls bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1077 1.1.1.1.8.2 tls sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1078 1.1.1.1.8.2 tls if (imm_encoding == NULL)
1079 1.1.1.1.8.2 tls {
1080 1.1.1.1.8.2 tls DEBUG_TRACE ("exit with FALSE");
1081 1.1.1.1.8.2 tls return FALSE;
1082 1.1.1.1.8.2 tls }
1083 1.1.1.1.8.2 tls if (encoding != NULL)
1084 1.1.1.1.8.2 tls *encoding = imm_encoding->encoding;
1085 1.1.1.1.8.2 tls DEBUG_TRACE ("exit with TRUE");
1086 1.1.1.1.8.2 tls return TRUE;
1087 1.1.1.1.8.2 tls }
1088 1.1.1.1.8.2 tls
1089 1.1.1.1.8.2 tls /* If 64-bit immediate IMM is in the format of
1090 1.1.1.1.8.2 tls "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1091 1.1.1.1.8.2 tls where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1092 1.1.1.1.8.2 tls of value "abcdefgh". Otherwise return -1. */
1093 1.1.1.1.8.2 tls int
1094 1.1.1.1.8.2 tls aarch64_shrink_expanded_imm8 (uint64_t imm)
1095 1.1.1.1.8.2 tls {
1096 1.1.1.1.8.2 tls int i, ret;
1097 1.1.1.1.8.2 tls uint32_t byte;
1098 1.1.1.1.8.2 tls
1099 1.1.1.1.8.2 tls ret = 0;
1100 1.1.1.1.8.2 tls for (i = 0; i < 8; i++)
1101 1.1.1.1.8.2 tls {
1102 1.1.1.1.8.2 tls byte = (imm >> (8 * i)) & 0xff;
1103 1.1.1.1.8.2 tls if (byte == 0xff)
1104 1.1.1.1.8.2 tls ret |= 1 << i;
1105 1.1.1.1.8.2 tls else if (byte != 0x00)
1106 1.1.1.1.8.2 tls return -1;
1107 1.1.1.1.8.2 tls }
1108 1.1.1.1.8.2 tls return ret;
1109 1.1.1.1.8.2 tls }
1110 1.1.1.1.8.2 tls
1111 1.1.1.1.8.2 tls /* Utility inline functions for operand_general_constraint_met_p. */
1112 1.1.1.1.8.2 tls
1113 1.1.1.1.8.2 tls static inline void
1114 1.1.1.1.8.2 tls set_error (aarch64_operand_error *mismatch_detail,
1115 1.1.1.1.8.2 tls enum aarch64_operand_error_kind kind, int idx,
1116 1.1.1.1.8.2 tls const char* error)
1117 1.1.1.1.8.2 tls {
1118 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1119 1.1.1.1.8.2 tls return;
1120 1.1.1.1.8.2 tls mismatch_detail->kind = kind;
1121 1.1.1.1.8.2 tls mismatch_detail->index = idx;
1122 1.1.1.1.8.2 tls mismatch_detail->error = error;
1123 1.1.1.1.8.2 tls }
1124 1.1.1.1.8.2 tls
1125 1.1.1.1.8.2 tls static inline void
1126 1.1.1.1.8.2 tls set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1127 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound,
1128 1.1.1.1.8.2 tls const char* error)
1129 1.1.1.1.8.2 tls {
1130 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1131 1.1.1.1.8.2 tls return;
1132 1.1.1.1.8.2 tls set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1133 1.1.1.1.8.2 tls mismatch_detail->data[0] = lower_bound;
1134 1.1.1.1.8.2 tls mismatch_detail->data[1] = upper_bound;
1135 1.1.1.1.8.2 tls }
1136 1.1.1.1.8.2 tls
1137 1.1.1.1.8.2 tls static inline void
1138 1.1.1.1.8.2 tls set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1139 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound)
1140 1.1.1.1.8.2 tls {
1141 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1142 1.1.1.1.8.2 tls return;
1143 1.1.1.1.8.2 tls set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1144 1.1.1.1.8.2 tls _("immediate value"));
1145 1.1.1.1.8.2 tls }
1146 1.1.1.1.8.2 tls
1147 1.1.1.1.8.2 tls static inline void
1148 1.1.1.1.8.2 tls set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1149 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound)
1150 1.1.1.1.8.2 tls {
1151 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1152 1.1.1.1.8.2 tls return;
1153 1.1.1.1.8.2 tls set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1154 1.1.1.1.8.2 tls _("immediate offset"));
1155 1.1.1.1.8.2 tls }
1156 1.1.1.1.8.2 tls
1157 1.1.1.1.8.2 tls static inline void
1158 1.1.1.1.8.2 tls set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1159 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound)
1160 1.1.1.1.8.2 tls {
1161 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1162 1.1.1.1.8.2 tls return;
1163 1.1.1.1.8.2 tls set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1164 1.1.1.1.8.2 tls _("register number"));
1165 1.1.1.1.8.2 tls }
1166 1.1.1.1.8.2 tls
1167 1.1.1.1.8.2 tls static inline void
1168 1.1.1.1.8.2 tls set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1169 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound)
1170 1.1.1.1.8.2 tls {
1171 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1172 1.1.1.1.8.2 tls return;
1173 1.1.1.1.8.2 tls set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1174 1.1.1.1.8.2 tls _("register element index"));
1175 1.1.1.1.8.2 tls }
1176 1.1.1.1.8.2 tls
1177 1.1.1.1.8.2 tls static inline void
1178 1.1.1.1.8.2 tls set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1179 1.1.1.1.8.2 tls int idx, int lower_bound, int upper_bound)
1180 1.1.1.1.8.2 tls {
1181 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1182 1.1.1.1.8.2 tls return;
1183 1.1.1.1.8.2 tls set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1184 1.1.1.1.8.2 tls _("shift amount"));
1185 1.1.1.1.8.2 tls }
1186 1.1.1.1.8.2 tls
1187 1.1.1.1.8.2 tls static inline void
1188 1.1.1.1.8.2 tls set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1189 1.1.1.1.8.2 tls int alignment)
1190 1.1.1.1.8.2 tls {
1191 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1192 1.1.1.1.8.2 tls return;
1193 1.1.1.1.8.2 tls set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1194 1.1.1.1.8.2 tls mismatch_detail->data[0] = alignment;
1195 1.1.1.1.8.2 tls }
1196 1.1.1.1.8.2 tls
1197 1.1.1.1.8.2 tls static inline void
1198 1.1.1.1.8.2 tls set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1199 1.1.1.1.8.2 tls int expected_num)
1200 1.1.1.1.8.2 tls {
1201 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1202 1.1.1.1.8.2 tls return;
1203 1.1.1.1.8.2 tls set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1204 1.1.1.1.8.2 tls mismatch_detail->data[0] = expected_num;
1205 1.1.1.1.8.2 tls }
1206 1.1.1.1.8.2 tls
1207 1.1.1.1.8.2 tls static inline void
1208 1.1.1.1.8.2 tls set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1209 1.1.1.1.8.2 tls const char* error)
1210 1.1.1.1.8.2 tls {
1211 1.1.1.1.8.2 tls if (mismatch_detail == NULL)
1212 1.1.1.1.8.2 tls return;
1213 1.1.1.1.8.2 tls set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1214 1.1.1.1.8.2 tls }
1215 1.1.1.1.8.2 tls
1216 1.1.1.1.8.2 tls /* General constraint checking based on operand code.
1217 1.1.1.1.8.2 tls
1218 1.1.1.1.8.2 tls Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1219 1.1.1.1.8.2 tls as the IDXth operand of opcode OPCODE. Otherwise return 0.
1220 1.1.1.1.8.2 tls
1221 1.1.1.1.8.2 tls This function has to be called after the qualifiers for all operands
1222 1.1.1.1.8.2 tls have been resolved.
1223 1.1.1.1.8.2 tls
1224 1.1.1.1.8.2 tls Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1225 1.1.1.1.8.2 tls i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1226 1.1.1.1.8.2 tls of error message during the disassembling where error message is not
1227 1.1.1.1.8.2 tls wanted. We avoid the dynamic construction of strings of error messages
1228 1.1.1.1.8.2 tls here (i.e. in libopcodes), as it is costly and complicated; instead, we
1229 1.1.1.1.8.2 tls use a combination of error code, static string and some integer data to
1230 1.1.1.1.8.2 tls represent an error. */
1231 1.1.1.1.8.2 tls
1232 1.1.1.1.8.2 tls static int
1233 1.1.1.1.8.2 tls operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1234 1.1.1.1.8.2 tls enum aarch64_opnd type,
1235 1.1.1.1.8.2 tls const aarch64_opcode *opcode,
1236 1.1.1.1.8.2 tls aarch64_operand_error *mismatch_detail)
1237 1.1.1.1.8.2 tls {
1238 1.1.1.1.8.2 tls unsigned num;
1239 1.1.1.1.8.2 tls unsigned char size;
1240 1.1.1.1.8.2 tls int64_t imm;
1241 1.1.1.1.8.2 tls const aarch64_opnd_info *opnd = opnds + idx;
1242 1.1.1.1.8.2 tls aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1243 1.1.1.1.8.2 tls
1244 1.1.1.1.8.2 tls assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1245 1.1.1.1.8.2 tls
1246 1.1.1.1.8.2 tls switch (aarch64_operands[type].op_class)
1247 1.1.1.1.8.2 tls {
1248 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_INT_REG:
1249 1.1.1.1.8.2 tls /* <Xt> may be optional in some IC and TLBI instructions. */
1250 1.1.1.1.8.2 tls if (type == AARCH64_OPND_Rt_SYS)
1251 1.1.1.1.8.2 tls {
1252 1.1.1.1.8.2 tls assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1253 1.1.1.1.8.2 tls == AARCH64_OPND_CLASS_SYSTEM));
1254 1.1.1.1.8.2 tls if (opnds[1].present && !opnds[0].sysins_op->has_xt)
1255 1.1.1.1.8.2 tls {
1256 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx, _("extraneous register"));
1257 1.1.1.1.8.2 tls return 0;
1258 1.1.1.1.8.2 tls }
1259 1.1.1.1.8.2 tls if (!opnds[1].present && opnds[0].sysins_op->has_xt)
1260 1.1.1.1.8.2 tls {
1261 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx, _("missing register"));
1262 1.1.1.1.8.2 tls return 0;
1263 1.1.1.1.8.2 tls }
1264 1.1.1.1.8.2 tls }
1265 1.1.1.1.8.2 tls switch (qualifier)
1266 1.1.1.1.8.2 tls {
1267 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_WSP:
1268 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_SP:
1269 1.1.1.1.8.2 tls if (!aarch64_stack_pointer_p (opnd))
1270 1.1.1.1.8.2 tls {
1271 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1272 1.1.1.1.8.2 tls _("stack pointer register expected"));
1273 1.1.1.1.8.2 tls return 0;
1274 1.1.1.1.8.2 tls }
1275 1.1.1.1.8.2 tls break;
1276 1.1.1.1.8.2 tls default:
1277 1.1.1.1.8.2 tls break;
1278 1.1.1.1.8.2 tls }
1279 1.1.1.1.8.2 tls break;
1280 1.1.1.1.8.2 tls
1281 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_ADDRESS:
1282 1.1.1.1.8.2 tls /* Check writeback. */
1283 1.1.1.1.8.2 tls switch (opcode->iclass)
1284 1.1.1.1.8.2 tls {
1285 1.1.1.1.8.2 tls case ldst_pos:
1286 1.1.1.1.8.2 tls case ldst_unscaled:
1287 1.1.1.1.8.2 tls case ldstnapair_offs:
1288 1.1.1.1.8.2 tls case ldstpair_off:
1289 1.1.1.1.8.2 tls case ldst_unpriv:
1290 1.1.1.1.8.2 tls if (opnd->addr.writeback == 1)
1291 1.1.1.1.8.2 tls {
1292 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1293 1.1.1.1.8.2 tls _("unexpected address writeback"));
1294 1.1.1.1.8.2 tls return 0;
1295 1.1.1.1.8.2 tls }
1296 1.1.1.1.8.2 tls break;
1297 1.1.1.1.8.2 tls case ldst_imm9:
1298 1.1.1.1.8.2 tls case ldstpair_indexed:
1299 1.1.1.1.8.2 tls case asisdlsep:
1300 1.1.1.1.8.2 tls case asisdlsop:
1301 1.1.1.1.8.2 tls if (opnd->addr.writeback == 0)
1302 1.1.1.1.8.2 tls {
1303 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1304 1.1.1.1.8.2 tls _("address writeback expected"));
1305 1.1.1.1.8.2 tls return 0;
1306 1.1.1.1.8.2 tls }
1307 1.1.1.1.8.2 tls break;
1308 1.1.1.1.8.2 tls default:
1309 1.1.1.1.8.2 tls assert (opnd->addr.writeback == 0);
1310 1.1.1.1.8.2 tls break;
1311 1.1.1.1.8.2 tls }
1312 1.1.1.1.8.2 tls switch (type)
1313 1.1.1.1.8.2 tls {
1314 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM7:
1315 1.1.1.1.8.2 tls /* Scaled signed 7 bits immediate offset. */
1316 1.1.1.1.8.2 tls /* Get the size of the data element that is accessed, which may be
1317 1.1.1.1.8.2 tls different from that of the source register size,
1318 1.1.1.1.8.2 tls e.g. in strb/ldrb. */
1319 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (opnd->qualifier);
1320 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1321 1.1.1.1.8.2 tls {
1322 1.1.1.1.8.2 tls set_offset_out_of_range_error (mismatch_detail, idx,
1323 1.1.1.1.8.2 tls -64 * size, 63 * size);
1324 1.1.1.1.8.2 tls return 0;
1325 1.1.1.1.8.2 tls }
1326 1.1.1.1.8.2 tls if (!value_aligned_p (opnd->addr.offset.imm, size))
1327 1.1.1.1.8.2 tls {
1328 1.1.1.1.8.2 tls set_unaligned_error (mismatch_detail, idx, size);
1329 1.1.1.1.8.2 tls return 0;
1330 1.1.1.1.8.2 tls }
1331 1.1.1.1.8.2 tls break;
1332 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM9:
1333 1.1.1.1.8.2 tls /* Unscaled signed 9 bits immediate offset. */
1334 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1335 1.1.1.1.8.2 tls {
1336 1.1.1.1.8.2 tls set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1337 1.1.1.1.8.2 tls return 0;
1338 1.1.1.1.8.2 tls }
1339 1.1.1.1.8.2 tls break;
1340 1.1.1.1.8.2 tls
1341 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM9_2:
1342 1.1.1.1.8.2 tls /* Unscaled signed 9 bits immediate offset, which has to be negative
1343 1.1.1.1.8.2 tls or unaligned. */
1344 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (qualifier);
1345 1.1.1.1.8.2 tls if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1346 1.1.1.1.8.2 tls && !value_aligned_p (opnd->addr.offset.imm, size))
1347 1.1.1.1.8.2 tls || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1348 1.1.1.1.8.2 tls return 1;
1349 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1350 1.1.1.1.8.2 tls _("negative or unaligned offset expected"));
1351 1.1.1.1.8.2 tls return 0;
1352 1.1.1.1.8.2 tls
1353 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_ADDR_POST:
1354 1.1.1.1.8.2 tls /* AdvSIMD load/store multiple structures, post-index. */
1355 1.1.1.1.8.2 tls assert (idx == 1);
1356 1.1.1.1.8.2 tls if (opnd->addr.offset.is_reg)
1357 1.1.1.1.8.2 tls {
1358 1.1.1.1.8.2 tls if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1359 1.1.1.1.8.2 tls return 1;
1360 1.1.1.1.8.2 tls else
1361 1.1.1.1.8.2 tls {
1362 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1363 1.1.1.1.8.2 tls _("invalid register offset"));
1364 1.1.1.1.8.2 tls return 0;
1365 1.1.1.1.8.2 tls }
1366 1.1.1.1.8.2 tls }
1367 1.1.1.1.8.2 tls else
1368 1.1.1.1.8.2 tls {
1369 1.1.1.1.8.2 tls const aarch64_opnd_info *prev = &opnds[idx-1];
1370 1.1.1.1.8.2 tls unsigned num_bytes; /* total number of bytes transferred. */
1371 1.1.1.1.8.2 tls /* The opcode dependent area stores the number of elements in
1372 1.1.1.1.8.2 tls each structure to be loaded/stored. */
1373 1.1.1.1.8.2 tls int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1374 1.1.1.1.8.2 tls if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1375 1.1.1.1.8.2 tls /* Special handling of loading single structure to all lane. */
1376 1.1.1.1.8.2 tls num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1377 1.1.1.1.8.2 tls * aarch64_get_qualifier_esize (prev->qualifier);
1378 1.1.1.1.8.2 tls else
1379 1.1.1.1.8.2 tls num_bytes = prev->reglist.num_regs
1380 1.1.1.1.8.2 tls * aarch64_get_qualifier_esize (prev->qualifier)
1381 1.1.1.1.8.2 tls * aarch64_get_qualifier_nelem (prev->qualifier);
1382 1.1.1.1.8.2 tls if ((int) num_bytes != opnd->addr.offset.imm)
1383 1.1.1.1.8.2 tls {
1384 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1385 1.1.1.1.8.2 tls _("invalid post-increment amount"));
1386 1.1.1.1.8.2 tls return 0;
1387 1.1.1.1.8.2 tls }
1388 1.1.1.1.8.2 tls }
1389 1.1.1.1.8.2 tls break;
1390 1.1.1.1.8.2 tls
1391 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_REGOFF:
1392 1.1.1.1.8.2 tls /* Get the size of the data element that is accessed, which may be
1393 1.1.1.1.8.2 tls different from that of the source register size,
1394 1.1.1.1.8.2 tls e.g. in strb/ldrb. */
1395 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (opnd->qualifier);
1396 1.1.1.1.8.2 tls /* It is either no shift or shift by the binary logarithm of SIZE. */
1397 1.1.1.1.8.2 tls if (opnd->shifter.amount != 0
1398 1.1.1.1.8.2 tls && opnd->shifter.amount != (int)get_logsz (size))
1399 1.1.1.1.8.2 tls {
1400 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1401 1.1.1.1.8.2 tls _("invalid shift amount"));
1402 1.1.1.1.8.2 tls return 0;
1403 1.1.1.1.8.2 tls }
1404 1.1.1.1.8.2 tls /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1405 1.1.1.1.8.2 tls operators. */
1406 1.1.1.1.8.2 tls switch (opnd->shifter.kind)
1407 1.1.1.1.8.2 tls {
1408 1.1.1.1.8.2 tls case AARCH64_MOD_UXTW:
1409 1.1.1.1.8.2 tls case AARCH64_MOD_LSL:
1410 1.1.1.1.8.2 tls case AARCH64_MOD_SXTW:
1411 1.1.1.1.8.2 tls case AARCH64_MOD_SXTX: break;
1412 1.1.1.1.8.2 tls default:
1413 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1414 1.1.1.1.8.2 tls _("invalid extend/shift operator"));
1415 1.1.1.1.8.2 tls return 0;
1416 1.1.1.1.8.2 tls }
1417 1.1.1.1.8.2 tls break;
1418 1.1.1.1.8.2 tls
1419 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_UIMM12:
1420 1.1.1.1.8.2 tls imm = opnd->addr.offset.imm;
1421 1.1.1.1.8.2 tls /* Get the size of the data element that is accessed, which may be
1422 1.1.1.1.8.2 tls different from that of the source register size,
1423 1.1.1.1.8.2 tls e.g. in strb/ldrb. */
1424 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (qualifier);
1425 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1426 1.1.1.1.8.2 tls {
1427 1.1.1.1.8.2 tls set_offset_out_of_range_error (mismatch_detail, idx,
1428 1.1.1.1.8.2 tls 0, 4095 * size);
1429 1.1.1.1.8.2 tls return 0;
1430 1.1.1.1.8.2 tls }
1431 1.1.1.1.8.2 tls if (!value_aligned_p (opnd->addr.offset.imm, size))
1432 1.1.1.1.8.2 tls {
1433 1.1.1.1.8.2 tls set_unaligned_error (mismatch_detail, idx, size);
1434 1.1.1.1.8.2 tls return 0;
1435 1.1.1.1.8.2 tls }
1436 1.1.1.1.8.2 tls break;
1437 1.1.1.1.8.2 tls
1438 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL14:
1439 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL19:
1440 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL21:
1441 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL26:
1442 1.1.1.1.8.2 tls imm = opnd->imm.value;
1443 1.1.1.1.8.2 tls if (operand_need_shift_by_two (get_operand_from_code (type)))
1444 1.1.1.1.8.2 tls {
1445 1.1.1.1.8.2 tls /* The offset value in a PC-relative branch instruction is alway
1446 1.1.1.1.8.2 tls 4-byte aligned and is encoded without the lowest 2 bits. */
1447 1.1.1.1.8.2 tls if (!value_aligned_p (imm, 4))
1448 1.1.1.1.8.2 tls {
1449 1.1.1.1.8.2 tls set_unaligned_error (mismatch_detail, idx, 4);
1450 1.1.1.1.8.2 tls return 0;
1451 1.1.1.1.8.2 tls }
1452 1.1.1.1.8.2 tls /* Right shift by 2 so that we can carry out the following check
1453 1.1.1.1.8.2 tls canonically. */
1454 1.1.1.1.8.2 tls imm >>= 2;
1455 1.1.1.1.8.2 tls }
1456 1.1.1.1.8.2 tls size = get_operand_fields_width (get_operand_from_code (type));
1457 1.1.1.1.8.2 tls if (!value_fit_signed_field_p (imm, size))
1458 1.1.1.1.8.2 tls {
1459 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1460 1.1.1.1.8.2 tls _("immediate out of range"));
1461 1.1.1.1.8.2 tls return 0;
1462 1.1.1.1.8.2 tls }
1463 1.1.1.1.8.2 tls break;
1464 1.1.1.1.8.2 tls
1465 1.1.1.1.8.2 tls default:
1466 1.1.1.1.8.2 tls break;
1467 1.1.1.1.8.2 tls }
1468 1.1.1.1.8.2 tls break;
1469 1.1.1.1.8.2 tls
1470 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_SIMD_REGLIST:
1471 1.1.1.1.8.2 tls /* The opcode dependent area stores the number of elements in
1472 1.1.1.1.8.2 tls each structure to be loaded/stored. */
1473 1.1.1.1.8.2 tls num = get_opcode_dependent_value (opcode);
1474 1.1.1.1.8.2 tls switch (type)
1475 1.1.1.1.8.2 tls {
1476 1.1.1.1.8.2 tls case AARCH64_OPND_LVt:
1477 1.1.1.1.8.2 tls assert (num >= 1 && num <= 4);
1478 1.1.1.1.8.2 tls /* Unless LD1/ST1, the number of registers should be equal to that
1479 1.1.1.1.8.2 tls of the structure elements. */
1480 1.1.1.1.8.2 tls if (num != 1 && opnd->reglist.num_regs != num)
1481 1.1.1.1.8.2 tls {
1482 1.1.1.1.8.2 tls set_reg_list_error (mismatch_detail, idx, num);
1483 1.1.1.1.8.2 tls return 0;
1484 1.1.1.1.8.2 tls }
1485 1.1.1.1.8.2 tls break;
1486 1.1.1.1.8.2 tls case AARCH64_OPND_LVt_AL:
1487 1.1.1.1.8.2 tls case AARCH64_OPND_LEt:
1488 1.1.1.1.8.2 tls assert (num >= 1 && num <= 4);
1489 1.1.1.1.8.2 tls /* The number of registers should be equal to that of the structure
1490 1.1.1.1.8.2 tls elements. */
1491 1.1.1.1.8.2 tls if (opnd->reglist.num_regs != num)
1492 1.1.1.1.8.2 tls {
1493 1.1.1.1.8.2 tls set_reg_list_error (mismatch_detail, idx, num);
1494 1.1.1.1.8.2 tls return 0;
1495 1.1.1.1.8.2 tls }
1496 1.1.1.1.8.2 tls break;
1497 1.1.1.1.8.2 tls default:
1498 1.1.1.1.8.2 tls break;
1499 1.1.1.1.8.2 tls }
1500 1.1.1.1.8.2 tls break;
1501 1.1.1.1.8.2 tls
1502 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_IMMEDIATE:
1503 1.1.1.1.8.2 tls /* Constraint check on immediate operand. */
1504 1.1.1.1.8.2 tls imm = opnd->imm.value;
1505 1.1.1.1.8.2 tls /* E.g. imm_0_31 constrains value to be 0..31. */
1506 1.1.1.1.8.2 tls if (qualifier_value_in_range_constraint_p (qualifier)
1507 1.1.1.1.8.2 tls && !value_in_range_p (imm, get_lower_bound (qualifier),
1508 1.1.1.1.8.2 tls get_upper_bound (qualifier)))
1509 1.1.1.1.8.2 tls {
1510 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx,
1511 1.1.1.1.8.2 tls get_lower_bound (qualifier),
1512 1.1.1.1.8.2 tls get_upper_bound (qualifier));
1513 1.1.1.1.8.2 tls return 0;
1514 1.1.1.1.8.2 tls }
1515 1.1.1.1.8.2 tls
1516 1.1.1.1.8.2 tls switch (type)
1517 1.1.1.1.8.2 tls {
1518 1.1.1.1.8.2 tls case AARCH64_OPND_AIMM:
1519 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_LSL)
1520 1.1.1.1.8.2 tls {
1521 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1522 1.1.1.1.8.2 tls _("invalid shift operator"));
1523 1.1.1.1.8.2 tls return 0;
1524 1.1.1.1.8.2 tls }
1525 1.1.1.1.8.2 tls if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
1526 1.1.1.1.8.2 tls {
1527 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1528 1.1.1.1.8.2 tls _("shift amount expected to be 0 or 12"));
1529 1.1.1.1.8.2 tls return 0;
1530 1.1.1.1.8.2 tls }
1531 1.1.1.1.8.2 tls if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
1532 1.1.1.1.8.2 tls {
1533 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1534 1.1.1.1.8.2 tls _("immediate out of range"));
1535 1.1.1.1.8.2 tls return 0;
1536 1.1.1.1.8.2 tls }
1537 1.1.1.1.8.2 tls break;
1538 1.1.1.1.8.2 tls
1539 1.1.1.1.8.2 tls case AARCH64_OPND_HALF:
1540 1.1.1.1.8.2 tls assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
1541 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_LSL)
1542 1.1.1.1.8.2 tls {
1543 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1544 1.1.1.1.8.2 tls _("invalid shift operator"));
1545 1.1.1.1.8.2 tls return 0;
1546 1.1.1.1.8.2 tls }
1547 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1548 1.1.1.1.8.2 tls if (!value_aligned_p (opnd->shifter.amount, 16))
1549 1.1.1.1.8.2 tls {
1550 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1551 1.1.1.1.8.2 tls _("shift amount should be a multiple of 16"));
1552 1.1.1.1.8.2 tls return 0;
1553 1.1.1.1.8.2 tls }
1554 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
1555 1.1.1.1.8.2 tls {
1556 1.1.1.1.8.2 tls set_sft_amount_out_of_range_error (mismatch_detail, idx,
1557 1.1.1.1.8.2 tls 0, size * 8 - 16);
1558 1.1.1.1.8.2 tls return 0;
1559 1.1.1.1.8.2 tls }
1560 1.1.1.1.8.2 tls if (opnd->imm.value < 0)
1561 1.1.1.1.8.2 tls {
1562 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1563 1.1.1.1.8.2 tls _("negative immediate value not allowed"));
1564 1.1.1.1.8.2 tls return 0;
1565 1.1.1.1.8.2 tls }
1566 1.1.1.1.8.2 tls if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
1567 1.1.1.1.8.2 tls {
1568 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1569 1.1.1.1.8.2 tls _("immediate out of range"));
1570 1.1.1.1.8.2 tls return 0;
1571 1.1.1.1.8.2 tls }
1572 1.1.1.1.8.2 tls break;
1573 1.1.1.1.8.2 tls
1574 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_MOV:
1575 1.1.1.1.8.2 tls {
1576 1.1.1.1.8.2 tls int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
1577 1.1.1.1.8.2 tls imm = opnd->imm.value;
1578 1.1.1.1.8.2 tls assert (idx == 1);
1579 1.1.1.1.8.2 tls switch (opcode->op)
1580 1.1.1.1.8.2 tls {
1581 1.1.1.1.8.2 tls case OP_MOV_IMM_WIDEN:
1582 1.1.1.1.8.2 tls imm = ~imm;
1583 1.1.1.1.8.2 tls /* Fall through... */
1584 1.1.1.1.8.2 tls case OP_MOV_IMM_WIDE:
1585 1.1.1.1.8.2 tls if (!aarch64_wide_constant_p (imm, is32, NULL))
1586 1.1.1.1.8.2 tls {
1587 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1588 1.1.1.1.8.2 tls _("immediate out of range"));
1589 1.1.1.1.8.2 tls return 0;
1590 1.1.1.1.8.2 tls }
1591 1.1.1.1.8.2 tls break;
1592 1.1.1.1.8.2 tls case OP_MOV_IMM_LOG:
1593 1.1.1.1.8.2 tls if (!aarch64_logical_immediate_p (imm, is32, NULL))
1594 1.1.1.1.8.2 tls {
1595 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1596 1.1.1.1.8.2 tls _("immediate out of range"));
1597 1.1.1.1.8.2 tls return 0;
1598 1.1.1.1.8.2 tls }
1599 1.1.1.1.8.2 tls break;
1600 1.1.1.1.8.2 tls default:
1601 1.1.1.1.8.2 tls assert (0);
1602 1.1.1.1.8.2 tls return 0;
1603 1.1.1.1.8.2 tls }
1604 1.1.1.1.8.2 tls }
1605 1.1.1.1.8.2 tls break;
1606 1.1.1.1.8.2 tls
1607 1.1.1.1.8.2 tls case AARCH64_OPND_NZCV:
1608 1.1.1.1.8.2 tls case AARCH64_OPND_CCMP_IMM:
1609 1.1.1.1.8.2 tls case AARCH64_OPND_EXCEPTION:
1610 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM4:
1611 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM7:
1612 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM3_OP1:
1613 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM3_OP2:
1614 1.1.1.1.8.2 tls size = get_operand_fields_width (get_operand_from_code (type));
1615 1.1.1.1.8.2 tls assert (size < 32);
1616 1.1.1.1.8.2 tls if (!value_fit_unsigned_field_p (opnd->imm.value, size))
1617 1.1.1.1.8.2 tls {
1618 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 0,
1619 1.1.1.1.8.2 tls (1 << size) - 1);
1620 1.1.1.1.8.2 tls return 0;
1621 1.1.1.1.8.2 tls }
1622 1.1.1.1.8.2 tls break;
1623 1.1.1.1.8.2 tls
1624 1.1.1.1.8.2 tls case AARCH64_OPND_WIDTH:
1625 1.1.1.1.8.2 tls assert (idx == 3 && opnds[idx-1].type == AARCH64_OPND_IMM
1626 1.1.1.1.8.2 tls && opnds[0].type == AARCH64_OPND_Rd);
1627 1.1.1.1.8.2 tls size = get_upper_bound (qualifier);
1628 1.1.1.1.8.2 tls if (opnd->imm.value + opnds[idx-1].imm.value > size)
1629 1.1.1.1.8.2 tls /* lsb+width <= reg.size */
1630 1.1.1.1.8.2 tls {
1631 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 1,
1632 1.1.1.1.8.2 tls size - opnds[idx-1].imm.value);
1633 1.1.1.1.8.2 tls return 0;
1634 1.1.1.1.8.2 tls }
1635 1.1.1.1.8.2 tls break;
1636 1.1.1.1.8.2 tls
1637 1.1.1.1.8.2 tls case AARCH64_OPND_LIMM:
1638 1.1.1.1.8.2 tls {
1639 1.1.1.1.8.2 tls int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
1640 1.1.1.1.8.2 tls uint64_t uimm = opnd->imm.value;
1641 1.1.1.1.8.2 tls if (opcode->op == OP_BIC)
1642 1.1.1.1.8.2 tls uimm = ~uimm;
1643 1.1.1.1.8.2 tls if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
1644 1.1.1.1.8.2 tls {
1645 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1646 1.1.1.1.8.2 tls _("immediate out of range"));
1647 1.1.1.1.8.2 tls return 0;
1648 1.1.1.1.8.2 tls }
1649 1.1.1.1.8.2 tls }
1650 1.1.1.1.8.2 tls break;
1651 1.1.1.1.8.2 tls
1652 1.1.1.1.8.2 tls case AARCH64_OPND_IMM0:
1653 1.1.1.1.8.2 tls case AARCH64_OPND_FPIMM0:
1654 1.1.1.1.8.2 tls if (opnd->imm.value != 0)
1655 1.1.1.1.8.2 tls {
1656 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1657 1.1.1.1.8.2 tls _("immediate zero expected"));
1658 1.1.1.1.8.2 tls return 0;
1659 1.1.1.1.8.2 tls }
1660 1.1.1.1.8.2 tls break;
1661 1.1.1.1.8.2 tls
1662 1.1.1.1.8.2 tls case AARCH64_OPND_SHLL_IMM:
1663 1.1.1.1.8.2 tls assert (idx == 2);
1664 1.1.1.1.8.2 tls size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
1665 1.1.1.1.8.2 tls if (opnd->imm.value != size)
1666 1.1.1.1.8.2 tls {
1667 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1668 1.1.1.1.8.2 tls _("invalid shift amount"));
1669 1.1.1.1.8.2 tls return 0;
1670 1.1.1.1.8.2 tls }
1671 1.1.1.1.8.2 tls break;
1672 1.1.1.1.8.2 tls
1673 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_VLSL:
1674 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (qualifier);
1675 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
1676 1.1.1.1.8.2 tls {
1677 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 0,
1678 1.1.1.1.8.2 tls size * 8 - 1);
1679 1.1.1.1.8.2 tls return 0;
1680 1.1.1.1.8.2 tls }
1681 1.1.1.1.8.2 tls break;
1682 1.1.1.1.8.2 tls
1683 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_VLSR:
1684 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (qualifier);
1685 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->imm.value, 1, size * 8))
1686 1.1.1.1.8.2 tls {
1687 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
1688 1.1.1.1.8.2 tls return 0;
1689 1.1.1.1.8.2 tls }
1690 1.1.1.1.8.2 tls break;
1691 1.1.1.1.8.2 tls
1692 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_IMM:
1693 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_IMM_SFT:
1694 1.1.1.1.8.2 tls /* Qualifier check. */
1695 1.1.1.1.8.2 tls switch (qualifier)
1696 1.1.1.1.8.2 tls {
1697 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_LSL:
1698 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_LSL)
1699 1.1.1.1.8.2 tls {
1700 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1701 1.1.1.1.8.2 tls _("invalid shift operator"));
1702 1.1.1.1.8.2 tls return 0;
1703 1.1.1.1.8.2 tls }
1704 1.1.1.1.8.2 tls break;
1705 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_MSL:
1706 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_MSL)
1707 1.1.1.1.8.2 tls {
1708 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1709 1.1.1.1.8.2 tls _("invalid shift operator"));
1710 1.1.1.1.8.2 tls return 0;
1711 1.1.1.1.8.2 tls }
1712 1.1.1.1.8.2 tls break;
1713 1.1.1.1.8.2 tls case AARCH64_OPND_QLF_NIL:
1714 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_NONE)
1715 1.1.1.1.8.2 tls {
1716 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1717 1.1.1.1.8.2 tls _("shift is not permitted"));
1718 1.1.1.1.8.2 tls return 0;
1719 1.1.1.1.8.2 tls }
1720 1.1.1.1.8.2 tls break;
1721 1.1.1.1.8.2 tls default:
1722 1.1.1.1.8.2 tls assert (0);
1723 1.1.1.1.8.2 tls return 0;
1724 1.1.1.1.8.2 tls }
1725 1.1.1.1.8.2 tls /* Is the immediate valid? */
1726 1.1.1.1.8.2 tls assert (idx == 1);
1727 1.1.1.1.8.2 tls if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
1728 1.1.1.1.8.2 tls {
1729 1.1.1.1.8.2 tls /* uimm8 */
1730 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->imm.value, 0, 255))
1731 1.1.1.1.8.2 tls {
1732 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 0, 255);
1733 1.1.1.1.8.2 tls return 0;
1734 1.1.1.1.8.2 tls }
1735 1.1.1.1.8.2 tls }
1736 1.1.1.1.8.2 tls else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
1737 1.1.1.1.8.2 tls {
1738 1.1.1.1.8.2 tls /* uimm64 is not
1739 1.1.1.1.8.2 tls 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
1740 1.1.1.1.8.2 tls ffffffffgggggggghhhhhhhh'. */
1741 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1742 1.1.1.1.8.2 tls _("invalid value for immediate"));
1743 1.1.1.1.8.2 tls return 0;
1744 1.1.1.1.8.2 tls }
1745 1.1.1.1.8.2 tls /* Is the shift amount valid? */
1746 1.1.1.1.8.2 tls switch (opnd->shifter.kind)
1747 1.1.1.1.8.2 tls {
1748 1.1.1.1.8.2 tls case AARCH64_MOD_LSL:
1749 1.1.1.1.8.2 tls size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1750 1.1.1.1.8.2 tls if (!value_aligned_p (opnd->shifter.amount, 8))
1751 1.1.1.1.8.2 tls {
1752 1.1.1.1.8.2 tls set_unaligned_error (mismatch_detail, idx, 8);
1753 1.1.1.1.8.2 tls return 0;
1754 1.1.1.1.8.2 tls }
1755 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
1756 1.1.1.1.8.2 tls {
1757 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 0,
1758 1.1.1.1.8.2 tls (size - 1) * 8);
1759 1.1.1.1.8.2 tls return 0;
1760 1.1.1.1.8.2 tls }
1761 1.1.1.1.8.2 tls break;
1762 1.1.1.1.8.2 tls case AARCH64_MOD_MSL:
1763 1.1.1.1.8.2 tls /* Only 8 and 16 are valid shift amount. */
1764 1.1.1.1.8.2 tls if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
1765 1.1.1.1.8.2 tls {
1766 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1767 1.1.1.1.8.2 tls _("shift amount expected to be 0 or 16"));
1768 1.1.1.1.8.2 tls return 0;
1769 1.1.1.1.8.2 tls }
1770 1.1.1.1.8.2 tls break;
1771 1.1.1.1.8.2 tls default:
1772 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_NONE)
1773 1.1.1.1.8.2 tls {
1774 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1775 1.1.1.1.8.2 tls _("invalid shift operator"));
1776 1.1.1.1.8.2 tls return 0;
1777 1.1.1.1.8.2 tls }
1778 1.1.1.1.8.2 tls break;
1779 1.1.1.1.8.2 tls }
1780 1.1.1.1.8.2 tls break;
1781 1.1.1.1.8.2 tls
1782 1.1.1.1.8.2 tls case AARCH64_OPND_FPIMM:
1783 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_FPIMM:
1784 1.1.1.1.8.2 tls if (opnd->imm.is_fp == 0)
1785 1.1.1.1.8.2 tls {
1786 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1787 1.1.1.1.8.2 tls _("floating-point immediate expected"));
1788 1.1.1.1.8.2 tls return 0;
1789 1.1.1.1.8.2 tls }
1790 1.1.1.1.8.2 tls /* The value is expected to be an 8-bit floating-point constant with
1791 1.1.1.1.8.2 tls sign, 3-bit exponent and normalized 4 bits of precision, encoded
1792 1.1.1.1.8.2 tls in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
1793 1.1.1.1.8.2 tls instruction). */
1794 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->imm.value, 0, 255))
1795 1.1.1.1.8.2 tls {
1796 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1797 1.1.1.1.8.2 tls _("immediate out of range"));
1798 1.1.1.1.8.2 tls return 0;
1799 1.1.1.1.8.2 tls }
1800 1.1.1.1.8.2 tls if (opnd->shifter.kind != AARCH64_MOD_NONE)
1801 1.1.1.1.8.2 tls {
1802 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1803 1.1.1.1.8.2 tls _("invalid shift operator"));
1804 1.1.1.1.8.2 tls return 0;
1805 1.1.1.1.8.2 tls }
1806 1.1.1.1.8.2 tls break;
1807 1.1.1.1.8.2 tls
1808 1.1.1.1.8.2 tls default:
1809 1.1.1.1.8.2 tls break;
1810 1.1.1.1.8.2 tls }
1811 1.1.1.1.8.2 tls break;
1812 1.1.1.1.8.2 tls
1813 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_CP_REG:
1814 1.1.1.1.8.2 tls /* Cn or Cm: 4-bit opcode field named for historical reasons.
1815 1.1.1.1.8.2 tls valid range: C0 - C15. */
1816 1.1.1.1.8.2 tls if (opnd->reg.regno > 15)
1817 1.1.1.1.8.2 tls {
1818 1.1.1.1.8.2 tls set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1819 1.1.1.1.8.2 tls return 0;
1820 1.1.1.1.8.2 tls }
1821 1.1.1.1.8.2 tls break;
1822 1.1.1.1.8.2 tls
1823 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_SYSTEM:
1824 1.1.1.1.8.2 tls switch (type)
1825 1.1.1.1.8.2 tls {
1826 1.1.1.1.8.2 tls case AARCH64_OPND_PSTATEFIELD:
1827 1.1.1.1.8.2 tls assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
1828 1.1.1.1.8.2 tls /* MSR SPSel, #uimm4
1829 1.1.1.1.8.2 tls Uses uimm4 as a control value to select the stack pointer: if
1830 1.1.1.1.8.2 tls bit 0 is set it selects the current exception level's stack
1831 1.1.1.1.8.2 tls pointer, if bit 0 is clear it selects shared EL0 stack pointer.
1832 1.1.1.1.8.2 tls Bits 1 to 3 of uimm4 are reserved and should be zero. */
1833 1.1.1.1.8.2 tls if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
1834 1.1.1.1.8.2 tls {
1835 1.1.1.1.8.2 tls set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
1836 1.1.1.1.8.2 tls return 0;
1837 1.1.1.1.8.2 tls }
1838 1.1.1.1.8.2 tls break;
1839 1.1.1.1.8.2 tls default:
1840 1.1.1.1.8.2 tls break;
1841 1.1.1.1.8.2 tls }
1842 1.1.1.1.8.2 tls break;
1843 1.1.1.1.8.2 tls
1844 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_SIMD_ELEMENT:
1845 1.1.1.1.8.2 tls /* Get the upper bound for the element index. */
1846 1.1.1.1.8.2 tls num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
1847 1.1.1.1.8.2 tls /* Index out-of-range. */
1848 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->reglane.index, 0, num))
1849 1.1.1.1.8.2 tls {
1850 1.1.1.1.8.2 tls set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
1851 1.1.1.1.8.2 tls return 0;
1852 1.1.1.1.8.2 tls }
1853 1.1.1.1.8.2 tls /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
1854 1.1.1.1.8.2 tls <Vm> Is the vector register (V0-V31) or (V0-V15), whose
1855 1.1.1.1.8.2 tls number is encoded in "size:M:Rm":
1856 1.1.1.1.8.2 tls size <Vm>
1857 1.1.1.1.8.2 tls 00 RESERVED
1858 1.1.1.1.8.2 tls 01 0:Rm
1859 1.1.1.1.8.2 tls 10 M:Rm
1860 1.1.1.1.8.2 tls 11 RESERVED */
1861 1.1.1.1.8.2 tls if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
1862 1.1.1.1.8.2 tls && !value_in_range_p (opnd->reglane.regno, 0, 15))
1863 1.1.1.1.8.2 tls {
1864 1.1.1.1.8.2 tls set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1865 1.1.1.1.8.2 tls return 0;
1866 1.1.1.1.8.2 tls }
1867 1.1.1.1.8.2 tls break;
1868 1.1.1.1.8.2 tls
1869 1.1.1.1.8.2 tls case AARCH64_OPND_CLASS_MODIFIED_REG:
1870 1.1.1.1.8.2 tls assert (idx == 1 || idx == 2);
1871 1.1.1.1.8.2 tls switch (type)
1872 1.1.1.1.8.2 tls {
1873 1.1.1.1.8.2 tls case AARCH64_OPND_Rm_EXT:
1874 1.1.1.1.8.2 tls if (aarch64_extend_operator_p (opnd->shifter.kind) == FALSE
1875 1.1.1.1.8.2 tls && opnd->shifter.kind != AARCH64_MOD_LSL)
1876 1.1.1.1.8.2 tls {
1877 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1878 1.1.1.1.8.2 tls _("extend operator expected"));
1879 1.1.1.1.8.2 tls return 0;
1880 1.1.1.1.8.2 tls }
1881 1.1.1.1.8.2 tls /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
1882 1.1.1.1.8.2 tls (i.e. SP), in which case it defaults to LSL. The LSL alias is
1883 1.1.1.1.8.2 tls only valid when "Rd" or "Rn" is '11111', and is preferred in that
1884 1.1.1.1.8.2 tls case. */
1885 1.1.1.1.8.2 tls if (!aarch64_stack_pointer_p (opnds + 0)
1886 1.1.1.1.8.2 tls && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
1887 1.1.1.1.8.2 tls {
1888 1.1.1.1.8.2 tls if (!opnd->shifter.operator_present)
1889 1.1.1.1.8.2 tls {
1890 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1891 1.1.1.1.8.2 tls _("missing extend operator"));
1892 1.1.1.1.8.2 tls return 0;
1893 1.1.1.1.8.2 tls }
1894 1.1.1.1.8.2 tls else if (opnd->shifter.kind == AARCH64_MOD_LSL)
1895 1.1.1.1.8.2 tls {
1896 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1897 1.1.1.1.8.2 tls _("'LSL' operator not allowed"));
1898 1.1.1.1.8.2 tls return 0;
1899 1.1.1.1.8.2 tls }
1900 1.1.1.1.8.2 tls }
1901 1.1.1.1.8.2 tls assert (opnd->shifter.operator_present /* Default to LSL. */
1902 1.1.1.1.8.2 tls || opnd->shifter.kind == AARCH64_MOD_LSL);
1903 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->shifter.amount, 0, 4))
1904 1.1.1.1.8.2 tls {
1905 1.1.1.1.8.2 tls set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
1906 1.1.1.1.8.2 tls return 0;
1907 1.1.1.1.8.2 tls }
1908 1.1.1.1.8.2 tls /* In the 64-bit form, the final register operand is written as Wm
1909 1.1.1.1.8.2 tls for all but the (possibly omitted) UXTX/LSL and SXTX
1910 1.1.1.1.8.2 tls operators.
1911 1.1.1.1.8.2 tls N.B. GAS allows X register to be used with any operator as a
1912 1.1.1.1.8.2 tls programming convenience. */
1913 1.1.1.1.8.2 tls if (qualifier == AARCH64_OPND_QLF_X
1914 1.1.1.1.8.2 tls && opnd->shifter.kind != AARCH64_MOD_LSL
1915 1.1.1.1.8.2 tls && opnd->shifter.kind != AARCH64_MOD_UXTX
1916 1.1.1.1.8.2 tls && opnd->shifter.kind != AARCH64_MOD_SXTX)
1917 1.1.1.1.8.2 tls {
1918 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx, _("W register expected"));
1919 1.1.1.1.8.2 tls return 0;
1920 1.1.1.1.8.2 tls }
1921 1.1.1.1.8.2 tls break;
1922 1.1.1.1.8.2 tls
1923 1.1.1.1.8.2 tls case AARCH64_OPND_Rm_SFT:
1924 1.1.1.1.8.2 tls /* ROR is not available to the shifted register operand in
1925 1.1.1.1.8.2 tls arithmetic instructions. */
1926 1.1.1.1.8.2 tls if (aarch64_shift_operator_p (opnd->shifter.kind) == FALSE)
1927 1.1.1.1.8.2 tls {
1928 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1929 1.1.1.1.8.2 tls _("shift operator expected"));
1930 1.1.1.1.8.2 tls return 0;
1931 1.1.1.1.8.2 tls }
1932 1.1.1.1.8.2 tls if (opnd->shifter.kind == AARCH64_MOD_ROR
1933 1.1.1.1.8.2 tls && opcode->iclass != log_shift)
1934 1.1.1.1.8.2 tls {
1935 1.1.1.1.8.2 tls set_other_error (mismatch_detail, idx,
1936 1.1.1.1.8.2 tls _("'ROR' operator not allowed"));
1937 1.1.1.1.8.2 tls return 0;
1938 1.1.1.1.8.2 tls }
1939 1.1.1.1.8.2 tls num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
1940 1.1.1.1.8.2 tls if (!value_in_range_p (opnd->shifter.amount, 0, num))
1941 1.1.1.1.8.2 tls {
1942 1.1.1.1.8.2 tls set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
1943 1.1.1.1.8.2 tls return 0;
1944 1.1.1.1.8.2 tls }
1945 1.1.1.1.8.2 tls break;
1946 1.1.1.1.8.2 tls
1947 1.1.1.1.8.2 tls default:
1948 1.1.1.1.8.2 tls break;
1949 1.1.1.1.8.2 tls }
1950 1.1.1.1.8.2 tls break;
1951 1.1.1.1.8.2 tls
1952 1.1.1.1.8.2 tls default:
1953 1.1.1.1.8.2 tls break;
1954 1.1.1.1.8.2 tls }
1955 1.1.1.1.8.2 tls
1956 1.1.1.1.8.2 tls return 1;
1957 1.1.1.1.8.2 tls }
1958 1.1.1.1.8.2 tls
1959 1.1.1.1.8.2 tls /* Main entrypoint for the operand constraint checking.
1960 1.1.1.1.8.2 tls
1961 1.1.1.1.8.2 tls Return 1 if operands of *INST meet the constraint applied by the operand
1962 1.1.1.1.8.2 tls codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
1963 1.1.1.1.8.2 tls not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
1964 1.1.1.1.8.2 tls adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
1965 1.1.1.1.8.2 tls with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
1966 1.1.1.1.8.2 tls error kind when it is notified that an instruction does not pass the check).
1967 1.1.1.1.8.2 tls
1968 1.1.1.1.8.2 tls Un-determined operand qualifiers may get established during the process. */
1969 1.1.1.1.8.2 tls
1970 1.1.1.1.8.2 tls int
1971 1.1.1.1.8.2 tls aarch64_match_operands_constraint (aarch64_inst *inst,
1972 1.1.1.1.8.2 tls aarch64_operand_error *mismatch_detail)
1973 1.1.1.1.8.2 tls {
1974 1.1.1.1.8.2 tls int i;
1975 1.1.1.1.8.2 tls
1976 1.1.1.1.8.2 tls DEBUG_TRACE ("enter");
1977 1.1.1.1.8.2 tls
1978 1.1.1.1.8.2 tls /* Match operands' qualifier.
1979 1.1.1.1.8.2 tls *INST has already had qualifier establish for some, if not all, of
1980 1.1.1.1.8.2 tls its operands; we need to find out whether these established
1981 1.1.1.1.8.2 tls qualifiers match one of the qualifier sequence in
1982 1.1.1.1.8.2 tls INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
1983 1.1.1.1.8.2 tls with the corresponding qualifier in such a sequence.
1984 1.1.1.1.8.2 tls Only basic operand constraint checking is done here; the more thorough
1985 1.1.1.1.8.2 tls constraint checking will carried out by operand_general_constraint_met_p,
1986 1.1.1.1.8.2 tls which has be to called after this in order to get all of the operands'
1987 1.1.1.1.8.2 tls qualifiers established. */
1988 1.1.1.1.8.2 tls if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
1989 1.1.1.1.8.2 tls {
1990 1.1.1.1.8.2 tls DEBUG_TRACE ("FAIL on operand qualifier matching");
1991 1.1.1.1.8.2 tls if (mismatch_detail)
1992 1.1.1.1.8.2 tls {
1993 1.1.1.1.8.2 tls /* Return an error type to indicate that it is the qualifier
1994 1.1.1.1.8.2 tls matching failure; we don't care about which operand as there
1995 1.1.1.1.8.2 tls are enough information in the opcode table to reproduce it. */
1996 1.1.1.1.8.2 tls mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
1997 1.1.1.1.8.2 tls mismatch_detail->index = -1;
1998 1.1.1.1.8.2 tls mismatch_detail->error = NULL;
1999 1.1.1.1.8.2 tls }
2000 1.1.1.1.8.2 tls return 0;
2001 1.1.1.1.8.2 tls }
2002 1.1.1.1.8.2 tls
2003 1.1.1.1.8.2 tls /* Match operands' constraint. */
2004 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2005 1.1.1.1.8.2 tls {
2006 1.1.1.1.8.2 tls enum aarch64_opnd type = inst->opcode->operands[i];
2007 1.1.1.1.8.2 tls if (type == AARCH64_OPND_NIL)
2008 1.1.1.1.8.2 tls break;
2009 1.1.1.1.8.2 tls if (inst->operands[i].skip)
2010 1.1.1.1.8.2 tls {
2011 1.1.1.1.8.2 tls DEBUG_TRACE ("skip the incomplete operand %d", i);
2012 1.1.1.1.8.2 tls continue;
2013 1.1.1.1.8.2 tls }
2014 1.1.1.1.8.2 tls if (operand_general_constraint_met_p (inst->operands, i, type,
2015 1.1.1.1.8.2 tls inst->opcode, mismatch_detail) == 0)
2016 1.1.1.1.8.2 tls {
2017 1.1.1.1.8.2 tls DEBUG_TRACE ("FAIL on operand %d", i);
2018 1.1.1.1.8.2 tls return 0;
2019 1.1.1.1.8.2 tls }
2020 1.1.1.1.8.2 tls }
2021 1.1.1.1.8.2 tls
2022 1.1.1.1.8.2 tls DEBUG_TRACE ("PASS");
2023 1.1.1.1.8.2 tls
2024 1.1.1.1.8.2 tls return 1;
2025 1.1.1.1.8.2 tls }
2026 1.1.1.1.8.2 tls
2027 1.1.1.1.8.2 tls /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2028 1.1.1.1.8.2 tls Also updates the TYPE of each INST->OPERANDS with the corresponding
2029 1.1.1.1.8.2 tls value of OPCODE->OPERANDS.
2030 1.1.1.1.8.2 tls
2031 1.1.1.1.8.2 tls Note that some operand qualifiers may need to be manually cleared by
2032 1.1.1.1.8.2 tls the caller before it further calls the aarch64_opcode_encode; by
2033 1.1.1.1.8.2 tls doing this, it helps the qualifier matching facilities work
2034 1.1.1.1.8.2 tls properly. */
2035 1.1.1.1.8.2 tls
2036 1.1.1.1.8.2 tls const aarch64_opcode*
2037 1.1.1.1.8.2 tls aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2038 1.1.1.1.8.2 tls {
2039 1.1.1.1.8.2 tls int i;
2040 1.1.1.1.8.2 tls const aarch64_opcode *old = inst->opcode;
2041 1.1.1.1.8.2 tls
2042 1.1.1.1.8.2 tls inst->opcode = opcode;
2043 1.1.1.1.8.2 tls
2044 1.1.1.1.8.2 tls /* Update the operand types. */
2045 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2046 1.1.1.1.8.2 tls {
2047 1.1.1.1.8.2 tls inst->operands[i].type = opcode->operands[i];
2048 1.1.1.1.8.2 tls if (opcode->operands[i] == AARCH64_OPND_NIL)
2049 1.1.1.1.8.2 tls break;
2050 1.1.1.1.8.2 tls }
2051 1.1.1.1.8.2 tls
2052 1.1.1.1.8.2 tls DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2053 1.1.1.1.8.2 tls
2054 1.1.1.1.8.2 tls return old;
2055 1.1.1.1.8.2 tls }
2056 1.1.1.1.8.2 tls
2057 1.1.1.1.8.2 tls int
2058 1.1.1.1.8.2 tls aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2059 1.1.1.1.8.2 tls {
2060 1.1.1.1.8.2 tls int i;
2061 1.1.1.1.8.2 tls for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2062 1.1.1.1.8.2 tls if (operands[i] == operand)
2063 1.1.1.1.8.2 tls return i;
2064 1.1.1.1.8.2 tls else if (operands[i] == AARCH64_OPND_NIL)
2065 1.1.1.1.8.2 tls break;
2066 1.1.1.1.8.2 tls return -1;
2067 1.1.1.1.8.2 tls }
2068 1.1.1.1.8.2 tls
2069 1.1.1.1.8.2 tls /* [0][0] 32-bit integer regs with sp Wn
2071 1.1.1.1.8.2 tls [0][1] 64-bit integer regs with sp Xn sf=1
2072 1.1.1.1.8.2 tls [1][0] 32-bit integer regs with #0 Wn
2073 1.1.1.1.8.2 tls [1][1] 64-bit integer regs with #0 Xn sf=1 */
2074 1.1.1.1.8.2 tls static const char *int_reg[2][2][32] = {
2075 1.1.1.1.8.2 tls #define R32 "w"
2076 1.1.1.1.8.2 tls #define R64 "x"
2077 1.1.1.1.8.2 tls { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2078 1.1.1.1.8.2 tls R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2079 1.1.1.1.8.2 tls R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2080 1.1.1.1.8.2 tls R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", "wsp" },
2081 1.1.1.1.8.2 tls { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2082 1.1.1.1.8.2 tls R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2083 1.1.1.1.8.2 tls R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2084 1.1.1.1.8.2 tls R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", "sp" } },
2085 1.1.1.1.8.2 tls { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2086 1.1.1.1.8.2 tls R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2087 1.1.1.1.8.2 tls R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2088 1.1.1.1.8.2 tls R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", R32 "zr" },
2089 1.1.1.1.8.2 tls { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2090 1.1.1.1.8.2 tls R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2091 1.1.1.1.8.2 tls R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2092 1.1.1.1.8.2 tls R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", R64 "zr" } }
2093 1.1.1.1.8.2 tls #undef R64
2094 1.1.1.1.8.2 tls #undef R32
2095 1.1.1.1.8.2 tls };
2096 1.1.1.1.8.2 tls
2097 1.1.1.1.8.2 tls /* Return the integer register name.
2098 1.1.1.1.8.2 tls if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2099 1.1.1.1.8.2 tls
2100 1.1.1.1.8.2 tls static inline const char *
2101 1.1.1.1.8.2 tls get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2102 1.1.1.1.8.2 tls {
2103 1.1.1.1.8.2 tls const int has_zr = sp_reg_p ? 0 : 1;
2104 1.1.1.1.8.2 tls const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2105 1.1.1.1.8.2 tls return int_reg[has_zr][is_64][regno];
2106 1.1.1.1.8.2 tls }
2107 1.1.1.1.8.2 tls
2108 1.1.1.1.8.2 tls /* Like get_int_reg_name, but IS_64 is always 1. */
2109 1.1.1.1.8.2 tls
2110 1.1.1.1.8.2 tls static inline const char *
2111 1.1.1.1.8.2 tls get_64bit_int_reg_name (int regno, int sp_reg_p)
2112 1.1.1.1.8.2 tls {
2113 1.1.1.1.8.2 tls const int has_zr = sp_reg_p ? 0 : 1;
2114 1.1.1.1.8.2 tls return int_reg[has_zr][1][regno];
2115 1.1.1.1.8.2 tls }
2116 1.1.1.1.8.2 tls
2117 1.1.1.1.8.2 tls /* Types for expanding an encoded 8-bit value to a floating-point value. */
2118 1.1.1.1.8.2 tls
2119 1.1.1.1.8.2 tls typedef union
2120 1.1.1.1.8.2 tls {
2121 1.1.1.1.8.2 tls uint64_t i;
2122 1.1.1.1.8.2 tls double d;
2123 1.1.1.1.8.2 tls } double_conv_t;
2124 1.1.1.1.8.2 tls
2125 1.1.1.1.8.2 tls typedef union
2126 1.1.1.1.8.2 tls {
2127 1.1.1.1.8.2 tls uint32_t i;
2128 1.1.1.1.8.2 tls float f;
2129 1.1.1.1.8.2 tls } single_conv_t;
2130 1.1.1.1.8.2 tls
2131 1.1.1.1.8.2 tls /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2132 1.1.1.1.8.2 tls normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2133 1.1.1.1.8.2 tls (depending on the type of the instruction). IMM8 will be expanded to a
2134 1.1.1.1.8.2 tls single-precision floating-point value (IS_DP == 0) or a double-precision
2135 1.1.1.1.8.2 tls floating-point value (IS_DP == 1). The expanded value is returned. */
2136 1.1.1.1.8.2 tls
2137 1.1.1.1.8.2 tls static uint64_t
2138 1.1.1.1.8.2 tls expand_fp_imm (int is_dp, uint32_t imm8)
2139 1.1.1.1.8.2 tls {
2140 1.1.1.1.8.2 tls uint64_t imm;
2141 1.1.1.1.8.2 tls uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2142 1.1.1.1.8.2 tls
2143 1.1.1.1.8.2 tls imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2144 1.1.1.1.8.2 tls imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2145 1.1.1.1.8.2 tls imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2146 1.1.1.1.8.2 tls imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2147 1.1.1.1.8.2 tls | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
2148 1.1.1.1.8.2 tls if (is_dp)
2149 1.1.1.1.8.2 tls {
2150 1.1.1.1.8.2 tls imm = (imm8_7 << (63-32)) /* imm8<7> */
2151 1.1.1.1.8.2 tls | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2152 1.1.1.1.8.2 tls | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2153 1.1.1.1.8.2 tls | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2154 1.1.1.1.8.2 tls | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2155 1.1.1.1.8.2 tls imm <<= 32;
2156 1.1.1.1.8.2 tls }
2157 1.1.1.1.8.2 tls else
2158 1.1.1.1.8.2 tls {
2159 1.1.1.1.8.2 tls imm = (imm8_7 << 31) /* imm8<7> */
2160 1.1.1.1.8.2 tls | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2161 1.1.1.1.8.2 tls | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2162 1.1.1.1.8.2 tls | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2163 1.1.1.1.8.2 tls }
2164 1.1.1.1.8.2 tls
2165 1.1.1.1.8.2 tls return imm;
2166 1.1.1.1.8.2 tls }
2167 1.1.1.1.8.2 tls
2168 1.1.1.1.8.2 tls /* Produce the string representation of the register list operand *OPND
2169 1.1.1.1.8.2 tls in the buffer pointed by BUF of size SIZE. */
2170 1.1.1.1.8.2 tls static void
2171 1.1.1.1.8.2 tls print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
2172 1.1.1.1.8.2 tls {
2173 1.1.1.1.8.2 tls const int num_regs = opnd->reglist.num_regs;
2174 1.1.1.1.8.2 tls const int first_reg = opnd->reglist.first_regno;
2175 1.1.1.1.8.2 tls const int last_reg = (first_reg + num_regs - 1) & 0x1f;
2176 1.1.1.1.8.2 tls const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
2177 1.1.1.1.8.2 tls char tb[8]; /* Temporary buffer. */
2178 1.1.1.1.8.2 tls
2179 1.1.1.1.8.2 tls assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
2180 1.1.1.1.8.2 tls assert (num_regs >= 1 && num_regs <= 4);
2181 1.1.1.1.8.2 tls
2182 1.1.1.1.8.2 tls /* Prepare the index if any. */
2183 1.1.1.1.8.2 tls if (opnd->reglist.has_index)
2184 1.1.1.1.8.2 tls snprintf (tb, 8, "[%d]", opnd->reglist.index);
2185 1.1.1.1.8.2 tls else
2186 1.1.1.1.8.2 tls tb[0] = '\0';
2187 1.1.1.1.8.2 tls
2188 1.1.1.1.8.2 tls /* The hyphenated form is preferred for disassembly if there are
2189 1.1.1.1.8.2 tls more than two registers in the list, and the register numbers
2190 1.1.1.1.8.2 tls are monotonically increasing in increments of one. */
2191 1.1.1.1.8.2 tls if (num_regs > 2 && last_reg > first_reg)
2192 1.1.1.1.8.2 tls snprintf (buf, size, "{v%d.%s-v%d.%s}%s", first_reg, qlf_name,
2193 1.1.1.1.8.2 tls last_reg, qlf_name, tb);
2194 1.1.1.1.8.2 tls else
2195 1.1.1.1.8.2 tls {
2196 1.1.1.1.8.2 tls const int reg0 = first_reg;
2197 1.1.1.1.8.2 tls const int reg1 = (first_reg + 1) & 0x1f;
2198 1.1.1.1.8.2 tls const int reg2 = (first_reg + 2) & 0x1f;
2199 1.1.1.1.8.2 tls const int reg3 = (first_reg + 3) & 0x1f;
2200 1.1.1.1.8.2 tls
2201 1.1.1.1.8.2 tls switch (num_regs)
2202 1.1.1.1.8.2 tls {
2203 1.1.1.1.8.2 tls case 1:
2204 1.1.1.1.8.2 tls snprintf (buf, size, "{v%d.%s}%s", reg0, qlf_name, tb);
2205 1.1.1.1.8.2 tls break;
2206 1.1.1.1.8.2 tls case 2:
2207 1.1.1.1.8.2 tls snprintf (buf, size, "{v%d.%s, v%d.%s}%s", reg0, qlf_name,
2208 1.1.1.1.8.2 tls reg1, qlf_name, tb);
2209 1.1.1.1.8.2 tls break;
2210 1.1.1.1.8.2 tls case 3:
2211 1.1.1.1.8.2 tls snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s}%s", reg0, qlf_name,
2212 1.1.1.1.8.2 tls reg1, qlf_name, reg2, qlf_name, tb);
2213 1.1.1.1.8.2 tls break;
2214 1.1.1.1.8.2 tls case 4:
2215 1.1.1.1.8.2 tls snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s, v%d.%s}%s",
2216 1.1.1.1.8.2 tls reg0, qlf_name, reg1, qlf_name, reg2, qlf_name,
2217 1.1.1.1.8.2 tls reg3, qlf_name, tb);
2218 1.1.1.1.8.2 tls break;
2219 1.1.1.1.8.2 tls }
2220 1.1.1.1.8.2 tls }
2221 1.1.1.1.8.2 tls }
2222 1.1.1.1.8.2 tls
2223 1.1.1.1.8.2 tls /* Produce the string representation of the register offset address operand
2224 1.1.1.1.8.2 tls *OPND in the buffer pointed by BUF of size SIZE. */
2225 1.1.1.1.8.2 tls static void
2226 1.1.1.1.8.2 tls print_register_offset_address (char *buf, size_t size,
2227 1.1.1.1.8.2 tls const aarch64_opnd_info *opnd)
2228 1.1.1.1.8.2 tls {
2229 1.1.1.1.8.2 tls const size_t tblen = 16;
2230 1.1.1.1.8.2 tls char tb[tblen]; /* Temporary buffer. */
2231 1.1.1.1.8.2 tls bfd_boolean lsl_p = FALSE; /* Is LSL shift operator? */
2232 1.1.1.1.8.2 tls bfd_boolean wm_p = FALSE; /* Should Rm be Wm? */
2233 1.1.1.1.8.2 tls bfd_boolean print_extend_p = TRUE;
2234 1.1.1.1.8.2 tls bfd_boolean print_amount_p = TRUE;
2235 1.1.1.1.8.2 tls const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
2236 1.1.1.1.8.2 tls
2237 1.1.1.1.8.2 tls switch (opnd->shifter.kind)
2238 1.1.1.1.8.2 tls {
2239 1.1.1.1.8.2 tls case AARCH64_MOD_UXTW: wm_p = TRUE; break;
2240 1.1.1.1.8.2 tls case AARCH64_MOD_LSL : lsl_p = TRUE; break;
2241 1.1.1.1.8.2 tls case AARCH64_MOD_SXTW: wm_p = TRUE; break;
2242 1.1.1.1.8.2 tls case AARCH64_MOD_SXTX: break;
2243 1.1.1.1.8.2 tls default: assert (0);
2244 1.1.1.1.8.2 tls }
2245 1.1.1.1.8.2 tls
2246 1.1.1.1.8.2 tls if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
2247 1.1.1.1.8.2 tls || !opnd->shifter.amount_present))
2248 1.1.1.1.8.2 tls {
2249 1.1.1.1.8.2 tls /* Not print the shift/extend amount when the amount is zero and
2250 1.1.1.1.8.2 tls when it is not the special case of 8-bit load/store instruction. */
2251 1.1.1.1.8.2 tls print_amount_p = FALSE;
2252 1.1.1.1.8.2 tls /* Likewise, no need to print the shift operator LSL in such a
2253 1.1.1.1.8.2 tls situation. */
2254 1.1.1.1.8.2 tls if (lsl_p)
2255 1.1.1.1.8.2 tls print_extend_p = FALSE;
2256 1.1.1.1.8.2 tls }
2257 1.1.1.1.8.2 tls
2258 1.1.1.1.8.2 tls /* Prepare for the extend/shift. */
2259 1.1.1.1.8.2 tls if (print_extend_p)
2260 1.1.1.1.8.2 tls {
2261 1.1.1.1.8.2 tls if (print_amount_p)
2262 1.1.1.1.8.2 tls snprintf (tb, tblen, ",%s #%d", shift_name, opnd->shifter.amount);
2263 1.1.1.1.8.2 tls else
2264 1.1.1.1.8.2 tls snprintf (tb, tblen, ",%s", shift_name);
2265 1.1.1.1.8.2 tls }
2266 1.1.1.1.8.2 tls else
2267 1.1.1.1.8.2 tls tb[0] = '\0';
2268 1.1.1.1.8.2 tls
2269 1.1.1.1.8.2 tls snprintf (buf, size, "[%s,%c%d%s]",
2270 1.1.1.1.8.2 tls get_64bit_int_reg_name (opnd->addr.base_regno, 1),
2271 1.1.1.1.8.2 tls wm_p ? 'w' : 'x', opnd->addr.offset.regno, tb);
2272 1.1.1.1.8.2 tls }
2273 1.1.1.1.8.2 tls
2274 1.1.1.1.8.2 tls /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
2275 1.1.1.1.8.2 tls in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
2276 1.1.1.1.8.2 tls PC, PCREL_P and ADDRESS are used to pass in and return information about
2277 1.1.1.1.8.2 tls the PC-relative address calculation, where the PC value is passed in
2278 1.1.1.1.8.2 tls PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
2279 1.1.1.1.8.2 tls will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
2280 1.1.1.1.8.2 tls calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
2281 1.1.1.1.8.2 tls
2282 1.1.1.1.8.2 tls The function serves both the disassembler and the assembler diagnostics
2283 1.1.1.1.8.2 tls issuer, which is the reason why it lives in this file. */
2284 1.1.1.1.8.2 tls
2285 1.1.1.1.8.2 tls void
2286 1.1.1.1.8.2 tls aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
2287 1.1.1.1.8.2 tls const aarch64_opcode *opcode,
2288 1.1.1.1.8.2 tls const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
2289 1.1.1.1.8.2 tls bfd_vma *address)
2290 1.1.1.1.8.2 tls {
2291 1.1.1.1.8.2 tls int i;
2292 1.1.1.1.8.2 tls const char *name = NULL;
2293 1.1.1.1.8.2 tls const aarch64_opnd_info *opnd = opnds + idx;
2294 1.1.1.1.8.2 tls enum aarch64_modifier_kind kind;
2295 1.1.1.1.8.2 tls uint64_t addr;
2296 1.1.1.1.8.2 tls
2297 1.1.1.1.8.2 tls buf[0] = '\0';
2298 1.1.1.1.8.2 tls if (pcrel_p)
2299 1.1.1.1.8.2 tls *pcrel_p = 0;
2300 1.1.1.1.8.2 tls
2301 1.1.1.1.8.2 tls switch (opnd->type)
2302 1.1.1.1.8.2 tls {
2303 1.1.1.1.8.2 tls case AARCH64_OPND_Rd:
2304 1.1.1.1.8.2 tls case AARCH64_OPND_Rn:
2305 1.1.1.1.8.2 tls case AARCH64_OPND_Rm:
2306 1.1.1.1.8.2 tls case AARCH64_OPND_Rt:
2307 1.1.1.1.8.2 tls case AARCH64_OPND_Rt2:
2308 1.1.1.1.8.2 tls case AARCH64_OPND_Rs:
2309 1.1.1.1.8.2 tls case AARCH64_OPND_Ra:
2310 1.1.1.1.8.2 tls case AARCH64_OPND_Rt_SYS:
2311 1.1.1.1.8.2 tls /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
2312 1.1.1.1.8.2 tls the <ic_op>, therefore we we use opnd->present to override the
2313 1.1.1.1.8.2 tls generic optional-ness information. */
2314 1.1.1.1.8.2 tls if (opnd->type == AARCH64_OPND_Rt_SYS && !opnd->present)
2315 1.1.1.1.8.2 tls break;
2316 1.1.1.1.8.2 tls /* Omit the operand, e.g. RET. */
2317 1.1.1.1.8.2 tls if (optional_operand_p (opcode, idx)
2318 1.1.1.1.8.2 tls && opnd->reg.regno == get_optional_operand_default_value (opcode))
2319 1.1.1.1.8.2 tls break;
2320 1.1.1.1.8.2 tls assert (opnd->qualifier == AARCH64_OPND_QLF_W
2321 1.1.1.1.8.2 tls || opnd->qualifier == AARCH64_OPND_QLF_X);
2322 1.1.1.1.8.2 tls snprintf (buf, size, "%s",
2323 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2324 1.1.1.1.8.2 tls break;
2325 1.1.1.1.8.2 tls
2326 1.1.1.1.8.2 tls case AARCH64_OPND_Rd_SP:
2327 1.1.1.1.8.2 tls case AARCH64_OPND_Rn_SP:
2328 1.1.1.1.8.2 tls assert (opnd->qualifier == AARCH64_OPND_QLF_W
2329 1.1.1.1.8.2 tls || opnd->qualifier == AARCH64_OPND_QLF_WSP
2330 1.1.1.1.8.2 tls || opnd->qualifier == AARCH64_OPND_QLF_X
2331 1.1.1.1.8.2 tls || opnd->qualifier == AARCH64_OPND_QLF_SP);
2332 1.1.1.1.8.2 tls snprintf (buf, size, "%s",
2333 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
2334 1.1.1.1.8.2 tls break;
2335 1.1.1.1.8.2 tls
2336 1.1.1.1.8.2 tls case AARCH64_OPND_Rm_EXT:
2337 1.1.1.1.8.2 tls kind = opnd->shifter.kind;
2338 1.1.1.1.8.2 tls assert (idx == 1 || idx == 2);
2339 1.1.1.1.8.2 tls if ((aarch64_stack_pointer_p (opnds)
2340 1.1.1.1.8.2 tls || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
2341 1.1.1.1.8.2 tls && ((opnd->qualifier == AARCH64_OPND_QLF_W
2342 1.1.1.1.8.2 tls && opnds[0].qualifier == AARCH64_OPND_QLF_W
2343 1.1.1.1.8.2 tls && kind == AARCH64_MOD_UXTW)
2344 1.1.1.1.8.2 tls || (opnd->qualifier == AARCH64_OPND_QLF_X
2345 1.1.1.1.8.2 tls && kind == AARCH64_MOD_UXTX)))
2346 1.1.1.1.8.2 tls {
2347 1.1.1.1.8.2 tls /* 'LSL' is the preferred form in this case. */
2348 1.1.1.1.8.2 tls kind = AARCH64_MOD_LSL;
2349 1.1.1.1.8.2 tls if (opnd->shifter.amount == 0)
2350 1.1.1.1.8.2 tls {
2351 1.1.1.1.8.2 tls /* Shifter omitted. */
2352 1.1.1.1.8.2 tls snprintf (buf, size, "%s",
2353 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2354 1.1.1.1.8.2 tls break;
2355 1.1.1.1.8.2 tls }
2356 1.1.1.1.8.2 tls }
2357 1.1.1.1.8.2 tls if (opnd->shifter.amount)
2358 1.1.1.1.8.2 tls snprintf (buf, size, "%s, %s #%d",
2359 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2360 1.1.1.1.8.2 tls aarch64_operand_modifiers[kind].name,
2361 1.1.1.1.8.2 tls opnd->shifter.amount);
2362 1.1.1.1.8.2 tls else
2363 1.1.1.1.8.2 tls snprintf (buf, size, "%s, %s",
2364 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2365 1.1.1.1.8.2 tls aarch64_operand_modifiers[kind].name);
2366 1.1.1.1.8.2 tls break;
2367 1.1.1.1.8.2 tls
2368 1.1.1.1.8.2 tls case AARCH64_OPND_Rm_SFT:
2369 1.1.1.1.8.2 tls assert (opnd->qualifier == AARCH64_OPND_QLF_W
2370 1.1.1.1.8.2 tls || opnd->qualifier == AARCH64_OPND_QLF_X);
2371 1.1.1.1.8.2 tls if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
2372 1.1.1.1.8.2 tls snprintf (buf, size, "%s",
2373 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2374 1.1.1.1.8.2 tls else
2375 1.1.1.1.8.2 tls snprintf (buf, size, "%s, %s #%d",
2376 1.1.1.1.8.2 tls get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2377 1.1.1.1.8.2 tls aarch64_operand_modifiers[opnd->shifter.kind].name,
2378 1.1.1.1.8.2 tls opnd->shifter.amount);
2379 1.1.1.1.8.2 tls break;
2380 1.1.1.1.8.2 tls
2381 1.1.1.1.8.2 tls case AARCH64_OPND_Fd:
2382 1.1.1.1.8.2 tls case AARCH64_OPND_Fn:
2383 1.1.1.1.8.2 tls case AARCH64_OPND_Fm:
2384 1.1.1.1.8.2 tls case AARCH64_OPND_Fa:
2385 1.1.1.1.8.2 tls case AARCH64_OPND_Ft:
2386 1.1.1.1.8.2 tls case AARCH64_OPND_Ft2:
2387 1.1.1.1.8.2 tls case AARCH64_OPND_Sd:
2388 1.1.1.1.8.2 tls case AARCH64_OPND_Sn:
2389 1.1.1.1.8.2 tls case AARCH64_OPND_Sm:
2390 1.1.1.1.8.2 tls snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
2391 1.1.1.1.8.2 tls opnd->reg.regno);
2392 1.1.1.1.8.2 tls break;
2393 1.1.1.1.8.2 tls
2394 1.1.1.1.8.2 tls case AARCH64_OPND_Vd:
2395 1.1.1.1.8.2 tls case AARCH64_OPND_Vn:
2396 1.1.1.1.8.2 tls case AARCH64_OPND_Vm:
2397 1.1.1.1.8.2 tls snprintf (buf, size, "v%d.%s", opnd->reg.regno,
2398 1.1.1.1.8.2 tls aarch64_get_qualifier_name (opnd->qualifier));
2399 1.1.1.1.8.2 tls break;
2400 1.1.1.1.8.2 tls
2401 1.1.1.1.8.2 tls case AARCH64_OPND_Ed:
2402 1.1.1.1.8.2 tls case AARCH64_OPND_En:
2403 1.1.1.1.8.2 tls case AARCH64_OPND_Em:
2404 1.1.1.1.8.2 tls snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
2405 1.1.1.1.8.2 tls aarch64_get_qualifier_name (opnd->qualifier),
2406 1.1.1.1.8.2 tls opnd->reglane.index);
2407 1.1.1.1.8.2 tls break;
2408 1.1.1.1.8.2 tls
2409 1.1.1.1.8.2 tls case AARCH64_OPND_VdD1:
2410 1.1.1.1.8.2 tls case AARCH64_OPND_VnD1:
2411 1.1.1.1.8.2 tls snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
2412 1.1.1.1.8.2 tls break;
2413 1.1.1.1.8.2 tls
2414 1.1.1.1.8.2 tls case AARCH64_OPND_LVn:
2415 1.1.1.1.8.2 tls case AARCH64_OPND_LVt:
2416 1.1.1.1.8.2 tls case AARCH64_OPND_LVt_AL:
2417 1.1.1.1.8.2 tls case AARCH64_OPND_LEt:
2418 1.1.1.1.8.2 tls print_register_list (buf, size, opnd);
2419 1.1.1.1.8.2 tls break;
2420 1.1.1.1.8.2 tls
2421 1.1.1.1.8.2 tls case AARCH64_OPND_Cn:
2422 1.1.1.1.8.2 tls case AARCH64_OPND_Cm:
2423 1.1.1.1.8.2 tls snprintf (buf, size, "C%d", opnd->reg.regno);
2424 1.1.1.1.8.2 tls break;
2425 1.1.1.1.8.2 tls
2426 1.1.1.1.8.2 tls case AARCH64_OPND_IDX:
2427 1.1.1.1.8.2 tls case AARCH64_OPND_IMM:
2428 1.1.1.1.8.2 tls case AARCH64_OPND_WIDTH:
2429 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM3_OP1:
2430 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM3_OP2:
2431 1.1.1.1.8.2 tls case AARCH64_OPND_BIT_NUM:
2432 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_VLSL:
2433 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_VLSR:
2434 1.1.1.1.8.2 tls case AARCH64_OPND_SHLL_IMM:
2435 1.1.1.1.8.2 tls case AARCH64_OPND_IMM0:
2436 1.1.1.1.8.2 tls case AARCH64_OPND_IMMR:
2437 1.1.1.1.8.2 tls case AARCH64_OPND_IMMS:
2438 1.1.1.1.8.2 tls case AARCH64_OPND_FBITS:
2439 1.1.1.1.8.2 tls snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
2440 1.1.1.1.8.2 tls break;
2441 1.1.1.1.8.2 tls
2442 1.1.1.1.8.2 tls case AARCH64_OPND_IMM_MOV:
2443 1.1.1.1.8.2 tls switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2444 1.1.1.1.8.2 tls {
2445 1.1.1.1.8.2 tls case 4: /* e.g. MOV Wd, #<imm32>. */
2446 1.1.1.1.8.2 tls {
2447 1.1.1.1.8.2 tls int imm32 = opnd->imm.value;
2448 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
2449 1.1.1.1.8.2 tls }
2450 1.1.1.1.8.2 tls break;
2451 1.1.1.1.8.2 tls case 8: /* e.g. MOV Xd, #<imm64>. */
2452 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
2453 1.1.1.1.8.2 tls opnd->imm.value, opnd->imm.value);
2454 1.1.1.1.8.2 tls break;
2455 1.1.1.1.8.2 tls default: assert (0);
2456 1.1.1.1.8.2 tls }
2457 1.1.1.1.8.2 tls break;
2458 1.1.1.1.8.2 tls
2459 1.1.1.1.8.2 tls case AARCH64_OPND_FPIMM0:
2460 1.1.1.1.8.2 tls snprintf (buf, size, "#0.0");
2461 1.1.1.1.8.2 tls break;
2462 1.1.1.1.8.2 tls
2463 1.1.1.1.8.2 tls case AARCH64_OPND_LIMM:
2464 1.1.1.1.8.2 tls case AARCH64_OPND_AIMM:
2465 1.1.1.1.8.2 tls case AARCH64_OPND_HALF:
2466 1.1.1.1.8.2 tls if (opnd->shifter.amount)
2467 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64 ", lsl #%d", opnd->imm.value,
2468 1.1.1.1.8.2 tls opnd->shifter.amount);
2469 1.1.1.1.8.2 tls else
2470 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2471 1.1.1.1.8.2 tls break;
2472 1.1.1.1.8.2 tls
2473 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_IMM:
2474 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_IMM_SFT:
2475 1.1.1.1.8.2 tls if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
2476 1.1.1.1.8.2 tls || opnd->shifter.kind == AARCH64_MOD_NONE)
2477 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2478 1.1.1.1.8.2 tls else
2479 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64 ", %s #%d", opnd->imm.value,
2480 1.1.1.1.8.2 tls aarch64_operand_modifiers[opnd->shifter.kind].name,
2481 1.1.1.1.8.2 tls opnd->shifter.amount);
2482 1.1.1.1.8.2 tls break;
2483 1.1.1.1.8.2 tls
2484 1.1.1.1.8.2 tls case AARCH64_OPND_FPIMM:
2485 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_FPIMM:
2486 1.1.1.1.8.2 tls switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2487 1.1.1.1.8.2 tls {
2488 1.1.1.1.8.2 tls case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
2489 1.1.1.1.8.2 tls {
2490 1.1.1.1.8.2 tls single_conv_t c;
2491 1.1.1.1.8.2 tls c.i = expand_fp_imm (0, opnd->imm.value);
2492 1.1.1.1.8.2 tls snprintf (buf, size, "#%.18e", c.f);
2493 1.1.1.1.8.2 tls }
2494 1.1.1.1.8.2 tls break;
2495 1.1.1.1.8.2 tls case 8: /* e.g. FMOV <Sd>, #<imm>. */
2496 1.1.1.1.8.2 tls {
2497 1.1.1.1.8.2 tls double_conv_t c;
2498 1.1.1.1.8.2 tls c.i = expand_fp_imm (1, opnd->imm.value);
2499 1.1.1.1.8.2 tls snprintf (buf, size, "#%.18e", c.d);
2500 1.1.1.1.8.2 tls }
2501 1.1.1.1.8.2 tls break;
2502 1.1.1.1.8.2 tls default: assert (0);
2503 1.1.1.1.8.2 tls }
2504 1.1.1.1.8.2 tls break;
2505 1.1.1.1.8.2 tls
2506 1.1.1.1.8.2 tls case AARCH64_OPND_CCMP_IMM:
2507 1.1.1.1.8.2 tls case AARCH64_OPND_NZCV:
2508 1.1.1.1.8.2 tls case AARCH64_OPND_EXCEPTION:
2509 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM4:
2510 1.1.1.1.8.2 tls case AARCH64_OPND_UIMM7:
2511 1.1.1.1.8.2 tls if (optional_operand_p (opcode, idx) == TRUE
2512 1.1.1.1.8.2 tls && (opnd->imm.value ==
2513 1.1.1.1.8.2 tls (int64_t) get_optional_operand_default_value (opcode)))
2514 1.1.1.1.8.2 tls /* Omit the operand, e.g. DCPS1. */
2515 1.1.1.1.8.2 tls break;
2516 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
2517 1.1.1.1.8.2 tls break;
2518 1.1.1.1.8.2 tls
2519 1.1.1.1.8.2 tls case AARCH64_OPND_COND:
2520 1.1.1.1.8.2 tls snprintf (buf, size, "%s", opnd->cond->names[0]);
2521 1.1.1.1.8.2 tls break;
2522 1.1.1.1.8.2 tls
2523 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_ADRP:
2524 1.1.1.1.8.2 tls addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
2525 1.1.1.1.8.2 tls + opnd->imm.value;
2526 1.1.1.1.8.2 tls if (pcrel_p)
2527 1.1.1.1.8.2 tls *pcrel_p = 1;
2528 1.1.1.1.8.2 tls if (address)
2529 1.1.1.1.8.2 tls *address = addr;
2530 1.1.1.1.8.2 tls /* This is not necessary during the disassembling, as print_address_func
2531 1.1.1.1.8.2 tls in the disassemble_info will take care of the printing. But some
2532 1.1.1.1.8.2 tls other callers may be still interested in getting the string in *STR,
2533 1.1.1.1.8.2 tls so here we do snprintf regardless. */
2534 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64, addr);
2535 1.1.1.1.8.2 tls break;
2536 1.1.1.1.8.2 tls
2537 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL14:
2538 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL19:
2539 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL21:
2540 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_PCREL26:
2541 1.1.1.1.8.2 tls addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
2542 1.1.1.1.8.2 tls if (pcrel_p)
2543 1.1.1.1.8.2 tls *pcrel_p = 1;
2544 1.1.1.1.8.2 tls if (address)
2545 1.1.1.1.8.2 tls *address = addr;
2546 1.1.1.1.8.2 tls /* This is not necessary during the disassembling, as print_address_func
2547 1.1.1.1.8.2 tls in the disassemble_info will take care of the printing. But some
2548 1.1.1.1.8.2 tls other callers may be still interested in getting the string in *STR,
2549 1.1.1.1.8.2 tls so here we do snprintf regardless. */
2550 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%" PRIx64, addr);
2551 1.1.1.1.8.2 tls break;
2552 1.1.1.1.8.2 tls
2553 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMPLE:
2554 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_ADDR_SIMPLE:
2555 1.1.1.1.8.2 tls case AARCH64_OPND_SIMD_ADDR_POST:
2556 1.1.1.1.8.2 tls name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2557 1.1.1.1.8.2 tls if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
2558 1.1.1.1.8.2 tls {
2559 1.1.1.1.8.2 tls if (opnd->addr.offset.is_reg)
2560 1.1.1.1.8.2 tls snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
2561 1.1.1.1.8.2 tls else
2562 1.1.1.1.8.2 tls snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
2563 1.1.1.1.8.2 tls }
2564 1.1.1.1.8.2 tls else
2565 1.1.1.1.8.2 tls snprintf (buf, size, "[%s]", name);
2566 1.1.1.1.8.2 tls break;
2567 1.1.1.1.8.2 tls
2568 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_REGOFF:
2569 1.1.1.1.8.2 tls print_register_offset_address (buf, size, opnd);
2570 1.1.1.1.8.2 tls break;
2571 1.1.1.1.8.2 tls
2572 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM7:
2573 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM9:
2574 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_SIMM9_2:
2575 1.1.1.1.8.2 tls name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2576 1.1.1.1.8.2 tls if (opnd->addr.writeback)
2577 1.1.1.1.8.2 tls {
2578 1.1.1.1.8.2 tls if (opnd->addr.preind)
2579 1.1.1.1.8.2 tls snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
2580 1.1.1.1.8.2 tls else
2581 1.1.1.1.8.2 tls snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
2582 1.1.1.1.8.2 tls }
2583 1.1.1.1.8.2 tls else
2584 1.1.1.1.8.2 tls {
2585 1.1.1.1.8.2 tls if (opnd->addr.offset.imm)
2586 1.1.1.1.8.2 tls snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2587 1.1.1.1.8.2 tls else
2588 1.1.1.1.8.2 tls snprintf (buf, size, "[%s]", name);
2589 1.1.1.1.8.2 tls }
2590 1.1.1.1.8.2 tls break;
2591 1.1.1.1.8.2 tls
2592 1.1.1.1.8.2 tls case AARCH64_OPND_ADDR_UIMM12:
2593 1.1.1.1.8.2 tls name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2594 1.1.1.1.8.2 tls if (opnd->addr.offset.imm)
2595 1.1.1.1.8.2 tls snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2596 1.1.1.1.8.2 tls else
2597 1.1.1.1.8.2 tls snprintf (buf, size, "[%s]", name);
2598 1.1.1.1.8.2 tls break;
2599 1.1.1.1.8.2 tls
2600 1.1.1.1.8.2 tls case AARCH64_OPND_SYSREG:
2601 1.1.1.1.8.2 tls for (i = 0; aarch64_sys_regs[i].name; ++i)
2602 1.1.1.1.8.2 tls if (aarch64_sys_regs[i].value == opnd->sysreg)
2603 1.1.1.1.8.2 tls break;
2604 1.1.1.1.8.2 tls if (aarch64_sys_regs[i].name)
2605 1.1.1.1.8.2 tls snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
2606 1.1.1.1.8.2 tls else
2607 1.1.1.1.8.2 tls {
2608 1.1.1.1.8.2 tls /* Implementation defined system register. */
2609 1.1.1.1.8.2 tls unsigned int value = opnd->sysreg;
2610 1.1.1.1.8.2 tls snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
2611 1.1.1.1.8.2 tls (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
2612 1.1.1.1.8.2 tls value & 0x7);
2613 1.1.1.1.8.2 tls }
2614 1.1.1.1.8.2 tls break;
2615 1.1.1.1.8.2 tls
2616 1.1.1.1.8.2 tls case AARCH64_OPND_PSTATEFIELD:
2617 1.1.1.1.8.2 tls for (i = 0; aarch64_pstatefields[i].name; ++i)
2618 1.1.1.1.8.2 tls if (aarch64_pstatefields[i].value == opnd->pstatefield)
2619 1.1.1.1.8.2 tls break;
2620 1.1.1.1.8.2 tls assert (aarch64_pstatefields[i].name);
2621 1.1.1.1.8.2 tls snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
2622 1.1.1.1.8.2 tls break;
2623 1.1.1.1.8.2 tls
2624 1.1.1.1.8.2 tls case AARCH64_OPND_SYSREG_AT:
2625 1.1.1.1.8.2 tls case AARCH64_OPND_SYSREG_DC:
2626 1.1.1.1.8.2 tls case AARCH64_OPND_SYSREG_IC:
2627 1.1.1.1.8.2 tls case AARCH64_OPND_SYSREG_TLBI:
2628 1.1.1.1.8.2 tls snprintf (buf, size, "%s", opnd->sysins_op->template);
2629 1.1.1.1.8.2 tls break;
2630 1.1.1.1.8.2 tls
2631 1.1.1.1.8.2 tls case AARCH64_OPND_BARRIER:
2632 1.1.1.1.8.2 tls snprintf (buf, size, "%s", opnd->barrier->name);
2633 1.1.1.1.8.2 tls break;
2634 1.1.1.1.8.2 tls
2635 1.1.1.1.8.2 tls case AARCH64_OPND_BARRIER_ISB:
2636 1.1.1.1.8.2 tls /* Operand can be omitted, e.g. in DCPS1. */
2637 1.1.1.1.8.2 tls if (! optional_operand_p (opcode, idx)
2638 1.1.1.1.8.2 tls || (opnd->barrier->value
2639 1.1.1.1.8.2 tls != get_optional_operand_default_value (opcode)))
2640 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%x", opnd->barrier->value);
2641 1.1.1.1.8.2 tls break;
2642 1.1.1.1.8.2 tls
2643 1.1.1.1.8.2 tls case AARCH64_OPND_PRFOP:
2644 1.1.1.1.8.2 tls if (opnd->prfop->name != NULL)
2645 1.1.1.1.8.2 tls snprintf (buf, size, "%s", opnd->prfop->name);
2646 1.1.1.1.8.2 tls else
2647 1.1.1.1.8.2 tls snprintf (buf, size, "#0x%02x", opnd->prfop->value);
2648 1.1.1.1.8.2 tls break;
2649 1.1.1.1.8.2 tls
2650 1.1.1.1.8.2 tls default:
2651 1.1.1.1.8.2 tls assert (0);
2652 1.1.1.1.8.2 tls }
2653 1.1.1.1.8.2 tls }
2654 1.1.1.1.8.2 tls
2655 1.1.1.1.8.2 tls #define CPENC(op0,op1,crn,crm,op2) \
2657 1.1.1.1.8.2 tls ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
2658 1.1.1.1.8.2 tls /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
2659 1.1.1.1.8.2 tls #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
2660 1.1.1.1.8.2 tls /* for 3.9.10 System Instructions */
2661 1.1.1.1.8.2 tls #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
2662 1.1.1.1.8.2 tls
2663 1.1.1.1.8.2 tls #define C0 0
2664 1.1.1.1.8.2 tls #define C1 1
2665 1.1.1.1.8.2 tls #define C2 2
2666 1.1.1.1.8.2 tls #define C3 3
2667 1.1.1.1.8.2 tls #define C4 4
2668 1.1.1.1.8.2 tls #define C5 5
2669 1.1.1.1.8.2 tls #define C6 6
2670 1.1.1.1.8.2 tls #define C7 7
2671 1.1.1.1.8.2 tls #define C8 8
2672 1.1.1.1.8.2 tls #define C9 9
2673 1.1.1.1.8.2 tls #define C10 10
2674 1.1.1.1.8.2 tls #define C11 11
2675 1.1.1.1.8.2 tls #define C12 12
2676 1.1.1.1.8.2 tls #define C13 13
2677 1.1.1.1.8.2 tls #define C14 14
2678 1.1.1.1.8.2 tls #define C15 15
2679 1.1.1.1.8.2 tls
2680 1.1.1.1.8.2 tls /* TODO there are two more issues need to be resolved
2681 1.1.1.1.8.2 tls 1. handle read-only and write-only system registers
2682 1.1.1.1.8.2 tls 2. handle cpu-implementation-defined system registers. */
2683 1.1.1.1.8.2 tls const struct aarch64_name_value_pair aarch64_sys_regs [] =
2684 1.1.1.1.8.2 tls {
2685 1.1.1.1.8.2 tls { "spsr_el1", CPEN_(0,C0,0) }, /* = spsr_svc */
2686 1.1.1.1.8.2 tls { "elr_el1", CPEN_(0,C0,1) },
2687 1.1.1.1.8.2 tls { "sp_el0", CPEN_(0,C1,0) },
2688 1.1.1.1.8.2 tls { "spsel", CPEN_(0,C2,0) },
2689 1.1.1.1.8.2 tls { "daif", CPEN_(3,C2,1) },
2690 1.1.1.1.8.2 tls { "currentel", CPEN_(0,C2,2) }, /* RO */
2691 1.1.1.1.8.2 tls { "nzcv", CPEN_(3,C2,0) },
2692 1.1.1.1.8.2 tls { "fpcr", CPEN_(3,C4,0) },
2693 1.1.1.1.8.2 tls { "fpsr", CPEN_(3,C4,1) },
2694 1.1.1.1.8.2 tls { "dspsr_el0", CPEN_(3,C5,0) },
2695 1.1.1.1.8.2 tls { "dlr_el0", CPEN_(3,C5,1) },
2696 1.1.1.1.8.2 tls { "spsr_el2", CPEN_(4,C0,0) }, /* = spsr_hyp */
2697 1.1.1.1.8.2 tls { "elr_el2", CPEN_(4,C0,1) },
2698 1.1.1.1.8.2 tls { "sp_el1", CPEN_(4,C1,0) },
2699 1.1.1.1.8.2 tls { "spsr_irq", CPEN_(4,C3,0) },
2700 1.1.1.1.8.2 tls { "spsr_abt", CPEN_(4,C3,1) },
2701 1.1.1.1.8.2 tls { "spsr_und", CPEN_(4,C3,2) },
2702 1.1.1.1.8.2 tls { "spsr_fiq", CPEN_(4,C3,3) },
2703 1.1.1.1.8.2 tls { "spsr_el3", CPEN_(6,C0,0) },
2704 1.1.1.1.8.2 tls { "elr_el3", CPEN_(6,C0,1) },
2705 1.1.1.1.8.2 tls { "sp_el2", CPEN_(6,C1,0) },
2706 1.1.1.1.8.2 tls { "spsr_svc", CPEN_(0,C0,0) }, /* = spsr_el1 */
2707 1.1.1.1.8.2 tls { "spsr_hyp", CPEN_(4,C0,0) }, /* = spsr_el2 */
2708 1.1.1.1.8.2 tls { "midr_el1", CPENC(3,0,C0,C0,0) }, /* RO */
2709 1.1.1.1.8.2 tls { "ctr_el0", CPENC(3,3,C0,C0,1) }, /* RO */
2710 1.1.1.1.8.2 tls { "mpidr_el1", CPENC(3,0,C0,C0,5) }, /* RO */
2711 1.1.1.1.8.2 tls { "revidr_el1", CPENC(3,0,C0,C0,6) }, /* RO */
2712 1.1.1.1.8.2 tls { "aidr_el1", CPENC(3,1,C0,C0,7) }, /* RO */
2713 1.1.1.1.8.2 tls { "dczid_el0", CPENC(3,3,C0,C0,7) }, /* RO */
2714 1.1.1.1.8.2 tls { "id_dfr0_el1", CPENC(3,0,C0,C1,2) }, /* RO */
2715 1.1.1.1.8.2 tls { "id_pfr0_el1", CPENC(3,0,C0,C1,0) }, /* RO */
2716 1.1.1.1.8.2 tls { "id_pfr1_el1", CPENC(3,0,C0,C1,1) }, /* RO */
2717 1.1.1.1.8.2 tls { "id_afr0_el1", CPENC(3,0,C0,C1,3) }, /* RO */
2718 1.1.1.1.8.2 tls { "id_mmfr0_el1", CPENC(3,0,C0,C1,4) }, /* RO */
2719 1.1.1.1.8.2 tls { "id_mmfr1_el1", CPENC(3,0,C0,C1,5) }, /* RO */
2720 1.1.1.1.8.2 tls { "id_mmfr2_el1", CPENC(3,0,C0,C1,6) }, /* RO */
2721 1.1.1.1.8.2 tls { "id_mmfr3_el1", CPENC(3,0,C0,C1,7) }, /* RO */
2722 1.1.1.1.8.2 tls { "id_isar0_el1", CPENC(3,0,C0,C2,0) }, /* RO */
2723 1.1.1.1.8.2 tls { "id_isar1_el1", CPENC(3,0,C0,C2,1) }, /* RO */
2724 1.1.1.1.8.2 tls { "id_isar2_el1", CPENC(3,0,C0,C2,2) }, /* RO */
2725 1.1.1.1.8.2 tls { "id_isar3_el1", CPENC(3,0,C0,C2,3) }, /* RO */
2726 1.1.1.1.8.2 tls { "id_isar4_el1", CPENC(3,0,C0,C2,4) }, /* RO */
2727 1.1.1.1.8.2 tls { "id_isar5_el1", CPENC(3,0,C0,C2,5) }, /* RO */
2728 1.1.1.1.8.2 tls { "mvfr0_el1", CPENC(3,0,C0,C3,0) }, /* RO */
2729 1.1.1.1.8.2 tls { "mvfr1_el1", CPENC(3,0,C0,C3,1) }, /* RO */
2730 1.1.1.1.8.2 tls { "mvfr2_el1", CPENC(3,0,C0,C3,2) }, /* RO */
2731 1.1.1.1.8.2 tls { "ccsidr_el1", CPENC(3,1,C0,C0,0) }, /* RO */
2732 1.1.1.1.8.2 tls { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0) }, /* RO */
2733 1.1.1.1.8.2 tls { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1) }, /* RO */
2734 1.1.1.1.8.2 tls { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0) }, /* RO */
2735 1.1.1.1.8.2 tls { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1) }, /* RO */
2736 1.1.1.1.8.2 tls { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0) }, /* RO */
2737 1.1.1.1.8.2 tls { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1) }, /* RO */
2738 1.1.1.1.8.2 tls { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0) }, /* RO */
2739 1.1.1.1.8.2 tls { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1) }, /* RO */
2740 1.1.1.1.8.2 tls { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4) }, /* RO */
2741 1.1.1.1.8.2 tls { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5) }, /* RO */
2742 1.1.1.1.8.2 tls { "clidr_el1", CPENC(3,1,C0,C0,1) }, /* RO */
2743 1.1.1.1.8.2 tls { "csselr_el1", CPENC(3,2,C0,C0,0) }, /* RO */
2744 1.1.1.1.8.2 tls { "vpidr_el2", CPENC(3,4,C0,C0,0) },
2745 1.1.1.1.8.2 tls { "vmpidr_el2", CPENC(3,4,C0,C0,5) },
2746 1.1.1.1.8.2 tls { "sctlr_el1", CPENC(3,0,C1,C0,0) },
2747 1.1.1.1.8.2 tls { "sctlr_el2", CPENC(3,4,C1,C0,0) },
2748 1.1.1.1.8.2 tls { "sctlr_el3", CPENC(3,6,C1,C0,0) },
2749 1.1.1.1.8.2 tls { "actlr_el1", CPENC(3,0,C1,C0,1) },
2750 1.1.1.1.8.2 tls { "actlr_el2", CPENC(3,4,C1,C0,1) },
2751 1.1.1.1.8.2 tls { "actlr_el3", CPENC(3,6,C1,C0,1) },
2752 1.1.1.1.8.2 tls { "cpacr_el1", CPENC(3,0,C1,C0,2) },
2753 1.1.1.1.8.2 tls { "cptr_el2", CPENC(3,4,C1,C1,2) },
2754 1.1.1.1.8.2 tls { "cptr_el3", CPENC(3,6,C1,C1,2) },
2755 1.1.1.1.8.2 tls { "scr_el3", CPENC(3,6,C1,C1,0) },
2756 1.1.1.1.8.2 tls { "hcr_el2", CPENC(3,4,C1,C1,0) },
2757 1.1.1.1.8.2 tls { "mdcr_el2", CPENC(3,4,C1,C1,1) },
2758 1.1.1.1.8.2 tls { "mdcr_el3", CPENC(3,6,C1,C3,1) },
2759 1.1.1.1.8.2 tls { "hstr_el2", CPENC(3,4,C1,C1,3) },
2760 1.1.1.1.8.2 tls { "hacr_el2", CPENC(3,4,C1,C1,7) },
2761 1.1.1.1.8.2 tls { "ttbr0_el1", CPENC(3,0,C2,C0,0) },
2762 1.1.1.1.8.2 tls { "ttbr1_el1", CPENC(3,0,C2,C0,1) },
2763 1.1.1.1.8.2 tls { "ttbr0_el2", CPENC(3,4,C2,C0,0) },
2764 1.1.1.1.8.2 tls { "ttbr0_el3", CPENC(3,6,C2,C0,0) },
2765 1.1.1.1.8.2 tls { "vttbr_el2", CPENC(3,4,C2,C1,0) },
2766 1.1.1.1.8.2 tls { "tcr_el1", CPENC(3,0,C2,C0,2) },
2767 1.1.1.1.8.2 tls { "tcr_el2", CPENC(3,4,C2,C0,2) },
2768 1.1.1.1.8.2 tls { "tcr_el3", CPENC(3,6,C2,C0,2) },
2769 1.1.1.1.8.2 tls { "vtcr_el2", CPENC(3,4,C2,C1,2) },
2770 1.1.1.1.8.2 tls { "afsr0_el1", CPENC(3,0,C5,C1,0) },
2771 1.1.1.1.8.2 tls { "afsr1_el1", CPENC(3,0,C5,C1,1) },
2772 1.1.1.1.8.2 tls { "afsr0_el2", CPENC(3,4,C5,C1,0) },
2773 1.1.1.1.8.2 tls { "afsr1_el2", CPENC(3,4,C5,C1,1) },
2774 1.1.1.1.8.2 tls { "afsr0_el3", CPENC(3,6,C5,C1,0) },
2775 1.1.1.1.8.2 tls { "afsr1_el3", CPENC(3,6,C5,C1,1) },
2776 1.1.1.1.8.2 tls { "esr_el1", CPENC(3,0,C5,C2,0) },
2777 1.1.1.1.8.2 tls { "esr_el2", CPENC(3,4,C5,C2,0) },
2778 1.1.1.1.8.2 tls { "esr_el3", CPENC(3,6,C5,C2,0) },
2779 1.1.1.1.8.2 tls { "fpexc32_el2", CPENC(3,4,C5,C3,0) },
2780 1.1.1.1.8.2 tls { "far_el1", CPENC(3,0,C6,C0,0) },
2781 1.1.1.1.8.2 tls { "far_el2", CPENC(3,4,C6,C0,0) },
2782 1.1.1.1.8.2 tls { "far_el3", CPENC(3,6,C6,C0,0) },
2783 1.1.1.1.8.2 tls { "hpfar_el2", CPENC(3,4,C6,C0,4) },
2784 1.1.1.1.8.2 tls { "par_el1", CPENC(3,0,C7,C4,0) },
2785 1.1.1.1.8.2 tls { "mair_el1", CPENC(3,0,C10,C2,0) },
2786 1.1.1.1.8.2 tls { "mair_el2", CPENC(3,4,C10,C2,0) },
2787 1.1.1.1.8.2 tls { "mair_el3", CPENC(3,6,C10,C2,0) },
2788 1.1.1.1.8.2 tls { "amair_el1", CPENC(3,0,C10,C3,0) },
2789 1.1.1.1.8.2 tls { "amair_el2", CPENC(3,4,C10,C3,0) },
2790 1.1.1.1.8.2 tls { "amair_el3", CPENC(3,6,C10,C3,0) },
2791 1.1.1.1.8.2 tls { "vbar_el1", CPENC(3,0,C12,C0,0) },
2792 1.1.1.1.8.2 tls { "vbar_el2", CPENC(3,4,C12,C0,0) },
2793 1.1.1.1.8.2 tls { "vbar_el3", CPENC(3,6,C12,C0,0) },
2794 1.1.1.1.8.2 tls { "rvbar_el1", CPENC(3,0,C12,C0,1) }, /* RO */
2795 1.1.1.1.8.2 tls { "rvbar_el2", CPENC(3,4,C12,C0,1) }, /* RO */
2796 1.1.1.1.8.2 tls { "rvbar_el3", CPENC(3,6,C12,C0,1) }, /* RO */
2797 1.1.1.1.8.2 tls { "rmr_el1", CPENC(3,0,C12,C0,2) },
2798 1.1.1.1.8.2 tls { "rmr_el2", CPENC(3,4,C12,C0,2) },
2799 1.1.1.1.8.2 tls { "rmr_el3", CPENC(3,6,C12,C0,2) },
2800 1.1.1.1.8.2 tls { "isr_el1", CPENC(3,0,C12,C1,0) }, /* RO */
2801 1.1.1.1.8.2 tls { "contextidr_el1", CPENC(3,0,C13,C0,1) },
2802 1.1.1.1.8.2 tls { "tpidr_el0", CPENC(3,3,C13,C0,2) },
2803 1.1.1.1.8.2 tls { "tpidrro_el0", CPENC(3,3,C13,C0,3) }, /* RO */
2804 1.1.1.1.8.2 tls { "tpidr_el1", CPENC(3,0,C13,C0,4) },
2805 1.1.1.1.8.2 tls { "tpidr_el2", CPENC(3,4,C13,C0,2) },
2806 1.1.1.1.8.2 tls { "tpidr_el3", CPENC(3,6,C13,C0,2) },
2807 1.1.1.1.8.2 tls { "teecr32_el1", CPENC(2,2,C0, C0,0) }, /* See section 3.9.7.1 */
2808 1.1.1.1.8.2 tls { "cntfrq_el0", CPENC(3,3,C14,C0,0) }, /* RO */
2809 1.1.1.1.8.2 tls { "cntpct_el0", CPENC(3,3,C14,C0,1) }, /* RO */
2810 1.1.1.1.8.2 tls { "cntvct_el0", CPENC(3,3,C14,C0,2) }, /* RO */
2811 1.1.1.1.8.2 tls { "cntvoff_el2", CPENC(3,4,C14,C0,3) },
2812 1.1.1.1.8.2 tls { "cntkctl_el1", CPENC(3,0,C14,C1,0) },
2813 1.1.1.1.8.2 tls { "cnthctl_el2", CPENC(3,4,C14,C1,0) },
2814 1.1.1.1.8.2 tls { "cntp_tval_el0", CPENC(3,3,C14,C2,0) },
2815 1.1.1.1.8.2 tls { "cntp_ctl_el0", CPENC(3,3,C14,C2,1) },
2816 1.1.1.1.8.2 tls { "cntp_cval_el0", CPENC(3,3,C14,C2,2) },
2817 1.1.1.1.8.2 tls { "cntv_tval_el0", CPENC(3,3,C14,C3,0) },
2818 1.1.1.1.8.2 tls { "cntv_ctl_el0", CPENC(3,3,C14,C3,1) },
2819 1.1.1.1.8.2 tls { "cntv_cval_el0", CPENC(3,3,C14,C3,2) },
2820 1.1.1.1.8.2 tls { "cnthp_tval_el2", CPENC(3,4,C14,C2,0) },
2821 1.1.1.1.8.2 tls { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1) },
2822 1.1.1.1.8.2 tls { "cnthp_cval_el2", CPENC(3,4,C14,C2,2) },
2823 1.1.1.1.8.2 tls { "cntps_tval_el1", CPENC(3,7,C14,C2,0) },
2824 1.1.1.1.8.2 tls { "cntps_ctl_el1", CPENC(3,7,C14,C2,1) },
2825 1.1.1.1.8.2 tls { "cntps_cval_el1", CPENC(3,7,C14,C2,2) },
2826 1.1.1.1.8.2 tls { "dacr32_el2", CPENC(3,4,C3,C0,0) },
2827 1.1.1.1.8.2 tls { "ifsr32_el2", CPENC(3,4,C5,C0,1) },
2828 1.1.1.1.8.2 tls { "teehbr32_el1", CPENC(2,2,C1,C0,0) },
2829 1.1.1.1.8.2 tls { "sder32_el3", CPENC(3,6,C1,C1,1) },
2830 1.1.1.1.8.2 tls { "mdscr_el1", CPENC(2,0,C0, C2, 2) },
2831 1.1.1.1.8.2 tls { "mdccsr_el0", CPENC(2,3,C0, C1, 0) }, /* r */
2832 1.1.1.1.8.2 tls { "mdccint_el1", CPENC(2,0,C0, C2, 0) },
2833 1.1.1.1.8.2 tls { "dbgdtr_el0", CPENC(2,3,C0, C4, 0) },
2834 1.1.1.1.8.2 tls { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0) }, /* r */
2835 1.1.1.1.8.2 tls { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0) }, /* w */
2836 1.1.1.1.8.2 tls { "osdtrrx_el1", CPENC(2,0,C0, C0, 2) }, /* r */
2837 1.1.1.1.8.2 tls { "osdtrtx_el1", CPENC(2,0,C0, C3, 2) }, /* w */
2838 1.1.1.1.8.2 tls { "oseccr_el1", CPENC(2,0,C0, C6, 2) },
2839 1.1.1.1.8.2 tls { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0) },
2840 1.1.1.1.8.2 tls { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4) },
2841 1.1.1.1.8.2 tls { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4) },
2842 1.1.1.1.8.2 tls { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4) },
2843 1.1.1.1.8.2 tls { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4) },
2844 1.1.1.1.8.2 tls { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4) },
2845 1.1.1.1.8.2 tls { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4) },
2846 1.1.1.1.8.2 tls { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4) },
2847 1.1.1.1.8.2 tls { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4) },
2848 1.1.1.1.8.2 tls { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4) },
2849 1.1.1.1.8.2 tls { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4) },
2850 1.1.1.1.8.2 tls { "dbgbvr10_el1", CPENC(2,0,C0, C10,4) },
2851 1.1.1.1.8.2 tls { "dbgbvr11_el1", CPENC(2,0,C0, C11,4) },
2852 1.1.1.1.8.2 tls { "dbgbvr12_el1", CPENC(2,0,C0, C12,4) },
2853 1.1.1.1.8.2 tls { "dbgbvr13_el1", CPENC(2,0,C0, C13,4) },
2854 1.1.1.1.8.2 tls { "dbgbvr14_el1", CPENC(2,0,C0, C14,4) },
2855 1.1.1.1.8.2 tls { "dbgbvr15_el1", CPENC(2,0,C0, C15,4) },
2856 1.1.1.1.8.2 tls { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5) },
2857 1.1.1.1.8.2 tls { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5) },
2858 1.1.1.1.8.2 tls { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5) },
2859 1.1.1.1.8.2 tls { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5) },
2860 1.1.1.1.8.2 tls { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5) },
2861 1.1.1.1.8.2 tls { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5) },
2862 1.1.1.1.8.2 tls { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5) },
2863 1.1.1.1.8.2 tls { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5) },
2864 1.1.1.1.8.2 tls { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5) },
2865 1.1.1.1.8.2 tls { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5) },
2866 1.1.1.1.8.2 tls { "dbgbcr10_el1", CPENC(2,0,C0, C10,5) },
2867 1.1.1.1.8.2 tls { "dbgbcr11_el1", CPENC(2,0,C0, C11,5) },
2868 1.1.1.1.8.2 tls { "dbgbcr12_el1", CPENC(2,0,C0, C12,5) },
2869 1.1.1.1.8.2 tls { "dbgbcr13_el1", CPENC(2,0,C0, C13,5) },
2870 1.1.1.1.8.2 tls { "dbgbcr14_el1", CPENC(2,0,C0, C14,5) },
2871 1.1.1.1.8.2 tls { "dbgbcr15_el1", CPENC(2,0,C0, C15,5) },
2872 1.1.1.1.8.2 tls { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6) },
2873 1.1.1.1.8.2 tls { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6) },
2874 1.1.1.1.8.2 tls { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6) },
2875 1.1.1.1.8.2 tls { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6) },
2876 1.1.1.1.8.2 tls { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6) },
2877 1.1.1.1.8.2 tls { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6) },
2878 1.1.1.1.8.2 tls { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6) },
2879 1.1.1.1.8.2 tls { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6) },
2880 1.1.1.1.8.2 tls { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6) },
2881 1.1.1.1.8.2 tls { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6) },
2882 1.1.1.1.8.2 tls { "dbgwvr10_el1", CPENC(2,0,C0, C10,6) },
2883 1.1.1.1.8.2 tls { "dbgwvr11_el1", CPENC(2,0,C0, C11,6) },
2884 1.1.1.1.8.2 tls { "dbgwvr12_el1", CPENC(2,0,C0, C12,6) },
2885 1.1.1.1.8.2 tls { "dbgwvr13_el1", CPENC(2,0,C0, C13,6) },
2886 1.1.1.1.8.2 tls { "dbgwvr14_el1", CPENC(2,0,C0, C14,6) },
2887 1.1.1.1.8.2 tls { "dbgwvr15_el1", CPENC(2,0,C0, C15,6) },
2888 1.1.1.1.8.2 tls { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7) },
2889 1.1.1.1.8.2 tls { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7) },
2890 1.1.1.1.8.2 tls { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7) },
2891 1.1.1.1.8.2 tls { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7) },
2892 1.1.1.1.8.2 tls { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7) },
2893 1.1.1.1.8.2 tls { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7) },
2894 1.1.1.1.8.2 tls { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7) },
2895 1.1.1.1.8.2 tls { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7) },
2896 1.1.1.1.8.2 tls { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7) },
2897 1.1.1.1.8.2 tls { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7) },
2898 1.1.1.1.8.2 tls { "dbgwcr10_el1", CPENC(2,0,C0, C10,7) },
2899 1.1.1.1.8.2 tls { "dbgwcr11_el1", CPENC(2,0,C0, C11,7) },
2900 1.1.1.1.8.2 tls { "dbgwcr12_el1", CPENC(2,0,C0, C12,7) },
2901 1.1.1.1.8.2 tls { "dbgwcr13_el1", CPENC(2,0,C0, C13,7) },
2902 1.1.1.1.8.2 tls { "dbgwcr14_el1", CPENC(2,0,C0, C14,7) },
2903 1.1.1.1.8.2 tls { "dbgwcr15_el1", CPENC(2,0,C0, C15,7) },
2904 1.1.1.1.8.2 tls { "mdrar_el1", CPENC(2,0,C1, C0, 0) }, /* r */
2905 1.1.1.1.8.2 tls { "oslar_el1", CPENC(2,0,C1, C0, 4) }, /* w */
2906 1.1.1.1.8.2 tls { "oslsr_el1", CPENC(2,0,C1, C1, 4) }, /* r */
2907 1.1.1.1.8.2 tls { "osdlr_el1", CPENC(2,0,C1, C3, 4) },
2908 1.1.1.1.8.2 tls { "dbgprcr_el1", CPENC(2,0,C1, C4, 4) },
2909 1.1.1.1.8.2 tls { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6) },
2910 1.1.1.1.8.2 tls { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6) },
2911 1.1.1.1.8.2 tls { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6) }, /* r */
2912 1.1.1.1.8.2 tls
2913 1.1.1.1.8.2 tls { "pmcr_el0", CPENC(3,3,C9,C12, 0) },
2914 1.1.1.1.8.2 tls { "pmcntenset_el0", CPENC(3,3,C9,C12, 1) },
2915 1.1.1.1.8.2 tls { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2) },
2916 1.1.1.1.8.2 tls { "pmovsclr_el0", CPENC(3,3,C9,C12, 3) },
2917 1.1.1.1.8.2 tls { "pmswinc_el0", CPENC(3,3,C9,C12, 4) }, /* w */
2918 1.1.1.1.8.2 tls { "pmselr_el0", CPENC(3,3,C9,C12, 5) },
2919 1.1.1.1.8.2 tls { "pmceid0_el0", CPENC(3,3,C9,C12, 6) }, /* r */
2920 1.1.1.1.8.2 tls { "pmceid1_el0", CPENC(3,3,C9,C12, 7) }, /* r */
2921 1.1.1.1.8.2 tls { "pmccntr_el0", CPENC(3,3,C9,C13, 0) },
2922 1.1.1.1.8.2 tls { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1) },
2923 1.1.1.1.8.2 tls { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2) },
2924 1.1.1.1.8.2 tls { "pmuserenr_el0", CPENC(3,3,C9,C14, 0) },
2925 1.1.1.1.8.2 tls { "pmintenset_el1", CPENC(3,0,C9,C14, 1) },
2926 1.1.1.1.8.2 tls { "pmintenclr_el1", CPENC(3,0,C9,C14, 2) },
2927 1.1.1.1.8.2 tls { "pmovsset_el0", CPENC(3,3,C9,C14, 3) },
2928 1.1.1.1.8.2 tls { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0) },
2929 1.1.1.1.8.2 tls { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1) },
2930 1.1.1.1.8.2 tls { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2) },
2931 1.1.1.1.8.2 tls { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3) },
2932 1.1.1.1.8.2 tls { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4) },
2933 1.1.1.1.8.2 tls { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5) },
2934 1.1.1.1.8.2 tls { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6) },
2935 1.1.1.1.8.2 tls { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7) },
2936 1.1.1.1.8.2 tls { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0) },
2937 1.1.1.1.8.2 tls { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1) },
2938 1.1.1.1.8.2 tls { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2) },
2939 1.1.1.1.8.2 tls { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3) },
2940 1.1.1.1.8.2 tls { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4) },
2941 1.1.1.1.8.2 tls { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5) },
2942 1.1.1.1.8.2 tls { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6) },
2943 1.1.1.1.8.2 tls { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7) },
2944 1.1.1.1.8.2 tls { "pmevcntr16_el0", CPENC(3,3,C14,C10,0) },
2945 1.1.1.1.8.2 tls { "pmevcntr17_el0", CPENC(3,3,C14,C10,1) },
2946 1.1.1.1.8.2 tls { "pmevcntr18_el0", CPENC(3,3,C14,C10,2) },
2947 1.1.1.1.8.2 tls { "pmevcntr19_el0", CPENC(3,3,C14,C10,3) },
2948 1.1.1.1.8.2 tls { "pmevcntr20_el0", CPENC(3,3,C14,C10,4) },
2949 1.1.1.1.8.2 tls { "pmevcntr21_el0", CPENC(3,3,C14,C10,5) },
2950 1.1.1.1.8.2 tls { "pmevcntr22_el0", CPENC(3,3,C14,C10,6) },
2951 1.1.1.1.8.2 tls { "pmevcntr23_el0", CPENC(3,3,C14,C10,7) },
2952 1.1.1.1.8.2 tls { "pmevcntr24_el0", CPENC(3,3,C14,C11,0) },
2953 1.1.1.1.8.2 tls { "pmevcntr25_el0", CPENC(3,3,C14,C11,1) },
2954 1.1.1.1.8.2 tls { "pmevcntr26_el0", CPENC(3,3,C14,C11,2) },
2955 1.1.1.1.8.2 tls { "pmevcntr27_el0", CPENC(3,3,C14,C11,3) },
2956 1.1.1.1.8.2 tls { "pmevcntr28_el0", CPENC(3,3,C14,C11,4) },
2957 1.1.1.1.8.2 tls { "pmevcntr29_el0", CPENC(3,3,C14,C11,5) },
2958 1.1.1.1.8.2 tls { "pmevcntr30_el0", CPENC(3,3,C14,C11,6) },
2959 1.1.1.1.8.2 tls { "pmevtyper0_el0", CPENC(3,3,C14,C12,0) },
2960 1.1.1.1.8.2 tls { "pmevtyper1_el0", CPENC(3,3,C14,C12,1) },
2961 1.1.1.1.8.2 tls { "pmevtyper2_el0", CPENC(3,3,C14,C12,2) },
2962 1.1.1.1.8.2 tls { "pmevtyper3_el0", CPENC(3,3,C14,C12,3) },
2963 1.1.1.1.8.2 tls { "pmevtyper4_el0", CPENC(3,3,C14,C12,4) },
2964 1.1.1.1.8.2 tls { "pmevtyper5_el0", CPENC(3,3,C14,C12,5) },
2965 1.1.1.1.8.2 tls { "pmevtyper6_el0", CPENC(3,3,C14,C12,6) },
2966 1.1.1.1.8.2 tls { "pmevtyper7_el0", CPENC(3,3,C14,C12,7) },
2967 1.1.1.1.8.2 tls { "pmevtyper8_el0", CPENC(3,3,C14,C13,0) },
2968 1.1.1.1.8.2 tls { "pmevtyper9_el0", CPENC(3,3,C14,C13,1) },
2969 1.1.1.1.8.2 tls { "pmevtyper10_el0", CPENC(3,3,C14,C13,2) },
2970 1.1.1.1.8.2 tls { "pmevtyper11_el0", CPENC(3,3,C14,C13,3) },
2971 1.1.1.1.8.2 tls { "pmevtyper12_el0", CPENC(3,3,C14,C13,4) },
2972 1.1.1.1.8.2 tls { "pmevtyper13_el0", CPENC(3,3,C14,C13,5) },
2973 1.1.1.1.8.2 tls { "pmevtyper14_el0", CPENC(3,3,C14,C13,6) },
2974 1.1.1.1.8.2 tls { "pmevtyper15_el0", CPENC(3,3,C14,C13,7) },
2975 1.1.1.1.8.2 tls { "pmevtyper16_el0", CPENC(3,3,C14,C14,0) },
2976 1.1.1.1.8.2 tls { "pmevtyper17_el0", CPENC(3,3,C14,C14,1) },
2977 1.1.1.1.8.2 tls { "pmevtyper18_el0", CPENC(3,3,C14,C14,2) },
2978 1.1.1.1.8.2 tls { "pmevtyper19_el0", CPENC(3,3,C14,C14,3) },
2979 1.1.1.1.8.2 tls { "pmevtyper20_el0", CPENC(3,3,C14,C14,4) },
2980 1.1.1.1.8.2 tls { "pmevtyper21_el0", CPENC(3,3,C14,C14,5) },
2981 1.1.1.1.8.2 tls { "pmevtyper22_el0", CPENC(3,3,C14,C14,6) },
2982 1.1.1.1.8.2 tls { "pmevtyper23_el0", CPENC(3,3,C14,C14,7) },
2983 1.1.1.1.8.2 tls { "pmevtyper24_el0", CPENC(3,3,C14,C15,0) },
2984 1.1.1.1.8.2 tls { "pmevtyper25_el0", CPENC(3,3,C14,C15,1) },
2985 1.1.1.1.8.2 tls { "pmevtyper26_el0", CPENC(3,3,C14,C15,2) },
2986 1.1.1.1.8.2 tls { "pmevtyper27_el0", CPENC(3,3,C14,C15,3) },
2987 1.1.1.1.8.2 tls { "pmevtyper28_el0", CPENC(3,3,C14,C15,4) },
2988 1.1.1.1.8.2 tls { "pmevtyper29_el0", CPENC(3,3,C14,C15,5) },
2989 1.1.1.1.8.2 tls { "pmevtyper30_el0", CPENC(3,3,C14,C15,6) },
2990 1.1.1.1.8.2 tls { "pmccfiltr_el0", CPENC(3,3,C14,C15,7) },
2991 1.1.1.1.8.2 tls { 0, CPENC(0,0,0,0,0) },
2992 1.1.1.1.8.2 tls };
2993 1.1.1.1.8.2 tls
2994 1.1.1.1.8.2 tls const struct aarch64_name_value_pair aarch64_pstatefields [] =
2995 1.1.1.1.8.2 tls {
2996 1.1.1.1.8.2 tls { "spsel", 0x05 },
2997 1.1.1.1.8.2 tls { "daifset", 0x1e },
2998 1.1.1.1.8.2 tls { "daifclr", 0x1f },
2999 1.1.1.1.8.2 tls { 0, CPENC(0,0,0,0,0) },
3000 1.1.1.1.8.2 tls };
3001 1.1.1.1.8.2 tls
3002 1.1.1.1.8.2 tls const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
3003 1.1.1.1.8.2 tls {
3004 1.1.1.1.8.2 tls { "ialluis", CPENS(0,C7,C1,0), 0 },
3005 1.1.1.1.8.2 tls { "iallu", CPENS(0,C7,C5,0), 0 },
3006 1.1.1.1.8.2 tls { "ivau", CPENS(3,C7,C5,1), 1 },
3007 1.1.1.1.8.2 tls { 0, CPENS(0,0,0,0), 0 }
3008 1.1.1.1.8.2 tls };
3009 1.1.1.1.8.2 tls
3010 1.1.1.1.8.2 tls const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
3011 1.1.1.1.8.2 tls {
3012 1.1.1.1.8.2 tls { "zva", CPENS(3,C7,C4,1), 1 },
3013 1.1.1.1.8.2 tls { "ivac", CPENS(0,C7,C6,1), 1 },
3014 1.1.1.1.8.2 tls { "isw", CPENS(0,C7,C6,2), 1 },
3015 1.1.1.1.8.2 tls { "cvac", CPENS(3,C7,C10,1), 1 },
3016 1.1.1.1.8.2 tls { "csw", CPENS(0,C7,C10,2), 1 },
3017 1.1.1.1.8.2 tls { "cvau", CPENS(3,C7,C11,1), 1 },
3018 1.1.1.1.8.2 tls { "civac", CPENS(3,C7,C14,1), 1 },
3019 1.1.1.1.8.2 tls { "cisw", CPENS(0,C7,C14,2), 1 },
3020 1.1.1.1.8.2 tls { 0, CPENS(0,0,0,0), 0 }
3021 1.1.1.1.8.2 tls };
3022 1.1.1.1.8.2 tls
3023 1.1.1.1.8.2 tls const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
3024 1.1.1.1.8.2 tls {
3025 1.1.1.1.8.2 tls { "s1e1r", CPENS(0,C7,C8,0), 1 },
3026 1.1.1.1.8.2 tls { "s1e1w", CPENS(0,C7,C8,1), 1 },
3027 1.1.1.1.8.2 tls { "s1e0r", CPENS(0,C7,C8,2), 1 },
3028 1.1.1.1.8.2 tls { "s1e0w", CPENS(0,C7,C8,3), 1 },
3029 1.1.1.1.8.2 tls { "s12e1r", CPENS(4,C7,C8,4), 1 },
3030 1.1.1.1.8.2 tls { "s12e1w", CPENS(4,C7,C8,5), 1 },
3031 1.1.1.1.8.2 tls { "s12e0r", CPENS(4,C7,C8,6), 1 },
3032 1.1.1.1.8.2 tls { "s12e0w", CPENS(4,C7,C8,7), 1 },
3033 1.1.1.1.8.2 tls { "s1e2r", CPENS(4,C7,C8,0), 1 },
3034 1.1.1.1.8.2 tls { "s1e2w", CPENS(4,C7,C8,1), 1 },
3035 1.1.1.1.8.2 tls { "s1e3r", CPENS(6,C7,C8,0), 1 },
3036 1.1.1.1.8.2 tls { "s1e3w", CPENS(6,C7,C8,1), 1 },
3037 1.1.1.1.8.2 tls { 0, CPENS(0,0,0,0), 0 }
3038 1.1.1.1.8.2 tls };
3039 1.1.1.1.8.2 tls
3040 1.1.1.1.8.2 tls const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
3041 1.1.1.1.8.2 tls {
3042 1.1.1.1.8.2 tls { "vmalle1", CPENS(0,C8,C7,0), 0 },
3043 1.1.1.1.8.2 tls { "vae1", CPENS(0,C8,C7,1), 1 },
3044 1.1.1.1.8.2 tls { "aside1", CPENS(0,C8,C7,2), 1 },
3045 1.1.1.1.8.2 tls { "vaae1", CPENS(0,C8,C7,3), 1 },
3046 1.1.1.1.8.2 tls { "vmalle1is", CPENS(0,C8,C3,0), 0 },
3047 1.1.1.1.8.2 tls { "vae1is", CPENS(0,C8,C3,1), 1 },
3048 1.1.1.1.8.2 tls { "aside1is", CPENS(0,C8,C3,2), 1 },
3049 1.1.1.1.8.2 tls { "vaae1is", CPENS(0,C8,C3,3), 1 },
3050 1.1.1.1.8.2 tls { "ipas2e1is", CPENS(4,C8,C0,1), 1 },
3051 1.1.1.1.8.2 tls { "ipas2le1is",CPENS(4,C8,C0,5), 1 },
3052 1.1.1.1.8.2 tls { "ipas2e1", CPENS(4,C8,C4,1), 1 },
3053 1.1.1.1.8.2 tls { "ipas2le1", CPENS(4,C8,C4,5), 1 },
3054 1.1.1.1.8.2 tls { "vae2", CPENS(4,C8,C7,1), 1 },
3055 1.1.1.1.8.2 tls { "vae2is", CPENS(4,C8,C3,1), 1 },
3056 1.1.1.1.8.2 tls { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
3057 1.1.1.1.8.2 tls { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
3058 1.1.1.1.8.2 tls { "vae3", CPENS(6,C8,C7,1), 1 },
3059 1.1.1.1.8.2 tls { "vae3is", CPENS(6,C8,C3,1), 1 },
3060 1.1.1.1.8.2 tls { "alle2", CPENS(4,C8,C7,0), 0 },
3061 1.1.1.1.8.2 tls { "alle2is", CPENS(4,C8,C3,0), 0 },
3062 1.1.1.1.8.2 tls { "alle1", CPENS(4,C8,C7,4), 0 },
3063 1.1.1.1.8.2 tls { "alle1is", CPENS(4,C8,C3,4), 0 },
3064 1.1.1.1.8.2 tls { "alle3", CPENS(6,C8,C7,0), 0 },
3065 1.1.1.1.8.2 tls { "alle3is", CPENS(6,C8,C3,0), 0 },
3066 1.1.1.1.8.2 tls { "vale1is", CPENS(0,C8,C3,5), 1 },
3067 1.1.1.1.8.2 tls { "vale2is", CPENS(4,C8,C3,5), 1 },
3068 1.1.1.1.8.2 tls { "vale3is", CPENS(6,C8,C3,5), 1 },
3069 1.1.1.1.8.2 tls { "vaale1is", CPENS(0,C8,C3,7), 1 },
3070 1.1.1.1.8.2 tls { "vale1", CPENS(0,C8,C7,5), 1 },
3071 1.1.1.1.8.2 tls { "vale2", CPENS(4,C8,C7,5), 1 },
3072 1.1.1.1.8.2 tls { "vale3", CPENS(6,C8,C7,5), 1 },
3073 1.1.1.1.8.2 tls { "vaale1", CPENS(0,C8,C7,7), 1 },
3074 1.1.1.1.8.2 tls { 0, CPENS(0,0,0,0), 0 }
3075 1.1.1.1.8.2 tls };
3076 1.1.1.1.8.2 tls
3077 1.1.1.1.8.2 tls #undef C0
3078 1.1.1.1.8.2 tls #undef C1
3079 1.1.1.1.8.2 tls #undef C2
3080 1.1.1.1.8.2 tls #undef C3
3081 1.1.1.1.8.2 tls #undef C4
3082 1.1.1.1.8.2 tls #undef C5
3083 1.1.1.1.8.2 tls #undef C6
3084 1.1.1.1.8.2 tls #undef C7
3085 1.1.1.1.8.2 tls #undef C8
3086 1.1.1.1.8.2 tls #undef C9
3087 1.1.1.1.8.2 tls #undef C10
3088 1.1.1.1.8.2 tls #undef C11
3089 1.1.1.1.8.2 tls #undef C12
3090 1.1.1.1.8.2 tls #undef C13
3091 1.1.1.1.8.2 tls #undef C14
3092 1.1.1.1.8.2 tls #undef C15
3093
3094 /* Include the opcode description table as well as the operand description
3095 table. */
3096 #include "aarch64-tbl.h"
3097