neon64.isa (10037:5cac77888310) neon64.isa (11165:d90aec9435bd)
1// Copyright (c) 2012-2013 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Giacomo Gabrielli
37// Mbou Eyole
38
39output header {{
40namespace Aarch64
41{
42 // AdvSIMD three same
1// Copyright (c) 2012-2013 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Giacomo Gabrielli
37// Mbou Eyole
38
39output header {{
40namespace Aarch64
41{
42 // AdvSIMD three same
43 template <typename DecoderFeatures>
43 StaticInstPtr decodeNeon3Same(ExtMachInst machInst);
44 // AdvSIMD three different
44 StaticInstPtr decodeNeon3Same(ExtMachInst machInst);
45 // AdvSIMD three different
45 StaticInstPtr decodeNeon3Diff(ExtMachInst machInst);
46 inline StaticInstPtr decodeNeon3Diff(ExtMachInst machInst);
46 // AdvSIMD two-reg misc
47 // AdvSIMD two-reg misc
47 StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst);
48 inline StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst);
48 // AdvSIMD across lanes
49 // AdvSIMD across lanes
49 StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst);
50 inline StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst);
50 // AdvSIMD copy
51 // AdvSIMD copy
51 StaticInstPtr decodeNeonCopy(ExtMachInst machInst);
52 inline StaticInstPtr decodeNeonCopy(ExtMachInst machInst);
52 // AdvSIMD vector x indexed element
53 // AdvSIMD vector x indexed element
54 template <typename DecoderFeatures>
53 StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst);
54 // AdvSIMD modified immediate
55 StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst);
56 // AdvSIMD modified immediate
55 StaticInstPtr decodeNeonModImm(ExtMachInst machInst);
57 inline StaticInstPtr decodeNeonModImm(ExtMachInst machInst);
56 // AdvSIMD shift by immediate
58 // AdvSIMD shift by immediate
57 StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst);
59 inline StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst);
58 // AdvSIMD TBL/TBX
60 // AdvSIMD TBL/TBX
59 StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst);
61 inline StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst);
60 // AdvSIMD ZIP/UZP/TRN
62 // AdvSIMD ZIP/UZP/TRN
61 StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst);
63 inline StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst);
62 // AdvSIMD EXT
64 // AdvSIMD EXT
63 StaticInstPtr decodeNeonExt(ExtMachInst machInst);
65 inline StaticInstPtr decodeNeonExt(ExtMachInst machInst);
64
65 // AdvSIMD scalar three same
66
67 // AdvSIMD scalar three same
66 StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst);
68 inline StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst);
67 // AdvSIMD scalar three different
69 // AdvSIMD scalar three different
68 StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst);
70 inline StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst);
69 // AdvSIMD scalar two-reg misc
71 // AdvSIMD scalar two-reg misc
70 StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst);
72 inline StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst);
71 // AdvSIMD scalar pairwise
73 // AdvSIMD scalar pairwise
72 StaticInstPtr decodeNeonScPwise(ExtMachInst machInst);
74 inline StaticInstPtr decodeNeonScPwise(ExtMachInst machInst);
73 // AdvSIMD scalar copy
75 // AdvSIMD scalar copy
74 StaticInstPtr decodeNeonScCopy(ExtMachInst machInst);
76 inline StaticInstPtr decodeNeonScCopy(ExtMachInst machInst);
75 // AdvSIMD scalar x indexed element
77 // AdvSIMD scalar x indexed element
76 StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst);
78 inline StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst);
77 // AdvSIMD scalar shift by immediate
79 // AdvSIMD scalar shift by immediate
78 StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst);
80 inline StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst);
79
80 // AdvSIMD load/store
81
82 // AdvSIMD load/store
81 StaticInstPtr decodeNeonMem(ExtMachInst machInst);
83 inline StaticInstPtr decodeNeonMem(ExtMachInst machInst);
82}
83}};
84
85output decoder {{
86namespace Aarch64
87{
84}
85}};
86
87output decoder {{
88namespace Aarch64
89{
90 template <typename DecoderFeatures>
88 StaticInstPtr
89 decodeNeon3Same(ExtMachInst machInst)
90 {
91 uint8_t q = bits(machInst, 30);
92 uint8_t u = bits(machInst, 29);
93 uint8_t size = bits(machInst, 23, 22);
94 uint8_t opcode = bits(machInst, 15, 11);
95
96 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
97 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
98 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
99
100 uint8_t size_q = (size << 1) | q;
101 uint8_t sz_q = size_q & 0x3;
102
103 switch (opcode) {
104 case 0x00:
105 if (size == 0x3)
106 return new Unknown64(machInst);
107 if (u)
108 return decodeNeonUThreeSReg<UhaddDX, UhaddQX>(
109 q, size, machInst, vd, vn, vm);
110 else
111 return decodeNeonSThreeSReg<ShaddDX, ShaddQX>(
112 q, size, machInst, vd, vn, vm);
113 case 0x01:
114 if (size_q == 0x6)
115 return new Unknown64(machInst);
116 if (u)
117 return decodeNeonUThreeXReg<UqaddDX, UqaddQX>(
118 q, size, machInst, vd, vn, vm);
119 else
120 return decodeNeonSThreeXReg<SqaddDX, SqaddQX>(
121 q, size, machInst, vd, vn, vm);
122 case 0x02:
123 if (size == 0x3)
124 return new Unknown64(machInst);
125 if (u)
126 return decodeNeonUThreeSReg<UrhaddDX, UrhaddQX>(
127 q, size, machInst, vd, vn, vm);
128 else
129 return decodeNeonSThreeSReg<SrhaddDX, SrhaddQX>(
130 q, size, machInst, vd, vn, vm);
131 case 0x03:
132 switch (size) {
133 case 0x0:
134 if (u) {
135 if (q)
136 return new EorQX<uint64_t>(machInst, vd, vn, vm);
137 else
138 return new EorDX<uint64_t>(machInst, vd, vn, vm);
139 } else {
140 if (q)
141 return new AndQX<uint64_t>(machInst, vd, vn, vm);
142 else
143 return new AndDX<uint64_t>(machInst, vd, vn, vm);
144 }
145 case 0x1:
146 if (u) {
147 if (q)
148 return new BslQX<uint64_t>(machInst, vd, vn, vm);
149 else
150 return new BslDX<uint64_t>(machInst, vd, vn, vm);
151 } else {
152 if (q)
153 return new BicQX<uint64_t>(machInst, vd, vn, vm);
154 else
155 return new BicDX<uint64_t>(machInst, vd, vn, vm);
156 }
157 case 0x2:
158 if (u) {
159 if (q)
160 return new BitQX<uint64_t>(machInst, vd, vn, vm);
161 else
162 return new BitDX<uint64_t>(machInst, vd, vn, vm);
163 } else {
164 if (q)
165 return new OrrQX<uint64_t>(machInst, vd, vn, vm);
166 else
167 return new OrrDX<uint64_t>(machInst, vd, vn, vm);
168 }
169 case 0x3:
170 if (u) {
171 if (q)
172 return new BifQX<uint64_t>(machInst, vd, vn, vm);
173 else
174 return new BifDX<uint64_t>(machInst, vd, vn, vm);
175 } else {
176 if (q)
177 return new OrnQX<uint64_t>(machInst, vd, vn, vm);
178 else
179 return new OrnDX<uint64_t>(machInst, vd, vn, vm);
180 }
181 }
182 case 0x04:
183 if (size == 0x3)
184 return new Unknown64(machInst);
185 if (u)
186 return decodeNeonUThreeSReg<UhsubDX, UhsubQX>(
187 q, size, machInst, vd, vn, vm);
188 else
189 return decodeNeonSThreeSReg<ShsubDX, ShsubQX>(
190 q, size, machInst, vd, vn, vm);
191 case 0x05:
192 if (size_q == 0x6)
193 return new Unknown64(machInst);
194 if (u)
195 return decodeNeonUThreeXReg<UqsubDX, UqsubQX>(
196 q, size, machInst, vd, vn, vm);
197 else
198 return decodeNeonSThreeXReg<SqsubDX, SqsubQX>(
199 q, size, machInst, vd, vn, vm);
200 case 0x06:
201 if (size_q == 0x6)
202 return new Unknown64(machInst);
203 if (u)
204 return decodeNeonUThreeXReg<CmhiDX, CmhiQX>(
205 q, size, machInst, vd, vn, vm);
206 else
207 return decodeNeonSThreeXReg<CmgtDX, CmgtQX>(
208 q, size, machInst, vd, vn, vm);
209 case 0x07:
210 if (size_q == 0x6)
211 return new Unknown64(machInst);
212 if (u)
213 return decodeNeonUThreeXReg<CmhsDX, CmhsQX>(
214 q, size, machInst, vd, vn, vm);
215 else
216 return decodeNeonSThreeXReg<CmgeDX, CmgeQX>(
217 q, size, machInst, vd, vn, vm);
218 case 0x08:
219 if (size_q == 0x6)
220 return new Unknown64(machInst);
221 if (u)
222 return decodeNeonUThreeXReg<UshlDX, UshlQX>(
223 q, size, machInst, vd, vn, vm);
224 else
225 return decodeNeonSThreeXReg<SshlDX, SshlQX>(
226 q, size, machInst, vd, vn, vm);
227 case 0x09:
228 if (size_q == 0x6)
229 return new Unknown64(machInst);
230 if (u)
231 return decodeNeonUThreeXReg<UqshlDX, UqshlQX>(
232 q, size, machInst, vd, vn, vm);
233 else
234 return decodeNeonSThreeXReg<SqshlDX, SqshlQX>(
235 q, size, machInst, vd, vn, vm);
236 case 0x0a:
237 if (size_q == 0x6)
238 return new Unknown64(machInst);
239 if (u)
240 return decodeNeonUThreeXReg<UrshlDX, UrshlQX>(
241 q, size, machInst, vd, vn, vm);
242 else
243 return decodeNeonSThreeXReg<SrshlDX, SrshlQX>(
244 q, size, machInst, vd, vn, vm);
245 case 0x0b:
246 if (size_q == 0x6)
247 return new Unknown64(machInst);
248 if (u)
249 return decodeNeonUThreeXReg<UqrshlDX, UqrshlQX>(
250 q, size, machInst, vd, vn, vm);
251 else
252 return decodeNeonSThreeXReg<SqrshlDX, SqrshlQX>(
253 q, size, machInst, vd, vn, vm);
254 case 0x0c:
255 if (size == 0x3)
256 return new Unknown64(machInst);
257 if (u)
258 return decodeNeonUThreeSReg<UmaxDX, UmaxQX>(
259 q, size, machInst, vd, vn, vm);
260 else
261 return decodeNeonSThreeSReg<SmaxDX, SmaxQX>(
262 q, size, machInst, vd, vn, vm);
263 case 0x0d:
264 if (size == 0x3)
265 return new Unknown64(machInst);
266 if (u)
267 return decodeNeonUThreeSReg<UminDX, UminQX>(
268 q, size, machInst, vd, vn, vm);
269 else
270 return decodeNeonSThreeSReg<SminDX, SminQX>(
271 q, size, machInst, vd, vn, vm);
272 case 0x0e:
273 if (size == 0x3)
274 return new Unknown64(machInst);
275 if (u)
276 return decodeNeonUThreeSReg<UabdDX, UabdQX>(
277 q, size, machInst, vd, vn, vm);
278 else
279 return decodeNeonSThreeSReg<SabdDX, SabdQX>(
280 q, size, machInst, vd, vn, vm);
281 case 0x0f:
282 if (size == 0x3)
283 return new Unknown64(machInst);
284 if (u)
285 return decodeNeonUThreeSReg<UabaDX, UabaQX>(
286 q, size, machInst, vd, vn, vm);
287 else
288 return decodeNeonSThreeSReg<SabaDX, SabaQX>(
289 q, size, machInst, vd, vn, vm);
290 case 0x10:
291 if (size_q == 0x6)
292 return new Unknown64(machInst);
293 if (u)
294 return decodeNeonUThreeXReg<SubDX, SubQX>(
295 q, size, machInst, vd, vn, vm);
296 else
297 return decodeNeonUThreeXReg<AddDX, AddQX>(
298 q, size, machInst, vd, vn, vm);
299 case 0x11:
300 if (size_q == 0x6)
301 return new Unknown64(machInst);
302 if (u)
303 return decodeNeonUThreeXReg<CmeqDX, CmeqQX>(
304 q, size, machInst, vd, vn, vm);
305 else
306 return decodeNeonUThreeXReg<CmtstDX, CmtstQX>(
307 q, size, machInst, vd, vn, vm);
308 case 0x12:
309 if (size == 0x3)
310 return new Unknown64(machInst);
311 if (u)
312 return decodeNeonUThreeSReg<MlsDX, MlsQX>(
313 q, size, machInst, vd, vn, vm);
314 else
315 return decodeNeonUThreeSReg<MlaDX, MlaQX>(
316 q, size, machInst, vd, vn, vm);
317 case 0x13:
318 if (size == 0x3 || (size != 0x0 && bits(machInst, 29)))
319 return new Unknown64(machInst);
320 if (u) {
321 if (q)
322 return new PmulQX<uint8_t>(machInst, vd, vn, vm);
323 else
324 return new PmulDX<uint8_t>(machInst, vd, vn, vm);
325 } else {
326 return decodeNeonUThreeSReg<MulDX, MulQX>(
327 q, size, machInst, vd, vn, vm);
328 }
329 case 0x14:
330 if (size == 0x3)
331 return new Unknown64(machInst);
332 if (u)
333 return decodeNeonUThreeSReg<UmaxpDX, UmaxpQX>(
334 q, size, machInst, vd, vn, vm);
335 else
336 return decodeNeonSThreeSReg<SmaxpDX, SmaxpQX>(
337 q, size, machInst, vd, vn, vm);
338 case 0x15:
339 if (size == 0x3)
340 return new Unknown64(machInst);
341 if (u)
342 return decodeNeonUThreeSReg<UminpDX, UminpQX>(
343 q, size, machInst, vd, vn, vm);
344 else
345 return decodeNeonSThreeSReg<SminpDX, SminpQX>(
346 q, size, machInst, vd, vn, vm);
347 case 0x16:
348 if (size == 0x3 || size == 0x0)
349 return new Unknown64(machInst);
350 if (u) {
351 if (q)
352 return decodeNeonSThreeHAndWReg<SqrdmulhQX>(
353 size, machInst, vd, vn, vm);
354 else
355 return decodeNeonSThreeHAndWReg<SqrdmulhDX>(
356 size, machInst, vd, vn, vm);
357 } else {
358 if (q)
359 return decodeNeonSThreeHAndWReg<SqdmulhQX>(
360 size, machInst, vd, vn, vm);
361 else
362 return decodeNeonSThreeHAndWReg<SqdmulhDX>(
363 size, machInst, vd, vn, vm);
364 }
365 case 0x17:
366 if (u || size_q == 0x6)
367 return new Unknown64(machInst);
368 else
369 return decodeNeonUThreeXReg<AddpDX, AddpQX>(
370 q, size, machInst, vd, vn, vm);
371 case 0x18:
372 if (sz_q == 0x2)
373 return new Unknown64(machInst);
374 if (size < 0x2) {
375 if (u)
376 return decodeNeonUThreeFpReg<FmaxnmpDX, FmaxnmpQX>(
377 q, size & 0x1, machInst, vd, vn, vm);
378 else
379 return decodeNeonUThreeFpReg<FmaxnmDX, FmaxnmQX>(
380 q, size & 0x1, machInst, vd, vn, vm);
381 } else {
382 if (u)
383 return decodeNeonUThreeFpReg<FminnmpDX, FminnmpQX>(
384 q, size & 0x1, machInst, vd, vn, vm);
385 else
386 return decodeNeonUThreeFpReg<FminnmDX, FminnmQX>(
387 q, size & 0x1, machInst, vd, vn, vm);
388 }
389 case 0x19:
390 if (size < 0x2) {
391 if (u || sz_q == 0x2)
392 return new Unknown64(machInst);
393 else
394 return decodeNeonUThreeFpReg<FmlaDX, FmlaQX>(
395 q, size & 0x1, machInst, vd, vn, vm);
396 } else {
397 if (u || sz_q == 0x2)
398 return new Unknown64(machInst);
399 else
400 return decodeNeonUThreeFpReg<FmlsDX, FmlsQX>(
401 q, size & 0x1, machInst, vd, vn, vm);
402 }
403 case 0x1a:
404 if (sz_q == 0x2)
405 return new Unknown64(machInst);
406 if (size < 0x2) {
407 if (u)
408 return decodeNeonUThreeFpReg<FaddpDX, FaddpQX>(
409 q, size & 0x1, machInst, vd, vn, vm);
410 else
411 return decodeNeonUThreeFpReg<FaddDX, FaddQX>(
412 q, size & 0x1, machInst, vd, vn, vm);
413 } else {
414 if (u)
415 return decodeNeonUThreeFpReg<FabdDX, FabdQX>(
416 q, size & 0x1, machInst, vd, vn, vm);
417 else
418 return decodeNeonUThreeFpReg<FsubDX, FsubQX>(
419 q, size & 0x1, machInst, vd, vn, vm);
420 }
421 case 0x1b:
422 if (size < 0x2 && sz_q != 0x2) {
423 if (u)
424 return decodeNeonUThreeFpReg<FmulDX, FmulQX>(
425 q, size & 0x1, machInst, vd, vn, vm);
426 else
427 return decodeNeonUThreeFpReg<FmulxDX, FmulxQX>(
428 q, size & 0x1, machInst, vd, vn, vm);
429 } else {
430 return new Unknown64(machInst);
431 }
432 case 0x1c:
433 if (size < 0x2) {
434 if (u)
435 return decodeNeonUThreeFpReg<FcmgeDX, FcmgeQX>(
436 q, size & 0x1, machInst, vd, vn, vm);
437 else
438 return decodeNeonUThreeFpReg<FcmeqDX, FcmeqQX>(
439 q, size & 0x1, machInst, vd, vn, vm);
440 } else {
441 if (u)
442 return decodeNeonUThreeFpReg<FcmgtDX, FcmgtQX>(
443 q, size & 0x1, machInst, vd, vn, vm);
444 else
445 return new Unknown64(machInst);
446 }
447 case 0x1d:
448 if (size < 0x2) {
449 if (u)
450 return decodeNeonUThreeFpReg<FacgeDX, FacgeQX>(
451 q, size & 0x1, machInst, vd, vn, vm);
452 else
453 return new Unknown64(machInst);
454 } else {
455 if (u)
456 return decodeNeonUThreeFpReg<FacgtDX, FacgtQX>(
457 q, size & 0x1, machInst, vd, vn, vm);
458 else
459 return new Unknown64(machInst);
460 }
461 case 0x1e:
462 if (sz_q == 0x2)
463 return new Unknown64(machInst);
464 if (size < 0x2) {
465 if (u)
466 return decodeNeonUThreeFpReg<FmaxpDX, FmaxpQX>(
467 q, size & 0x1, machInst, vd, vn, vm);
468 else
469 return decodeNeonUThreeFpReg<FmaxDX, FmaxQX>(
470 q, size & 0x1, machInst, vd, vn, vm);
471 } else {
472 if (u)
473 return decodeNeonUThreeFpReg<FminpDX, FminpQX>(
474 q, size & 0x1, machInst, vd, vn, vm);
475 else
476 return decodeNeonUThreeFpReg<FminDX, FminQX>(
477 q, size & 0x1, machInst, vd, vn, vm);
478 }
479 case 0x1f:
480 if (sz_q == 0x2)
481 return new Unknown64(machInst);
482 if (size < 0x2) {
483 if (u)
484 return decodeNeonUThreeFpReg<FdivDX, FdivQX>(
485 q, size & 0x1, machInst, vd, vn, vm);
486 else
487 return decodeNeonUThreeFpReg<FrecpsDX, FrecpsQX>(
488 q, size & 0x1, machInst, vd, vn, vm);
489 } else {
490 if (u)
491 return new Unknown64(machInst);
492 else
493 return decodeNeonUThreeFpReg<FrsqrtsDX, FrsqrtsQX>(
494 q, size & 0x1, machInst, vd, vn, vm);
495 }
496 default:
497 return new Unknown64(machInst);
498 }
499 }
500
501 StaticInstPtr
502 decodeNeon3Diff(ExtMachInst machInst)
503 {
504 uint8_t q = bits(machInst, 30);
505 uint8_t u = bits(machInst, 29);
506 uint8_t size = bits(machInst, 23, 22);
507 uint8_t opcode = bits(machInst, 15, 12);
508
509 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
510 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
511 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
512
513 switch (opcode) {
514 case 0x0:
515 if (size == 0x3)
516 return new Unknown64(machInst);
517 if (u)
518 return decodeNeonUThreeSReg<UaddlX, Uaddl2X>(
519 q, size, machInst, vd, vn, vm);
520 else
521 return decodeNeonSThreeSReg<SaddlX, Saddl2X>(
522 q, size, machInst, vd, vn, vm);
523 case 0x1:
524 if (size == 0x3)
525 return new Unknown64(machInst);
526 if (u)
527 return decodeNeonUThreeSReg<UaddwX, Uaddw2X>(
528 q, size, machInst, vd, vn, vm);
529 else
530 return decodeNeonSThreeSReg<SaddwX, Saddw2X>(
531 q, size, machInst, vd, vn, vm);
532 case 0x2:
533 if (size == 0x3)
534 return new Unknown64(machInst);
535 if (u)
536 return decodeNeonUThreeSReg<UsublX, Usubl2X>(
537 q, size, machInst, vd, vn, vm);
538 else
539 return decodeNeonSThreeSReg<SsublX, Ssubl2X>(
540 q, size, machInst, vd, vn, vm);
541 case 0x3:
542 if (size == 0x3)
543 return new Unknown64(machInst);
544 if (u)
545 return decodeNeonUThreeSReg<UsubwX, Usubw2X>(
546 q, size, machInst, vd, vn, vm);
547 else
548 return decodeNeonSThreeSReg<SsubwX, Ssubw2X>(
549 q, size, machInst, vd, vn, vm);
550 case 0x4:
551 if (size == 0x3)
552 return new Unknown64(machInst);
553 if (u)
554 return decodeNeonUThreeSReg<RaddhnX, Raddhn2X>(
555 q, size, machInst, vd, vn, vm);
556 else
557 return decodeNeonUThreeSReg<AddhnX, Addhn2X>(
558 q, size, machInst, vd, vn, vm);
559 case 0x5:
560 if (size == 0x3)
561 return new Unknown64(machInst);
562 if (u)
563 return decodeNeonUThreeSReg<UabalX, Uabal2X>(
564 q, size, machInst, vd, vn, vm);
565 else
566 return decodeNeonSThreeSReg<SabalX, Sabal2X>(
567 q, size, machInst, vd, vn, vm);
568 case 0x6:
569 if (size == 0x3)
570 return new Unknown64(machInst);
571 if (u)
572 return decodeNeonUThreeSReg<RsubhnX, Rsubhn2X>(
573 q, size, machInst, vd, vn, vm);
574 else
575 return decodeNeonUThreeSReg<SubhnX, Subhn2X>(
576 q, size, machInst, vd, vn, vm);
577 case 0x7:
578 if (size == 0x3)
579 return new Unknown64(machInst);
580 if (u)
581 return decodeNeonUThreeSReg<UabdlX, Uabdl2X>(
582 q, size, machInst, vd, vn, vm);
583 else
584 return decodeNeonSThreeSReg<SabdlX, Sabdl2X>(
585 q, size, machInst, vd, vn, vm);
586 case 0x8:
587 if (size == 0x3)
588 return new Unknown64(machInst);
589 if (u)
590 return decodeNeonUThreeSReg<UmlalX, Umlal2X>(
591 q, size, machInst, vd, vn, vm);
592 else
593 return decodeNeonSThreeSReg<SmlalX, Smlal2X>(
594 q, size, machInst, vd, vn, vm);
595 case 0x9:
596 if (u || (size == 0x0 || size == 0x3)) {
597 return new Unknown64(machInst);
598 } else {
599 if (q) {
600 return decodeNeonSThreeHAndWReg<Sqdmlal2X>(
601 size, machInst, vd, vn, vm);
602 } else {
603 return decodeNeonSThreeHAndWReg<SqdmlalX>(
604 size, machInst, vd, vn, vm);
605 }
606 }
607 case 0xa:
608 if (size == 0x3)
609 return new Unknown64(machInst);
610 if (u)
611 return decodeNeonUThreeSReg<UmlslX, Umlsl2X>(
612 q, size, machInst, vd, vn, vm);
613 else
614 return decodeNeonSThreeSReg<SmlslX, Smlsl2X>(
615 q, size, machInst, vd, vn, vm);
616 case 0xb:
617 if (u || (size == 0x0 || size == 0x3)) {
618 return new Unknown64(machInst);
619 } else {
620 if (q) {
621 return decodeNeonSThreeHAndWReg<Sqdmlsl2X>(
622 size, machInst, vd, vn, vm);
623 } else {
624 return decodeNeonSThreeHAndWReg<SqdmlslX>(
625 size, machInst, vd, vn, vm);
626 }
627 }
628 case 0xc:
629 if (size == 0x3)
630 return new Unknown64(machInst);
631 if (u)
632 return decodeNeonUThreeSReg<UmullX, Umull2X>(
633 q, size, machInst, vd, vn, vm);
634 else
635 return decodeNeonSThreeSReg<SmullX, Smull2X>(
636 q, size, machInst, vd, vn, vm);
637 case 0xd:
638 if (u || (size == 0x0 || size == 0x3)) {
639 return new Unknown64(machInst);
640 } else {
641 if (q) {
642 return decodeNeonSThreeHAndWReg<Sqdmull2X>(
643 size, machInst, vd, vn, vm);
644 } else {
645 return decodeNeonSThreeHAndWReg<SqdmullX>(
646 size, machInst, vd, vn, vm);
647 }
648 }
649 case 0xe:
650 if (u || size != 0) {
651 return new Unknown64(machInst);
652 } else {
653 if (q)
654 return new Pmull2X<uint8_t>(machInst, vd, vn, vm);
655 else
656 return new PmullX<uint8_t>(machInst, vd, vn, vm);
657 }
658 default:
659 return new Unknown64(machInst);
660 }
661 }
662
663 StaticInstPtr
664 decodeNeon2RegMisc(ExtMachInst machInst)
665 {
666 uint8_t q = bits(machInst, 30);
667 uint8_t u = bits(machInst, 29);
668 uint8_t size = bits(machInst, 23, 22);
669 uint8_t opcode = bits(machInst, 16, 12);
670
671 IntRegIndex vd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
672 IntRegIndex vn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
673
674 uint8_t size_q = (size << 1) | q;
675 uint8_t sz_q = size_q & 0x3;
676 uint8_t op = (uint8_t)((bits(machInst, 12) << 1) |
677 bits(machInst, 29));
678 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
679
680 switch (switchVal) {
681 case 0x00:
682 if (op + size >= 3)
683 return new Unknown64(machInst);
684 return decodeNeonUTwoMiscSReg<Rev64DX, Rev64QX>(
685 q, size, machInst, vd, vn);
686 case 0x01:
687 if (op + size >= 3)
688 return new Unknown64(machInst);
689 if (q)
690 return new Rev16QX<uint8_t>(machInst, vd, vn);
691 else
692 return new Rev16DX<uint8_t>(machInst, vd, vn);
693 case 0x02:
694 if (size == 0x3)
695 return new Unknown64(machInst);
696 return decodeNeonSTwoMiscSReg<SaddlpDX, SaddlpQX>(
697 q, size, machInst, vd, vn);
698 case 0x03:
699 if (size_q == 0x6)
700 return new Unknown64(machInst);
701 return decodeNeonUTwoMiscXReg<SuqaddDX, SuqaddQX>(
702 q, size, machInst, vd, vn);
703 case 0x04:
704 if (size == 0x3)
705 return new Unknown64(machInst);
706 return decodeNeonSTwoMiscSReg<ClsDX, ClsQX>(
707 q, size, machInst, vd, vn);
708 case 0x05:
709 if (size != 0x0)
710 return new Unknown64(machInst);
711 if (q)
712 return new CntQX<uint8_t>(machInst, vd, vn);
713 else
714 return new CntDX<uint8_t>(machInst, vd, vn);
715 case 0x06:
716 if (size == 0x3)
717 return new Unknown64(machInst);
718 return decodeNeonSTwoMiscSReg<SadalpDX, SadalpQX>(
719 q, size, machInst, vd, vn);
720 case 0x07:
721 if (size_q == 0x6)
722 return new Unknown64(machInst);
723 return decodeNeonSTwoMiscXReg<SqabsDX, SqabsQX>(
724 q, size, machInst, vd, vn);
725 case 0x08:
726 if (size_q == 0x6)
727 return new Unknown64(machInst);
728 return decodeNeonSTwoMiscXReg<CmgtZeroDX, CmgtZeroQX>(
729 q, size, machInst, vd, vn);
730 case 0x09:
731 if (size_q == 0x6)
732 return new Unknown64(machInst);
733 return decodeNeonSTwoMiscXReg<CmeqZeroDX, CmeqZeroQX>(
734 q, size, machInst, vd, vn);
735 case 0x0a:
736 if (size_q == 0x6)
737 return new Unknown64(machInst);
738 return decodeNeonSTwoMiscXReg<CmltZeroDX, CmltZeroQX>(
739 q, size, machInst, vd, vn);
740 case 0x0b:
741 if (size_q == 0x6)
742 return new Unknown64(machInst);
743 return decodeNeonSTwoMiscXReg<AbsDX, AbsQX>(
744 q, size, machInst, vd, vn);
745 case 0x0c:
746 if (size < 0x2 || sz_q == 0x2)
747 return new Unknown64(machInst);
748 return decodeNeonUTwoMiscFpReg<FcmgtZeroDX, FcmgtZeroQX>(
749 q, size & 0x1, machInst, vd, vn);
750 case 0x0d:
751 if (size < 0x2 || sz_q == 0x2)
752 return new Unknown64(machInst);
753 return decodeNeonUTwoMiscFpReg<FcmeqZeroDX, FcmeqZeroQX>(
754 q, size & 0x1, machInst, vd, vn);
755 case 0x0e:
756 if (size < 0x2 || sz_q == 0x2)
757 return new Unknown64(machInst);
758 return decodeNeonUTwoMiscFpReg<FcmltZeroDX, FcmltZeroQX>(
759 q, size & 0x1, machInst, vd, vn);
760 case 0x0f:
761 if (size < 0x2 || sz_q == 0x2)
762 return new Unknown64(machInst);
763 return decodeNeonUTwoMiscFpReg<FabsDX, FabsQX>(
764 q, size & 0x1, machInst, vd, vn);
765 case 0x12:
766 if (size == 0x3)
767 return new Unknown64(machInst);
768 return decodeNeonUTwoMiscSReg<XtnX, Xtn2X>(
769 q, size, machInst, vd, vn);
770 case 0x14:
771 if (size == 0x3)
772 return new Unknown64(machInst);
773 return decodeNeonSTwoMiscSReg<SqxtnX, Sqxtn2X>(
774 q, size, machInst, vd, vn);
775 case 0x16:
776 if (size > 0x1)
777 return new Unknown64(machInst);
778 if (q) {
779 if (size)
780 return new Fcvtn2X<uint32_t>(machInst, vd, vn);
781 else
782 return new Fcvtn2X<uint16_t>(machInst, vd, vn);
783 } else {
784 if (size)
785 return new FcvtnX<uint32_t>(machInst, vd, vn);
786 else
787 return new FcvtnX<uint16_t>(machInst, vd, vn);
788 }
789 case 0x17:
790 if (size > 0x1)
791 return new Unknown64(machInst);
792 if (q) {
793 if (size)
794 return new Fcvtl2X<uint32_t>(machInst, vd, vn);
795 else
796 return new Fcvtl2X<uint16_t>(machInst, vd, vn);
797 } else {
798 if (size)
799 return new FcvtlX<uint32_t>(machInst, vd, vn);
800 else
801 return new FcvtlX<uint16_t>(machInst, vd, vn);
802 }
803 case 0x18:
804 if (sz_q == 0x2)
805 return new Unknown64(machInst);
806 if (size < 0x2)
807 return decodeNeonUTwoMiscFpReg<FrintnDX, FrintnQX>(
808 q, size & 0x1, machInst, vd, vn);
809 else
810 return decodeNeonUTwoMiscFpReg<FrintpDX, FrintpQX>(
811 q, size & 0x1, machInst, vd, vn);
812 case 0x19:
813 if (sz_q == 0x2)
814 return new Unknown64(machInst);
815 if (size < 0x2)
816 return decodeNeonUTwoMiscFpReg<FrintmDX, FrintmQX>(
817 q, size & 0x1, machInst, vd, vn);
818 else
819 return decodeNeonUTwoMiscFpReg<FrintzDX, FrintzQX>(
820 q, size & 0x1, machInst, vd, vn);
821 case 0x1a:
822 if (sz_q == 0x2)
823 return new Unknown64(machInst);
824 if (size < 0x2)
825 return decodeNeonUTwoMiscFpReg<FcvtnsDX, FcvtnsQX>(
826 q, size & 0x1, machInst, vd, vn);
827 else
828 return decodeNeonUTwoMiscFpReg<FcvtpsDX, FcvtpsQX>(
829 q, size & 0x1, machInst, vd, vn);
830 case 0x1b:
831 if (sz_q == 0x2)
832 return new Unknown64(machInst);
833 if (size < 0x2)
834 return decodeNeonUTwoMiscFpReg<FcvtmsDX, FcvtmsQX>(
835 q, size & 0x1, machInst, vd, vn);
836 else
837 return decodeNeonUTwoMiscFpReg<FcvtzsIntDX, FcvtzsIntQX>(
838 q, size & 0x1, machInst, vd, vn);
839 case 0x1c:
840 if (size < 0x2) {
841 if (sz_q == 0x2)
842 return new Unknown64(machInst);
843 return decodeNeonUTwoMiscFpReg<FcvtasDX, FcvtasQX>(
844 q, size & 0x1, machInst, vd, vn);
845 } else {
846 if (size & 0x1)
847 return new Unknown64(machInst);
848 if (q)
849 return new UrecpeQX<uint32_t>(machInst, vd, vn);
850 else
851 return new UrecpeDX<uint32_t>(machInst, vd, vn);
852 }
853 case 0x1d:
854 if (sz_q == 0x2)
855 return new Unknown64(machInst);
856 if (size < 0x2) {
857 if (q) {
858 if (size & 0x1)
859 return new ScvtfIntDQX<uint64_t>(machInst, vd, vn);
860 else
861 return new ScvtfIntSQX<uint32_t>(machInst, vd, vn);
862 } else {
863 if (size & 0x1)
864 return new Unknown(machInst);
865 else
866 return new ScvtfIntDX<uint32_t>(machInst, vd, vn);
867 }
868 } else {
869 return decodeNeonUTwoMiscFpReg<FrecpeDX, FrecpeQX>(
870 q, size & 0x1, machInst, vd, vn);
871 }
872 case 0x20:
873 if (op + size >= 3)
874 return new Unknown64(machInst);
875 if (q) {
876 if (size & 0x1)
877 return new Rev32QX<uint16_t>(machInst, vd, vn);
878 else
879 return new Rev32QX<uint8_t>(machInst, vd, vn);
880 } else {
881 if (size & 0x1)
882 return new Rev32DX<uint16_t>(machInst, vd, vn);
883 else
884 return new Rev32DX<uint8_t>(machInst, vd, vn);
885 }
886 case 0x22:
887 if (size == 0x3)
888 return new Unknown64(machInst);
889 return decodeNeonUTwoMiscSReg<UaddlpDX, UaddlpQX>(
890 q, size, machInst, vd, vn);
891 case 0x23:
892 if (size_q == 0x6)
893 return new Unknown64(machInst);
894 return decodeNeonUTwoMiscXReg<UsqaddDX, UsqaddQX>(
895 q, size, machInst, vd, vn);
896 return new Unknown64(machInst);
897 case 0x24:
898 if (size == 0x3)
899 return new Unknown64(machInst);
900 return decodeNeonSTwoMiscSReg<ClzDX, ClzQX>(
901 q, size, machInst, vd, vn);
902 case 0x25:
903 if (size == 0x0) {
904 if (q)
905 return new MvnQX<uint64_t>(machInst, vd, vn);
906 else
907 return new MvnDX<uint64_t>(machInst, vd, vn);
908 } else if (size == 0x1) {
909 if (q)
910 return new RbitQX<uint8_t>(machInst, vd, vn);
911 else
912 return new RbitDX<uint8_t>(machInst, vd, vn);
913 } else {
914 return new Unknown64(machInst);
915 }
916 case 0x26:
917 if (size == 0x3)
918 return new Unknown64(machInst);
919 return decodeNeonUTwoMiscSReg<UadalpDX, UadalpQX>(
920 q, size, machInst, vd, vn);
921 case 0x27:
922 if (size_q == 0x6)
923 return new Unknown64(machInst);
924 return decodeNeonSTwoMiscXReg<SqnegDX, SqnegQX>(
925 q, size, machInst, vd, vn);
926 case 0x28:
927 if (size_q == 0x6)
928 return new Unknown64(machInst);
929 return decodeNeonSTwoMiscXReg<CmgeZeroDX, CmgeZeroQX>(
930 q, size, machInst, vd, vn);
931 case 0x29:
932 if (size_q == 0x6)
933 return new Unknown64(machInst);
934 return decodeNeonSTwoMiscXReg<CmleZeroDX, CmleZeroQX>(
935 q, size, machInst, vd, vn);
936 case 0x2b:
937 if (size_q == 0x6)
938 return new Unknown64(machInst);
939 return decodeNeonSTwoMiscXReg<NegDX, NegQX>(
940 q, size, machInst, vd, vn);
941 case 0x2c:
942 if (size < 0x2 || sz_q == 0x2)
943 return new Unknown64(machInst);
944 return decodeNeonUTwoMiscFpReg<FcmgeZeroDX, FcmgeZeroQX>(
945 q, size & 0x1, machInst, vd, vn);
946 case 0x2d:
947 if (size < 0x2 || sz_q == 0x2)
948 return new Unknown64(machInst);
949 return decodeNeonUTwoMiscFpReg<FcmleZeroDX, FcmleZeroQX>(
950 q, size & 0x1, machInst, vd, vn);
951 case 0x2f:
952 if (size < 0x2 || size_q == 0x6)
953 return new Unknown64(machInst);
954 return decodeNeonUTwoMiscFpReg<FnegDX, FnegQX>(
955 q, size & 0x1, machInst, vd, vn);
956 case 0x32:
957 if (size == 0x3)
958 return new Unknown64(machInst);
959 return decodeNeonSTwoMiscSReg<SqxtunX, Sqxtun2X>(
960 q, size, machInst, vd, vn);
961 case 0x33:
962 if (size == 0x3)
963 return new Unknown64(machInst);
964 return decodeNeonUTwoMiscSReg<ShllX, Shll2X>(
965 q, size, machInst, vd, vn);
966 case 0x34:
967 if (size == 0x3)
968 return new Unknown64(machInst);
969 return decodeNeonUTwoMiscSReg<UqxtnX, Uqxtn2X>(
970 q, size, machInst, vd, vn);
971 case 0x36:
972 if (size != 0x1)
973 return new Unknown64(machInst);
974 if (q)
975 return new Fcvtxn2X<uint32_t>(machInst, vd, vn);
976 else
977 return new FcvtxnX<uint32_t>(machInst, vd, vn);
978 case 0x38:
979 if (size > 0x1 || sz_q == 0x2)
980 return new Unknown64(machInst);
981 return decodeNeonUTwoMiscFpReg<FrintaDX, FrintaQX>(
982 q, size & 0x1, machInst, vd, vn);
983 case 0x39:
984 if (sz_q == 0x2)
985 return new Unknown64(machInst);
986 if (size < 0x2)
987 return decodeNeonUTwoMiscFpReg<FrintxDX, FrintxQX>(
988 q, size & 0x1, machInst, vd, vn);
989 else
990 return decodeNeonUTwoMiscFpReg<FrintiDX, FrintiQX>(
991 q, size & 0x1, machInst, vd, vn);
992 case 0x3a:
993 if (sz_q == 0x2)
994 return new Unknown64(machInst);
995 if (size < 0x2)
996 return decodeNeonUTwoMiscFpReg<FcvtnuDX, FcvtnuQX>(
997 q, size & 0x1, machInst, vd, vn);
998 else
999 return decodeNeonUTwoMiscFpReg<FcvtpuDX, FcvtpuQX>(
1000 q, size & 0x1, machInst, vd, vn);
1001 case 0x3b:
1002 if (sz_q == 0x2)
1003 return new Unknown64(machInst);
1004 if (size < 0x2)
1005 return decodeNeonUTwoMiscFpReg<FcvtmuDX, FcvtmuQX>(
1006 q, size & 0x1, machInst, vd, vn);
1007 else
1008 return decodeNeonUTwoMiscFpReg<FcvtzuIntDX, FcvtzuIntQX>(
1009 q, size & 0x1, machInst, vd, vn);
1010 case 0x3c:
1011 if (size < 0x2) {
1012 return decodeNeonUTwoMiscFpReg<FcvtauDX, FcvtauQX>(
1013 q, size & 0x1, machInst, vd, vn);
1014 } else if (size == 0x2) {
1015 if (q)
1016 return new UrsqrteQX<uint32_t>(machInst, vd, vn);
1017 else
1018 return new UrsqrteDX<uint32_t>(machInst, vd, vn);
1019 } else {
1020 return new Unknown64(machInst);
1021 }
1022 case 0x3d:
1023 if (sz_q == 0x2)
1024 return new Unknown64(machInst);
1025 if (size < 0x2)
1026 return decodeNeonUTwoMiscFpReg<UcvtfIntDX, UcvtfIntQX>(
1027 q, size & 0x1, machInst, vd, vn);
1028 else
1029 return decodeNeonUTwoMiscFpReg<FrsqrteDX, FrsqrteQX>(
1030 q, size & 0x1, machInst, vd, vn);
1031 case 0x3f:
1032 if (size < 0x2 || sz_q == 0x2)
1033 return new Unknown64(machInst);
1034 return decodeNeonUTwoMiscFpReg<FsqrtDX, FsqrtQX>(
1035 q, size & 0x1, machInst, vd, vn);
1036 default:
1037 return new Unknown64(machInst);
1038 }
1039 }
1040
1041 StaticInstPtr
1042 decodeNeonAcrossLanes(ExtMachInst machInst)
1043 {
1044 uint8_t q = bits(machInst, 30);
1045 uint8_t u = bits(machInst, 29);
1046 uint8_t size = bits(machInst, 23, 22);
1047 uint8_t opcode = bits(machInst, 16, 12);
1048
1049 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1050 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1051
1052 uint8_t size_q = (size << 1) | q;
1053 uint8_t sz_q = size_q & 0x3;
1054 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
1055
1056 switch (switchVal) {
1057 case 0x03:
1058 if (size_q == 0x4 || size == 0x3)
1059 return new Unknown64(machInst);
1060 return decodeNeonSAcrossLanesLongReg<SaddlvDX, SaddlvQX,
1061 SaddlvBQX>(
1062 q, size, machInst, vd, vn);
1063 case 0x0a:
1064 if (size_q == 0x4 || size == 0x3)
1065 return new Unknown64(machInst);
1066 return decodeNeonSAcrossLanesReg<SmaxvDX, SmaxvQX>(
1067 q, size, machInst, vd, vn);
1068 case 0x1a:
1069 if (size_q == 0x4 || size == 0x3)
1070 return new Unknown64(machInst);
1071 return decodeNeonSAcrossLanesReg<SminvDX, SminvQX>(
1072 q, size, machInst, vd, vn);
1073 case 0x1b:
1074 if (size_q == 0x4 || size == 0x3)
1075 return new Unknown64(machInst);
1076 return decodeNeonUAcrossLanesReg<AddvDX, AddvQX>(
1077 q, size, machInst, vd, vn);
1078 case 0x23:
1079 if (size_q == 0x4 || size == 0x3)
1080 return new Unknown64(machInst);
1081 return decodeNeonUAcrossLanesLongReg<UaddlvDX, UaddlvQX,
1082 UaddlvBQX>(
1083 q, size, machInst, vd, vn);
1084 case 0x2a:
1085 if (size_q == 0x4 || size == 0x3)
1086 return new Unknown64(machInst);
1087 return decodeNeonUAcrossLanesReg<UmaxvDX, UmaxvQX>(
1088 q, size, machInst, vd, vn);
1089 case 0x2c:
1090 if (sz_q != 0x1)
1091 return new Unknown64(machInst);
1092 if (size < 0x2) {
1093 if (q)
1094 return new FmaxnmvQX<uint32_t>(machInst, vd, vn);
1095 else
1096 return new Unknown64(machInst);
1097 } else {
1098 if (q)
1099 return new FminnmvQX<uint32_t>(machInst, vd, vn);
1100 else
1101 return new Unknown64(machInst);
1102 }
1103 case 0x2f:
1104 if (sz_q != 0x1)
1105 return new Unknown64(machInst);
1106 if (size < 0x2) {
1107 if (q)
1108 return new FmaxvQX<uint32_t>(machInst, vd, vn);
1109 else
1110 return new Unknown64(machInst);
1111 } else {
1112 if (q)
1113 return new FminvQX<uint32_t>(machInst, vd, vn);
1114 else
1115 return new Unknown64(machInst);
1116 }
1117 case 0x3a:
1118 if (size_q == 0x4 || size == 0x3)
1119 return new Unknown64(machInst);
1120 return decodeNeonUAcrossLanesReg<UminvDX, UminvQX>(
1121 q, size, machInst, vd, vn);
1122 default:
1123 return new Unknown64(machInst);
1124 }
1125 }
1126
1127 StaticInstPtr
1128 decodeNeonCopy(ExtMachInst machInst)
1129 {
1130 uint8_t q = bits(machInst, 30);
1131 uint8_t op = bits(machInst, 29);
1132 uint8_t imm5 = bits(machInst, 20, 16);
1133 uint8_t imm4 = bits(machInst, 14, 11);
1134
1135 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1136 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1137
1138 uint8_t imm5_pos = findLsbSet(imm5);
1139 uint8_t index1 = 0, index2 = 0;
1140
1141 if (op) {
1142 if (!q || (imm4 & mask(imm5_pos)))
1143 return new Unknown64(machInst);
1144
1145 index1 = bits(imm5, 4, imm5_pos + 1); // dst
1146 index2 = bits(imm4, 3, imm5_pos); // src
1147
1148 switch (imm5_pos) {
1149 case 0:
1150 return new InsElemX<uint8_t>(machInst, vd, vn, index1, index2);
1151 case 1:
1152 return new InsElemX<uint16_t>(machInst, vd, vn, index1, index2);
1153 case 2:
1154 return new InsElemX<uint32_t>(machInst, vd, vn, index1, index2);
1155 case 3:
1156 return new InsElemX<uint64_t>(machInst, vd, vn, index1, index2);
1157 default:
1158 return new Unknown64(machInst);
1159 }
1160 }
1161
1162 switch (imm4) {
1163 case 0x0:
1164 index1 = bits(imm5, 4, imm5_pos + 1);
1165 switch (imm5_pos) {
1166 case 0:
1167 if (q)
1168 return new DupElemQX<uint8_t>(machInst, vd, vn, index1);
1169 else
1170 return new DupElemDX<uint8_t>(machInst, vd, vn, index1);
1171 case 1:
1172 if (q)
1173 return new DupElemQX<uint16_t>(machInst, vd, vn, index1);
1174 else
1175 return new DupElemDX<uint16_t>(machInst, vd, vn, index1);
1176 case 2:
1177 if (q)
1178 return new DupElemQX<uint32_t>(machInst, vd, vn, index1);
1179 else
1180 return new DupElemDX<uint32_t>(machInst, vd, vn, index1);
1181 case 3:
1182 if (q)
1183 return new DupElemQX<uint64_t>(machInst, vd, vn, index1);
1184 else
1185 return new Unknown64(machInst);
1186 default:
1187 return new Unknown64(machInst);
1188 }
1189 case 0x1:
1190 switch (imm5) {
1191 case 0x1:
1192 if (q)
1193 return new DupGprWQX<uint8_t>(machInst, vd, vn);
1194 else
1195 return new DupGprWDX<uint8_t>(machInst, vd, vn);
1196 case 0x2:
1197 if (q)
1198 return new DupGprWQX<uint16_t>(machInst, vd, vn);
1199 else
1200 return new DupGprWDX<uint16_t>(machInst, vd, vn);
1201 case 0x4:
1202 if (q)
1203 return new DupGprWQX<uint32_t>(machInst, vd, vn);
1204 else
1205 return new DupGprWDX<uint32_t>(machInst, vd, vn);
1206 case 0x8:
1207 if (q)
1208 return new DupGprXQX<uint64_t>(machInst, vd, vn);
1209 else
1210 return new Unknown64(machInst);
1211 }
1212 case 0x3:
1213 index1 = imm5 >> (imm5_pos + 1);
1214 switch (imm5_pos) {
1215 case 0:
1216 return new InsGprWX<uint8_t>(machInst, vd, vn, index1);
1217 case 1:
1218 return new InsGprWX<uint16_t>(machInst, vd, vn, index1);
1219 case 2:
1220 return new InsGprWX<uint32_t>(machInst, vd, vn, index1);
1221 case 3:
1222 return new InsGprXX<uint64_t>(machInst, vd, vn, index1);
1223 default:
1224 return new Unknown64(machInst);
1225 }
1226 case 0x5:
1227 index1 = bits(imm5, 4, imm5_pos + 1);
1228 switch (imm5_pos) {
1229 case 0:
1230 if (q)
1231 return new SmovXX<int8_t>(machInst, vd, vn, index1);
1232 else
1233 return new SmovWX<int8_t>(machInst, vd, vn, index1);
1234 case 1:
1235 if (q)
1236 return new SmovXX<int16_t>(machInst, vd, vn, index1);
1237 else
1238 return new SmovWX<int16_t>(machInst, vd, vn, index1);
1239 case 2:
1240 if (q)
1241 return new SmovXX<int32_t>(machInst, vd, vn, index1);
1242 else
1243 return new Unknown64(machInst);
1244 default:
1245 return new Unknown64(machInst);
1246 }
1247 case 0x7:
1248 index1 = imm5 >> (imm5_pos + 1);
1249
1250 if ((q && imm5_pos != 3) || (!q && imm5_pos >= 3))
1251 return new Unknown64(machInst);
1252
1253 switch (imm5_pos) {
1254 case 0:
1255 return new UmovWX<uint8_t>(machInst, vd, vn, index1);
1256 case 1:
1257 return new UmovWX<uint16_t>(machInst, vd, vn, index1);
1258 case 2:
1259 return new UmovWX<uint32_t>(machInst, vd, vn, index1);
1260 case 3:
1261 return new UmovXX<uint64_t>(machInst, vd, vn, index1);
1262 default:
1263 return new Unknown64(machInst);
1264 }
1265 default:
1266 return new Unknown64(machInst);
1267 }
1268 }
1269
91 StaticInstPtr
92 decodeNeon3Same(ExtMachInst machInst)
93 {
94 uint8_t q = bits(machInst, 30);
95 uint8_t u = bits(machInst, 29);
96 uint8_t size = bits(machInst, 23, 22);
97 uint8_t opcode = bits(machInst, 15, 11);
98
99 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
100 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
101 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
102
103 uint8_t size_q = (size << 1) | q;
104 uint8_t sz_q = size_q & 0x3;
105
106 switch (opcode) {
107 case 0x00:
108 if (size == 0x3)
109 return new Unknown64(machInst);
110 if (u)
111 return decodeNeonUThreeSReg<UhaddDX, UhaddQX>(
112 q, size, machInst, vd, vn, vm);
113 else
114 return decodeNeonSThreeSReg<ShaddDX, ShaddQX>(
115 q, size, machInst, vd, vn, vm);
116 case 0x01:
117 if (size_q == 0x6)
118 return new Unknown64(machInst);
119 if (u)
120 return decodeNeonUThreeXReg<UqaddDX, UqaddQX>(
121 q, size, machInst, vd, vn, vm);
122 else
123 return decodeNeonSThreeXReg<SqaddDX, SqaddQX>(
124 q, size, machInst, vd, vn, vm);
125 case 0x02:
126 if (size == 0x3)
127 return new Unknown64(machInst);
128 if (u)
129 return decodeNeonUThreeSReg<UrhaddDX, UrhaddQX>(
130 q, size, machInst, vd, vn, vm);
131 else
132 return decodeNeonSThreeSReg<SrhaddDX, SrhaddQX>(
133 q, size, machInst, vd, vn, vm);
134 case 0x03:
135 switch (size) {
136 case 0x0:
137 if (u) {
138 if (q)
139 return new EorQX<uint64_t>(machInst, vd, vn, vm);
140 else
141 return new EorDX<uint64_t>(machInst, vd, vn, vm);
142 } else {
143 if (q)
144 return new AndQX<uint64_t>(machInst, vd, vn, vm);
145 else
146 return new AndDX<uint64_t>(machInst, vd, vn, vm);
147 }
148 case 0x1:
149 if (u) {
150 if (q)
151 return new BslQX<uint64_t>(machInst, vd, vn, vm);
152 else
153 return new BslDX<uint64_t>(machInst, vd, vn, vm);
154 } else {
155 if (q)
156 return new BicQX<uint64_t>(machInst, vd, vn, vm);
157 else
158 return new BicDX<uint64_t>(machInst, vd, vn, vm);
159 }
160 case 0x2:
161 if (u) {
162 if (q)
163 return new BitQX<uint64_t>(machInst, vd, vn, vm);
164 else
165 return new BitDX<uint64_t>(machInst, vd, vn, vm);
166 } else {
167 if (q)
168 return new OrrQX<uint64_t>(machInst, vd, vn, vm);
169 else
170 return new OrrDX<uint64_t>(machInst, vd, vn, vm);
171 }
172 case 0x3:
173 if (u) {
174 if (q)
175 return new BifQX<uint64_t>(machInst, vd, vn, vm);
176 else
177 return new BifDX<uint64_t>(machInst, vd, vn, vm);
178 } else {
179 if (q)
180 return new OrnQX<uint64_t>(machInst, vd, vn, vm);
181 else
182 return new OrnDX<uint64_t>(machInst, vd, vn, vm);
183 }
184 }
185 case 0x04:
186 if (size == 0x3)
187 return new Unknown64(machInst);
188 if (u)
189 return decodeNeonUThreeSReg<UhsubDX, UhsubQX>(
190 q, size, machInst, vd, vn, vm);
191 else
192 return decodeNeonSThreeSReg<ShsubDX, ShsubQX>(
193 q, size, machInst, vd, vn, vm);
194 case 0x05:
195 if (size_q == 0x6)
196 return new Unknown64(machInst);
197 if (u)
198 return decodeNeonUThreeXReg<UqsubDX, UqsubQX>(
199 q, size, machInst, vd, vn, vm);
200 else
201 return decodeNeonSThreeXReg<SqsubDX, SqsubQX>(
202 q, size, machInst, vd, vn, vm);
203 case 0x06:
204 if (size_q == 0x6)
205 return new Unknown64(machInst);
206 if (u)
207 return decodeNeonUThreeXReg<CmhiDX, CmhiQX>(
208 q, size, machInst, vd, vn, vm);
209 else
210 return decodeNeonSThreeXReg<CmgtDX, CmgtQX>(
211 q, size, machInst, vd, vn, vm);
212 case 0x07:
213 if (size_q == 0x6)
214 return new Unknown64(machInst);
215 if (u)
216 return decodeNeonUThreeXReg<CmhsDX, CmhsQX>(
217 q, size, machInst, vd, vn, vm);
218 else
219 return decodeNeonSThreeXReg<CmgeDX, CmgeQX>(
220 q, size, machInst, vd, vn, vm);
221 case 0x08:
222 if (size_q == 0x6)
223 return new Unknown64(machInst);
224 if (u)
225 return decodeNeonUThreeXReg<UshlDX, UshlQX>(
226 q, size, machInst, vd, vn, vm);
227 else
228 return decodeNeonSThreeXReg<SshlDX, SshlQX>(
229 q, size, machInst, vd, vn, vm);
230 case 0x09:
231 if (size_q == 0x6)
232 return new Unknown64(machInst);
233 if (u)
234 return decodeNeonUThreeXReg<UqshlDX, UqshlQX>(
235 q, size, machInst, vd, vn, vm);
236 else
237 return decodeNeonSThreeXReg<SqshlDX, SqshlQX>(
238 q, size, machInst, vd, vn, vm);
239 case 0x0a:
240 if (size_q == 0x6)
241 return new Unknown64(machInst);
242 if (u)
243 return decodeNeonUThreeXReg<UrshlDX, UrshlQX>(
244 q, size, machInst, vd, vn, vm);
245 else
246 return decodeNeonSThreeXReg<SrshlDX, SrshlQX>(
247 q, size, machInst, vd, vn, vm);
248 case 0x0b:
249 if (size_q == 0x6)
250 return new Unknown64(machInst);
251 if (u)
252 return decodeNeonUThreeXReg<UqrshlDX, UqrshlQX>(
253 q, size, machInst, vd, vn, vm);
254 else
255 return decodeNeonSThreeXReg<SqrshlDX, SqrshlQX>(
256 q, size, machInst, vd, vn, vm);
257 case 0x0c:
258 if (size == 0x3)
259 return new Unknown64(machInst);
260 if (u)
261 return decodeNeonUThreeSReg<UmaxDX, UmaxQX>(
262 q, size, machInst, vd, vn, vm);
263 else
264 return decodeNeonSThreeSReg<SmaxDX, SmaxQX>(
265 q, size, machInst, vd, vn, vm);
266 case 0x0d:
267 if (size == 0x3)
268 return new Unknown64(machInst);
269 if (u)
270 return decodeNeonUThreeSReg<UminDX, UminQX>(
271 q, size, machInst, vd, vn, vm);
272 else
273 return decodeNeonSThreeSReg<SminDX, SminQX>(
274 q, size, machInst, vd, vn, vm);
275 case 0x0e:
276 if (size == 0x3)
277 return new Unknown64(machInst);
278 if (u)
279 return decodeNeonUThreeSReg<UabdDX, UabdQX>(
280 q, size, machInst, vd, vn, vm);
281 else
282 return decodeNeonSThreeSReg<SabdDX, SabdQX>(
283 q, size, machInst, vd, vn, vm);
284 case 0x0f:
285 if (size == 0x3)
286 return new Unknown64(machInst);
287 if (u)
288 return decodeNeonUThreeSReg<UabaDX, UabaQX>(
289 q, size, machInst, vd, vn, vm);
290 else
291 return decodeNeonSThreeSReg<SabaDX, SabaQX>(
292 q, size, machInst, vd, vn, vm);
293 case 0x10:
294 if (size_q == 0x6)
295 return new Unknown64(machInst);
296 if (u)
297 return decodeNeonUThreeXReg<SubDX, SubQX>(
298 q, size, machInst, vd, vn, vm);
299 else
300 return decodeNeonUThreeXReg<AddDX, AddQX>(
301 q, size, machInst, vd, vn, vm);
302 case 0x11:
303 if (size_q == 0x6)
304 return new Unknown64(machInst);
305 if (u)
306 return decodeNeonUThreeXReg<CmeqDX, CmeqQX>(
307 q, size, machInst, vd, vn, vm);
308 else
309 return decodeNeonUThreeXReg<CmtstDX, CmtstQX>(
310 q, size, machInst, vd, vn, vm);
311 case 0x12:
312 if (size == 0x3)
313 return new Unknown64(machInst);
314 if (u)
315 return decodeNeonUThreeSReg<MlsDX, MlsQX>(
316 q, size, machInst, vd, vn, vm);
317 else
318 return decodeNeonUThreeSReg<MlaDX, MlaQX>(
319 q, size, machInst, vd, vn, vm);
320 case 0x13:
321 if (size == 0x3 || (size != 0x0 && bits(machInst, 29)))
322 return new Unknown64(machInst);
323 if (u) {
324 if (q)
325 return new PmulQX<uint8_t>(machInst, vd, vn, vm);
326 else
327 return new PmulDX<uint8_t>(machInst, vd, vn, vm);
328 } else {
329 return decodeNeonUThreeSReg<MulDX, MulQX>(
330 q, size, machInst, vd, vn, vm);
331 }
332 case 0x14:
333 if (size == 0x3)
334 return new Unknown64(machInst);
335 if (u)
336 return decodeNeonUThreeSReg<UmaxpDX, UmaxpQX>(
337 q, size, machInst, vd, vn, vm);
338 else
339 return decodeNeonSThreeSReg<SmaxpDX, SmaxpQX>(
340 q, size, machInst, vd, vn, vm);
341 case 0x15:
342 if (size == 0x3)
343 return new Unknown64(machInst);
344 if (u)
345 return decodeNeonUThreeSReg<UminpDX, UminpQX>(
346 q, size, machInst, vd, vn, vm);
347 else
348 return decodeNeonSThreeSReg<SminpDX, SminpQX>(
349 q, size, machInst, vd, vn, vm);
350 case 0x16:
351 if (size == 0x3 || size == 0x0)
352 return new Unknown64(machInst);
353 if (u) {
354 if (q)
355 return decodeNeonSThreeHAndWReg<SqrdmulhQX>(
356 size, machInst, vd, vn, vm);
357 else
358 return decodeNeonSThreeHAndWReg<SqrdmulhDX>(
359 size, machInst, vd, vn, vm);
360 } else {
361 if (q)
362 return decodeNeonSThreeHAndWReg<SqdmulhQX>(
363 size, machInst, vd, vn, vm);
364 else
365 return decodeNeonSThreeHAndWReg<SqdmulhDX>(
366 size, machInst, vd, vn, vm);
367 }
368 case 0x17:
369 if (u || size_q == 0x6)
370 return new Unknown64(machInst);
371 else
372 return decodeNeonUThreeXReg<AddpDX, AddpQX>(
373 q, size, machInst, vd, vn, vm);
374 case 0x18:
375 if (sz_q == 0x2)
376 return new Unknown64(machInst);
377 if (size < 0x2) {
378 if (u)
379 return decodeNeonUThreeFpReg<FmaxnmpDX, FmaxnmpQX>(
380 q, size & 0x1, machInst, vd, vn, vm);
381 else
382 return decodeNeonUThreeFpReg<FmaxnmDX, FmaxnmQX>(
383 q, size & 0x1, machInst, vd, vn, vm);
384 } else {
385 if (u)
386 return decodeNeonUThreeFpReg<FminnmpDX, FminnmpQX>(
387 q, size & 0x1, machInst, vd, vn, vm);
388 else
389 return decodeNeonUThreeFpReg<FminnmDX, FminnmQX>(
390 q, size & 0x1, machInst, vd, vn, vm);
391 }
392 case 0x19:
393 if (size < 0x2) {
394 if (u || sz_q == 0x2)
395 return new Unknown64(machInst);
396 else
397 return decodeNeonUThreeFpReg<FmlaDX, FmlaQX>(
398 q, size & 0x1, machInst, vd, vn, vm);
399 } else {
400 if (u || sz_q == 0x2)
401 return new Unknown64(machInst);
402 else
403 return decodeNeonUThreeFpReg<FmlsDX, FmlsQX>(
404 q, size & 0x1, machInst, vd, vn, vm);
405 }
406 case 0x1a:
407 if (sz_q == 0x2)
408 return new Unknown64(machInst);
409 if (size < 0x2) {
410 if (u)
411 return decodeNeonUThreeFpReg<FaddpDX, FaddpQX>(
412 q, size & 0x1, machInst, vd, vn, vm);
413 else
414 return decodeNeonUThreeFpReg<FaddDX, FaddQX>(
415 q, size & 0x1, machInst, vd, vn, vm);
416 } else {
417 if (u)
418 return decodeNeonUThreeFpReg<FabdDX, FabdQX>(
419 q, size & 0x1, machInst, vd, vn, vm);
420 else
421 return decodeNeonUThreeFpReg<FsubDX, FsubQX>(
422 q, size & 0x1, machInst, vd, vn, vm);
423 }
424 case 0x1b:
425 if (size < 0x2 && sz_q != 0x2) {
426 if (u)
427 return decodeNeonUThreeFpReg<FmulDX, FmulQX>(
428 q, size & 0x1, machInst, vd, vn, vm);
429 else
430 return decodeNeonUThreeFpReg<FmulxDX, FmulxQX>(
431 q, size & 0x1, machInst, vd, vn, vm);
432 } else {
433 return new Unknown64(machInst);
434 }
435 case 0x1c:
436 if (size < 0x2) {
437 if (u)
438 return decodeNeonUThreeFpReg<FcmgeDX, FcmgeQX>(
439 q, size & 0x1, machInst, vd, vn, vm);
440 else
441 return decodeNeonUThreeFpReg<FcmeqDX, FcmeqQX>(
442 q, size & 0x1, machInst, vd, vn, vm);
443 } else {
444 if (u)
445 return decodeNeonUThreeFpReg<FcmgtDX, FcmgtQX>(
446 q, size & 0x1, machInst, vd, vn, vm);
447 else
448 return new Unknown64(machInst);
449 }
450 case 0x1d:
451 if (size < 0x2) {
452 if (u)
453 return decodeNeonUThreeFpReg<FacgeDX, FacgeQX>(
454 q, size & 0x1, machInst, vd, vn, vm);
455 else
456 return new Unknown64(machInst);
457 } else {
458 if (u)
459 return decodeNeonUThreeFpReg<FacgtDX, FacgtQX>(
460 q, size & 0x1, machInst, vd, vn, vm);
461 else
462 return new Unknown64(machInst);
463 }
464 case 0x1e:
465 if (sz_q == 0x2)
466 return new Unknown64(machInst);
467 if (size < 0x2) {
468 if (u)
469 return decodeNeonUThreeFpReg<FmaxpDX, FmaxpQX>(
470 q, size & 0x1, machInst, vd, vn, vm);
471 else
472 return decodeNeonUThreeFpReg<FmaxDX, FmaxQX>(
473 q, size & 0x1, machInst, vd, vn, vm);
474 } else {
475 if (u)
476 return decodeNeonUThreeFpReg<FminpDX, FminpQX>(
477 q, size & 0x1, machInst, vd, vn, vm);
478 else
479 return decodeNeonUThreeFpReg<FminDX, FminQX>(
480 q, size & 0x1, machInst, vd, vn, vm);
481 }
482 case 0x1f:
483 if (sz_q == 0x2)
484 return new Unknown64(machInst);
485 if (size < 0x2) {
486 if (u)
487 return decodeNeonUThreeFpReg<FdivDX, FdivQX>(
488 q, size & 0x1, machInst, vd, vn, vm);
489 else
490 return decodeNeonUThreeFpReg<FrecpsDX, FrecpsQX>(
491 q, size & 0x1, machInst, vd, vn, vm);
492 } else {
493 if (u)
494 return new Unknown64(machInst);
495 else
496 return decodeNeonUThreeFpReg<FrsqrtsDX, FrsqrtsQX>(
497 q, size & 0x1, machInst, vd, vn, vm);
498 }
499 default:
500 return new Unknown64(machInst);
501 }
502 }
503
504 StaticInstPtr
505 decodeNeon3Diff(ExtMachInst machInst)
506 {
507 uint8_t q = bits(machInst, 30);
508 uint8_t u = bits(machInst, 29);
509 uint8_t size = bits(machInst, 23, 22);
510 uint8_t opcode = bits(machInst, 15, 12);
511
512 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
513 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
514 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
515
516 switch (opcode) {
517 case 0x0:
518 if (size == 0x3)
519 return new Unknown64(machInst);
520 if (u)
521 return decodeNeonUThreeSReg<UaddlX, Uaddl2X>(
522 q, size, machInst, vd, vn, vm);
523 else
524 return decodeNeonSThreeSReg<SaddlX, Saddl2X>(
525 q, size, machInst, vd, vn, vm);
526 case 0x1:
527 if (size == 0x3)
528 return new Unknown64(machInst);
529 if (u)
530 return decodeNeonUThreeSReg<UaddwX, Uaddw2X>(
531 q, size, machInst, vd, vn, vm);
532 else
533 return decodeNeonSThreeSReg<SaddwX, Saddw2X>(
534 q, size, machInst, vd, vn, vm);
535 case 0x2:
536 if (size == 0x3)
537 return new Unknown64(machInst);
538 if (u)
539 return decodeNeonUThreeSReg<UsublX, Usubl2X>(
540 q, size, machInst, vd, vn, vm);
541 else
542 return decodeNeonSThreeSReg<SsublX, Ssubl2X>(
543 q, size, machInst, vd, vn, vm);
544 case 0x3:
545 if (size == 0x3)
546 return new Unknown64(machInst);
547 if (u)
548 return decodeNeonUThreeSReg<UsubwX, Usubw2X>(
549 q, size, machInst, vd, vn, vm);
550 else
551 return decodeNeonSThreeSReg<SsubwX, Ssubw2X>(
552 q, size, machInst, vd, vn, vm);
553 case 0x4:
554 if (size == 0x3)
555 return new Unknown64(machInst);
556 if (u)
557 return decodeNeonUThreeSReg<RaddhnX, Raddhn2X>(
558 q, size, machInst, vd, vn, vm);
559 else
560 return decodeNeonUThreeSReg<AddhnX, Addhn2X>(
561 q, size, machInst, vd, vn, vm);
562 case 0x5:
563 if (size == 0x3)
564 return new Unknown64(machInst);
565 if (u)
566 return decodeNeonUThreeSReg<UabalX, Uabal2X>(
567 q, size, machInst, vd, vn, vm);
568 else
569 return decodeNeonSThreeSReg<SabalX, Sabal2X>(
570 q, size, machInst, vd, vn, vm);
571 case 0x6:
572 if (size == 0x3)
573 return new Unknown64(machInst);
574 if (u)
575 return decodeNeonUThreeSReg<RsubhnX, Rsubhn2X>(
576 q, size, machInst, vd, vn, vm);
577 else
578 return decodeNeonUThreeSReg<SubhnX, Subhn2X>(
579 q, size, machInst, vd, vn, vm);
580 case 0x7:
581 if (size == 0x3)
582 return new Unknown64(machInst);
583 if (u)
584 return decodeNeonUThreeSReg<UabdlX, Uabdl2X>(
585 q, size, machInst, vd, vn, vm);
586 else
587 return decodeNeonSThreeSReg<SabdlX, Sabdl2X>(
588 q, size, machInst, vd, vn, vm);
589 case 0x8:
590 if (size == 0x3)
591 return new Unknown64(machInst);
592 if (u)
593 return decodeNeonUThreeSReg<UmlalX, Umlal2X>(
594 q, size, machInst, vd, vn, vm);
595 else
596 return decodeNeonSThreeSReg<SmlalX, Smlal2X>(
597 q, size, machInst, vd, vn, vm);
598 case 0x9:
599 if (u || (size == 0x0 || size == 0x3)) {
600 return new Unknown64(machInst);
601 } else {
602 if (q) {
603 return decodeNeonSThreeHAndWReg<Sqdmlal2X>(
604 size, machInst, vd, vn, vm);
605 } else {
606 return decodeNeonSThreeHAndWReg<SqdmlalX>(
607 size, machInst, vd, vn, vm);
608 }
609 }
610 case 0xa:
611 if (size == 0x3)
612 return new Unknown64(machInst);
613 if (u)
614 return decodeNeonUThreeSReg<UmlslX, Umlsl2X>(
615 q, size, machInst, vd, vn, vm);
616 else
617 return decodeNeonSThreeSReg<SmlslX, Smlsl2X>(
618 q, size, machInst, vd, vn, vm);
619 case 0xb:
620 if (u || (size == 0x0 || size == 0x3)) {
621 return new Unknown64(machInst);
622 } else {
623 if (q) {
624 return decodeNeonSThreeHAndWReg<Sqdmlsl2X>(
625 size, machInst, vd, vn, vm);
626 } else {
627 return decodeNeonSThreeHAndWReg<SqdmlslX>(
628 size, machInst, vd, vn, vm);
629 }
630 }
631 case 0xc:
632 if (size == 0x3)
633 return new Unknown64(machInst);
634 if (u)
635 return decodeNeonUThreeSReg<UmullX, Umull2X>(
636 q, size, machInst, vd, vn, vm);
637 else
638 return decodeNeonSThreeSReg<SmullX, Smull2X>(
639 q, size, machInst, vd, vn, vm);
640 case 0xd:
641 if (u || (size == 0x0 || size == 0x3)) {
642 return new Unknown64(machInst);
643 } else {
644 if (q) {
645 return decodeNeonSThreeHAndWReg<Sqdmull2X>(
646 size, machInst, vd, vn, vm);
647 } else {
648 return decodeNeonSThreeHAndWReg<SqdmullX>(
649 size, machInst, vd, vn, vm);
650 }
651 }
652 case 0xe:
653 if (u || size != 0) {
654 return new Unknown64(machInst);
655 } else {
656 if (q)
657 return new Pmull2X<uint8_t>(machInst, vd, vn, vm);
658 else
659 return new PmullX<uint8_t>(machInst, vd, vn, vm);
660 }
661 default:
662 return new Unknown64(machInst);
663 }
664 }
665
666 StaticInstPtr
667 decodeNeon2RegMisc(ExtMachInst machInst)
668 {
669 uint8_t q = bits(machInst, 30);
670 uint8_t u = bits(machInst, 29);
671 uint8_t size = bits(machInst, 23, 22);
672 uint8_t opcode = bits(machInst, 16, 12);
673
674 IntRegIndex vd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
675 IntRegIndex vn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
676
677 uint8_t size_q = (size << 1) | q;
678 uint8_t sz_q = size_q & 0x3;
679 uint8_t op = (uint8_t)((bits(machInst, 12) << 1) |
680 bits(machInst, 29));
681 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
682
683 switch (switchVal) {
684 case 0x00:
685 if (op + size >= 3)
686 return new Unknown64(machInst);
687 return decodeNeonUTwoMiscSReg<Rev64DX, Rev64QX>(
688 q, size, machInst, vd, vn);
689 case 0x01:
690 if (op + size >= 3)
691 return new Unknown64(machInst);
692 if (q)
693 return new Rev16QX<uint8_t>(machInst, vd, vn);
694 else
695 return new Rev16DX<uint8_t>(machInst, vd, vn);
696 case 0x02:
697 if (size == 0x3)
698 return new Unknown64(machInst);
699 return decodeNeonSTwoMiscSReg<SaddlpDX, SaddlpQX>(
700 q, size, machInst, vd, vn);
701 case 0x03:
702 if (size_q == 0x6)
703 return new Unknown64(machInst);
704 return decodeNeonUTwoMiscXReg<SuqaddDX, SuqaddQX>(
705 q, size, machInst, vd, vn);
706 case 0x04:
707 if (size == 0x3)
708 return new Unknown64(machInst);
709 return decodeNeonSTwoMiscSReg<ClsDX, ClsQX>(
710 q, size, machInst, vd, vn);
711 case 0x05:
712 if (size != 0x0)
713 return new Unknown64(machInst);
714 if (q)
715 return new CntQX<uint8_t>(machInst, vd, vn);
716 else
717 return new CntDX<uint8_t>(machInst, vd, vn);
718 case 0x06:
719 if (size == 0x3)
720 return new Unknown64(machInst);
721 return decodeNeonSTwoMiscSReg<SadalpDX, SadalpQX>(
722 q, size, machInst, vd, vn);
723 case 0x07:
724 if (size_q == 0x6)
725 return new Unknown64(machInst);
726 return decodeNeonSTwoMiscXReg<SqabsDX, SqabsQX>(
727 q, size, machInst, vd, vn);
728 case 0x08:
729 if (size_q == 0x6)
730 return new Unknown64(machInst);
731 return decodeNeonSTwoMiscXReg<CmgtZeroDX, CmgtZeroQX>(
732 q, size, machInst, vd, vn);
733 case 0x09:
734 if (size_q == 0x6)
735 return new Unknown64(machInst);
736 return decodeNeonSTwoMiscXReg<CmeqZeroDX, CmeqZeroQX>(
737 q, size, machInst, vd, vn);
738 case 0x0a:
739 if (size_q == 0x6)
740 return new Unknown64(machInst);
741 return decodeNeonSTwoMiscXReg<CmltZeroDX, CmltZeroQX>(
742 q, size, machInst, vd, vn);
743 case 0x0b:
744 if (size_q == 0x6)
745 return new Unknown64(machInst);
746 return decodeNeonSTwoMiscXReg<AbsDX, AbsQX>(
747 q, size, machInst, vd, vn);
748 case 0x0c:
749 if (size < 0x2 || sz_q == 0x2)
750 return new Unknown64(machInst);
751 return decodeNeonUTwoMiscFpReg<FcmgtZeroDX, FcmgtZeroQX>(
752 q, size & 0x1, machInst, vd, vn);
753 case 0x0d:
754 if (size < 0x2 || sz_q == 0x2)
755 return new Unknown64(machInst);
756 return decodeNeonUTwoMiscFpReg<FcmeqZeroDX, FcmeqZeroQX>(
757 q, size & 0x1, machInst, vd, vn);
758 case 0x0e:
759 if (size < 0x2 || sz_q == 0x2)
760 return new Unknown64(machInst);
761 return decodeNeonUTwoMiscFpReg<FcmltZeroDX, FcmltZeroQX>(
762 q, size & 0x1, machInst, vd, vn);
763 case 0x0f:
764 if (size < 0x2 || sz_q == 0x2)
765 return new Unknown64(machInst);
766 return decodeNeonUTwoMiscFpReg<FabsDX, FabsQX>(
767 q, size & 0x1, machInst, vd, vn);
768 case 0x12:
769 if (size == 0x3)
770 return new Unknown64(machInst);
771 return decodeNeonUTwoMiscSReg<XtnX, Xtn2X>(
772 q, size, machInst, vd, vn);
773 case 0x14:
774 if (size == 0x3)
775 return new Unknown64(machInst);
776 return decodeNeonSTwoMiscSReg<SqxtnX, Sqxtn2X>(
777 q, size, machInst, vd, vn);
778 case 0x16:
779 if (size > 0x1)
780 return new Unknown64(machInst);
781 if (q) {
782 if (size)
783 return new Fcvtn2X<uint32_t>(machInst, vd, vn);
784 else
785 return new Fcvtn2X<uint16_t>(machInst, vd, vn);
786 } else {
787 if (size)
788 return new FcvtnX<uint32_t>(machInst, vd, vn);
789 else
790 return new FcvtnX<uint16_t>(machInst, vd, vn);
791 }
792 case 0x17:
793 if (size > 0x1)
794 return new Unknown64(machInst);
795 if (q) {
796 if (size)
797 return new Fcvtl2X<uint32_t>(machInst, vd, vn);
798 else
799 return new Fcvtl2X<uint16_t>(machInst, vd, vn);
800 } else {
801 if (size)
802 return new FcvtlX<uint32_t>(machInst, vd, vn);
803 else
804 return new FcvtlX<uint16_t>(machInst, vd, vn);
805 }
806 case 0x18:
807 if (sz_q == 0x2)
808 return new Unknown64(machInst);
809 if (size < 0x2)
810 return decodeNeonUTwoMiscFpReg<FrintnDX, FrintnQX>(
811 q, size & 0x1, machInst, vd, vn);
812 else
813 return decodeNeonUTwoMiscFpReg<FrintpDX, FrintpQX>(
814 q, size & 0x1, machInst, vd, vn);
815 case 0x19:
816 if (sz_q == 0x2)
817 return new Unknown64(machInst);
818 if (size < 0x2)
819 return decodeNeonUTwoMiscFpReg<FrintmDX, FrintmQX>(
820 q, size & 0x1, machInst, vd, vn);
821 else
822 return decodeNeonUTwoMiscFpReg<FrintzDX, FrintzQX>(
823 q, size & 0x1, machInst, vd, vn);
824 case 0x1a:
825 if (sz_q == 0x2)
826 return new Unknown64(machInst);
827 if (size < 0x2)
828 return decodeNeonUTwoMiscFpReg<FcvtnsDX, FcvtnsQX>(
829 q, size & 0x1, machInst, vd, vn);
830 else
831 return decodeNeonUTwoMiscFpReg<FcvtpsDX, FcvtpsQX>(
832 q, size & 0x1, machInst, vd, vn);
833 case 0x1b:
834 if (sz_q == 0x2)
835 return new Unknown64(machInst);
836 if (size < 0x2)
837 return decodeNeonUTwoMiscFpReg<FcvtmsDX, FcvtmsQX>(
838 q, size & 0x1, machInst, vd, vn);
839 else
840 return decodeNeonUTwoMiscFpReg<FcvtzsIntDX, FcvtzsIntQX>(
841 q, size & 0x1, machInst, vd, vn);
842 case 0x1c:
843 if (size < 0x2) {
844 if (sz_q == 0x2)
845 return new Unknown64(machInst);
846 return decodeNeonUTwoMiscFpReg<FcvtasDX, FcvtasQX>(
847 q, size & 0x1, machInst, vd, vn);
848 } else {
849 if (size & 0x1)
850 return new Unknown64(machInst);
851 if (q)
852 return new UrecpeQX<uint32_t>(machInst, vd, vn);
853 else
854 return new UrecpeDX<uint32_t>(machInst, vd, vn);
855 }
856 case 0x1d:
857 if (sz_q == 0x2)
858 return new Unknown64(machInst);
859 if (size < 0x2) {
860 if (q) {
861 if (size & 0x1)
862 return new ScvtfIntDQX<uint64_t>(machInst, vd, vn);
863 else
864 return new ScvtfIntSQX<uint32_t>(machInst, vd, vn);
865 } else {
866 if (size & 0x1)
867 return new Unknown(machInst);
868 else
869 return new ScvtfIntDX<uint32_t>(machInst, vd, vn);
870 }
871 } else {
872 return decodeNeonUTwoMiscFpReg<FrecpeDX, FrecpeQX>(
873 q, size & 0x1, machInst, vd, vn);
874 }
875 case 0x20:
876 if (op + size >= 3)
877 return new Unknown64(machInst);
878 if (q) {
879 if (size & 0x1)
880 return new Rev32QX<uint16_t>(machInst, vd, vn);
881 else
882 return new Rev32QX<uint8_t>(machInst, vd, vn);
883 } else {
884 if (size & 0x1)
885 return new Rev32DX<uint16_t>(machInst, vd, vn);
886 else
887 return new Rev32DX<uint8_t>(machInst, vd, vn);
888 }
889 case 0x22:
890 if (size == 0x3)
891 return new Unknown64(machInst);
892 return decodeNeonUTwoMiscSReg<UaddlpDX, UaddlpQX>(
893 q, size, machInst, vd, vn);
894 case 0x23:
895 if (size_q == 0x6)
896 return new Unknown64(machInst);
897 return decodeNeonUTwoMiscXReg<UsqaddDX, UsqaddQX>(
898 q, size, machInst, vd, vn);
899 return new Unknown64(machInst);
900 case 0x24:
901 if (size == 0x3)
902 return new Unknown64(machInst);
903 return decodeNeonSTwoMiscSReg<ClzDX, ClzQX>(
904 q, size, machInst, vd, vn);
905 case 0x25:
906 if (size == 0x0) {
907 if (q)
908 return new MvnQX<uint64_t>(machInst, vd, vn);
909 else
910 return new MvnDX<uint64_t>(machInst, vd, vn);
911 } else if (size == 0x1) {
912 if (q)
913 return new RbitQX<uint8_t>(machInst, vd, vn);
914 else
915 return new RbitDX<uint8_t>(machInst, vd, vn);
916 } else {
917 return new Unknown64(machInst);
918 }
919 case 0x26:
920 if (size == 0x3)
921 return new Unknown64(machInst);
922 return decodeNeonUTwoMiscSReg<UadalpDX, UadalpQX>(
923 q, size, machInst, vd, vn);
924 case 0x27:
925 if (size_q == 0x6)
926 return new Unknown64(machInst);
927 return decodeNeonSTwoMiscXReg<SqnegDX, SqnegQX>(
928 q, size, machInst, vd, vn);
929 case 0x28:
930 if (size_q == 0x6)
931 return new Unknown64(machInst);
932 return decodeNeonSTwoMiscXReg<CmgeZeroDX, CmgeZeroQX>(
933 q, size, machInst, vd, vn);
934 case 0x29:
935 if (size_q == 0x6)
936 return new Unknown64(machInst);
937 return decodeNeonSTwoMiscXReg<CmleZeroDX, CmleZeroQX>(
938 q, size, machInst, vd, vn);
939 case 0x2b:
940 if (size_q == 0x6)
941 return new Unknown64(machInst);
942 return decodeNeonSTwoMiscXReg<NegDX, NegQX>(
943 q, size, machInst, vd, vn);
944 case 0x2c:
945 if (size < 0x2 || sz_q == 0x2)
946 return new Unknown64(machInst);
947 return decodeNeonUTwoMiscFpReg<FcmgeZeroDX, FcmgeZeroQX>(
948 q, size & 0x1, machInst, vd, vn);
949 case 0x2d:
950 if (size < 0x2 || sz_q == 0x2)
951 return new Unknown64(machInst);
952 return decodeNeonUTwoMiscFpReg<FcmleZeroDX, FcmleZeroQX>(
953 q, size & 0x1, machInst, vd, vn);
954 case 0x2f:
955 if (size < 0x2 || size_q == 0x6)
956 return new Unknown64(machInst);
957 return decodeNeonUTwoMiscFpReg<FnegDX, FnegQX>(
958 q, size & 0x1, machInst, vd, vn);
959 case 0x32:
960 if (size == 0x3)
961 return new Unknown64(machInst);
962 return decodeNeonSTwoMiscSReg<SqxtunX, Sqxtun2X>(
963 q, size, machInst, vd, vn);
964 case 0x33:
965 if (size == 0x3)
966 return new Unknown64(machInst);
967 return decodeNeonUTwoMiscSReg<ShllX, Shll2X>(
968 q, size, machInst, vd, vn);
969 case 0x34:
970 if (size == 0x3)
971 return new Unknown64(machInst);
972 return decodeNeonUTwoMiscSReg<UqxtnX, Uqxtn2X>(
973 q, size, machInst, vd, vn);
974 case 0x36:
975 if (size != 0x1)
976 return new Unknown64(machInst);
977 if (q)
978 return new Fcvtxn2X<uint32_t>(machInst, vd, vn);
979 else
980 return new FcvtxnX<uint32_t>(machInst, vd, vn);
981 case 0x38:
982 if (size > 0x1 || sz_q == 0x2)
983 return new Unknown64(machInst);
984 return decodeNeonUTwoMiscFpReg<FrintaDX, FrintaQX>(
985 q, size & 0x1, machInst, vd, vn);
986 case 0x39:
987 if (sz_q == 0x2)
988 return new Unknown64(machInst);
989 if (size < 0x2)
990 return decodeNeonUTwoMiscFpReg<FrintxDX, FrintxQX>(
991 q, size & 0x1, machInst, vd, vn);
992 else
993 return decodeNeonUTwoMiscFpReg<FrintiDX, FrintiQX>(
994 q, size & 0x1, machInst, vd, vn);
995 case 0x3a:
996 if (sz_q == 0x2)
997 return new Unknown64(machInst);
998 if (size < 0x2)
999 return decodeNeonUTwoMiscFpReg<FcvtnuDX, FcvtnuQX>(
1000 q, size & 0x1, machInst, vd, vn);
1001 else
1002 return decodeNeonUTwoMiscFpReg<FcvtpuDX, FcvtpuQX>(
1003 q, size & 0x1, machInst, vd, vn);
1004 case 0x3b:
1005 if (sz_q == 0x2)
1006 return new Unknown64(machInst);
1007 if (size < 0x2)
1008 return decodeNeonUTwoMiscFpReg<FcvtmuDX, FcvtmuQX>(
1009 q, size & 0x1, machInst, vd, vn);
1010 else
1011 return decodeNeonUTwoMiscFpReg<FcvtzuIntDX, FcvtzuIntQX>(
1012 q, size & 0x1, machInst, vd, vn);
1013 case 0x3c:
1014 if (size < 0x2) {
1015 return decodeNeonUTwoMiscFpReg<FcvtauDX, FcvtauQX>(
1016 q, size & 0x1, machInst, vd, vn);
1017 } else if (size == 0x2) {
1018 if (q)
1019 return new UrsqrteQX<uint32_t>(machInst, vd, vn);
1020 else
1021 return new UrsqrteDX<uint32_t>(machInst, vd, vn);
1022 } else {
1023 return new Unknown64(machInst);
1024 }
1025 case 0x3d:
1026 if (sz_q == 0x2)
1027 return new Unknown64(machInst);
1028 if (size < 0x2)
1029 return decodeNeonUTwoMiscFpReg<UcvtfIntDX, UcvtfIntQX>(
1030 q, size & 0x1, machInst, vd, vn);
1031 else
1032 return decodeNeonUTwoMiscFpReg<FrsqrteDX, FrsqrteQX>(
1033 q, size & 0x1, machInst, vd, vn);
1034 case 0x3f:
1035 if (size < 0x2 || sz_q == 0x2)
1036 return new Unknown64(machInst);
1037 return decodeNeonUTwoMiscFpReg<FsqrtDX, FsqrtQX>(
1038 q, size & 0x1, machInst, vd, vn);
1039 default:
1040 return new Unknown64(machInst);
1041 }
1042 }
1043
1044 StaticInstPtr
1045 decodeNeonAcrossLanes(ExtMachInst machInst)
1046 {
1047 uint8_t q = bits(machInst, 30);
1048 uint8_t u = bits(machInst, 29);
1049 uint8_t size = bits(machInst, 23, 22);
1050 uint8_t opcode = bits(machInst, 16, 12);
1051
1052 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1053 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1054
1055 uint8_t size_q = (size << 1) | q;
1056 uint8_t sz_q = size_q & 0x3;
1057 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
1058
1059 switch (switchVal) {
1060 case 0x03:
1061 if (size_q == 0x4 || size == 0x3)
1062 return new Unknown64(machInst);
1063 return decodeNeonSAcrossLanesLongReg<SaddlvDX, SaddlvQX,
1064 SaddlvBQX>(
1065 q, size, machInst, vd, vn);
1066 case 0x0a:
1067 if (size_q == 0x4 || size == 0x3)
1068 return new Unknown64(machInst);
1069 return decodeNeonSAcrossLanesReg<SmaxvDX, SmaxvQX>(
1070 q, size, machInst, vd, vn);
1071 case 0x1a:
1072 if (size_q == 0x4 || size == 0x3)
1073 return new Unknown64(machInst);
1074 return decodeNeonSAcrossLanesReg<SminvDX, SminvQX>(
1075 q, size, machInst, vd, vn);
1076 case 0x1b:
1077 if (size_q == 0x4 || size == 0x3)
1078 return new Unknown64(machInst);
1079 return decodeNeonUAcrossLanesReg<AddvDX, AddvQX>(
1080 q, size, machInst, vd, vn);
1081 case 0x23:
1082 if (size_q == 0x4 || size == 0x3)
1083 return new Unknown64(machInst);
1084 return decodeNeonUAcrossLanesLongReg<UaddlvDX, UaddlvQX,
1085 UaddlvBQX>(
1086 q, size, machInst, vd, vn);
1087 case 0x2a:
1088 if (size_q == 0x4 || size == 0x3)
1089 return new Unknown64(machInst);
1090 return decodeNeonUAcrossLanesReg<UmaxvDX, UmaxvQX>(
1091 q, size, machInst, vd, vn);
1092 case 0x2c:
1093 if (sz_q != 0x1)
1094 return new Unknown64(machInst);
1095 if (size < 0x2) {
1096 if (q)
1097 return new FmaxnmvQX<uint32_t>(machInst, vd, vn);
1098 else
1099 return new Unknown64(machInst);
1100 } else {
1101 if (q)
1102 return new FminnmvQX<uint32_t>(machInst, vd, vn);
1103 else
1104 return new Unknown64(machInst);
1105 }
1106 case 0x2f:
1107 if (sz_q != 0x1)
1108 return new Unknown64(machInst);
1109 if (size < 0x2) {
1110 if (q)
1111 return new FmaxvQX<uint32_t>(machInst, vd, vn);
1112 else
1113 return new Unknown64(machInst);
1114 } else {
1115 if (q)
1116 return new FminvQX<uint32_t>(machInst, vd, vn);
1117 else
1118 return new Unknown64(machInst);
1119 }
1120 case 0x3a:
1121 if (size_q == 0x4 || size == 0x3)
1122 return new Unknown64(machInst);
1123 return decodeNeonUAcrossLanesReg<UminvDX, UminvQX>(
1124 q, size, machInst, vd, vn);
1125 default:
1126 return new Unknown64(machInst);
1127 }
1128 }
1129
1130 StaticInstPtr
1131 decodeNeonCopy(ExtMachInst machInst)
1132 {
1133 uint8_t q = bits(machInst, 30);
1134 uint8_t op = bits(machInst, 29);
1135 uint8_t imm5 = bits(machInst, 20, 16);
1136 uint8_t imm4 = bits(machInst, 14, 11);
1137
1138 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1139 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1140
1141 uint8_t imm5_pos = findLsbSet(imm5);
1142 uint8_t index1 = 0, index2 = 0;
1143
1144 if (op) {
1145 if (!q || (imm4 & mask(imm5_pos)))
1146 return new Unknown64(machInst);
1147
1148 index1 = bits(imm5, 4, imm5_pos + 1); // dst
1149 index2 = bits(imm4, 3, imm5_pos); // src
1150
1151 switch (imm5_pos) {
1152 case 0:
1153 return new InsElemX<uint8_t>(machInst, vd, vn, index1, index2);
1154 case 1:
1155 return new InsElemX<uint16_t>(machInst, vd, vn, index1, index2);
1156 case 2:
1157 return new InsElemX<uint32_t>(machInst, vd, vn, index1, index2);
1158 case 3:
1159 return new InsElemX<uint64_t>(machInst, vd, vn, index1, index2);
1160 default:
1161 return new Unknown64(machInst);
1162 }
1163 }
1164
1165 switch (imm4) {
1166 case 0x0:
1167 index1 = bits(imm5, 4, imm5_pos + 1);
1168 switch (imm5_pos) {
1169 case 0:
1170 if (q)
1171 return new DupElemQX<uint8_t>(machInst, vd, vn, index1);
1172 else
1173 return new DupElemDX<uint8_t>(machInst, vd, vn, index1);
1174 case 1:
1175 if (q)
1176 return new DupElemQX<uint16_t>(machInst, vd, vn, index1);
1177 else
1178 return new DupElemDX<uint16_t>(machInst, vd, vn, index1);
1179 case 2:
1180 if (q)
1181 return new DupElemQX<uint32_t>(machInst, vd, vn, index1);
1182 else
1183 return new DupElemDX<uint32_t>(machInst, vd, vn, index1);
1184 case 3:
1185 if (q)
1186 return new DupElemQX<uint64_t>(machInst, vd, vn, index1);
1187 else
1188 return new Unknown64(machInst);
1189 default:
1190 return new Unknown64(machInst);
1191 }
1192 case 0x1:
1193 switch (imm5) {
1194 case 0x1:
1195 if (q)
1196 return new DupGprWQX<uint8_t>(machInst, vd, vn);
1197 else
1198 return new DupGprWDX<uint8_t>(machInst, vd, vn);
1199 case 0x2:
1200 if (q)
1201 return new DupGprWQX<uint16_t>(machInst, vd, vn);
1202 else
1203 return new DupGprWDX<uint16_t>(machInst, vd, vn);
1204 case 0x4:
1205 if (q)
1206 return new DupGprWQX<uint32_t>(machInst, vd, vn);
1207 else
1208 return new DupGprWDX<uint32_t>(machInst, vd, vn);
1209 case 0x8:
1210 if (q)
1211 return new DupGprXQX<uint64_t>(machInst, vd, vn);
1212 else
1213 return new Unknown64(machInst);
1214 }
1215 case 0x3:
1216 index1 = imm5 >> (imm5_pos + 1);
1217 switch (imm5_pos) {
1218 case 0:
1219 return new InsGprWX<uint8_t>(machInst, vd, vn, index1);
1220 case 1:
1221 return new InsGprWX<uint16_t>(machInst, vd, vn, index1);
1222 case 2:
1223 return new InsGprWX<uint32_t>(machInst, vd, vn, index1);
1224 case 3:
1225 return new InsGprXX<uint64_t>(machInst, vd, vn, index1);
1226 default:
1227 return new Unknown64(machInst);
1228 }
1229 case 0x5:
1230 index1 = bits(imm5, 4, imm5_pos + 1);
1231 switch (imm5_pos) {
1232 case 0:
1233 if (q)
1234 return new SmovXX<int8_t>(machInst, vd, vn, index1);
1235 else
1236 return new SmovWX<int8_t>(machInst, vd, vn, index1);
1237 case 1:
1238 if (q)
1239 return new SmovXX<int16_t>(machInst, vd, vn, index1);
1240 else
1241 return new SmovWX<int16_t>(machInst, vd, vn, index1);
1242 case 2:
1243 if (q)
1244 return new SmovXX<int32_t>(machInst, vd, vn, index1);
1245 else
1246 return new Unknown64(machInst);
1247 default:
1248 return new Unknown64(machInst);
1249 }
1250 case 0x7:
1251 index1 = imm5 >> (imm5_pos + 1);
1252
1253 if ((q && imm5_pos != 3) || (!q && imm5_pos >= 3))
1254 return new Unknown64(machInst);
1255
1256 switch (imm5_pos) {
1257 case 0:
1258 return new UmovWX<uint8_t>(machInst, vd, vn, index1);
1259 case 1:
1260 return new UmovWX<uint16_t>(machInst, vd, vn, index1);
1261 case 2:
1262 return new UmovWX<uint32_t>(machInst, vd, vn, index1);
1263 case 3:
1264 return new UmovXX<uint64_t>(machInst, vd, vn, index1);
1265 default:
1266 return new Unknown64(machInst);
1267 }
1268 default:
1269 return new Unknown64(machInst);
1270 }
1271 }
1272
1273 template <typename DecoderFeatures>
1270 StaticInstPtr
1271 decodeNeonIndexedElem(ExtMachInst machInst)
1272 {
1273 uint8_t q = bits(machInst, 30);
1274 uint8_t u = bits(machInst, 29);
1275 uint8_t size = bits(machInst, 23, 22);
1276 uint8_t L = bits(machInst, 21);
1277 uint8_t M = bits(machInst, 20);
1278 uint8_t opcode = bits(machInst, 15, 12);
1279 uint8_t H = bits(machInst, 11);
1280
1281 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1282 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1283 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16);
1284
1285 uint8_t index = 0;
1286 uint8_t index_fp = 0;
1287 uint8_t vmh = 0;
1288 uint8_t sz = size & 0x1;
1289 uint8_t sz_q = (sz << 1) | bits(machInst, 30);
1290 uint8_t sz_L = (sz << 1) | L;
1291
1292 // Index and 2nd register operand for integer instructions
1293 if (size == 0x1) {
1294 index = (H << 2) | (L << 1) | M;
1295 // vmh = 0;
1296 } else if (size == 0x2) {
1297 index = (H << 1) | L;
1298 vmh = M;
1299 }
1300 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
1301
1302 // Index and 2nd register operand for FP instructions
1303 vmh = M;
1304 if ((size & 0x1) == 0) {
1305 index_fp = (H << 1) | L;
1306 } else if (L == 0) {
1307 index_fp = H;
1308 }
1309 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
1310
1311 switch (opcode) {
1312 case 0x0:
1313 if (!u || (size == 0x0 || size == 0x3))
1314 return new Unknown64(machInst);
1315 else
1316 return decodeNeonUThreeImmHAndWReg<MlaElemDX, MlaElemQX>(
1317 q, size, machInst, vd, vn, vm, index);
1318 case 0x1:
1319 if (!u && size >= 2 && sz_q != 0x2 && sz_L != 0x3)
1320 return decodeNeonUThreeImmFpReg<FmlaElemDX, FmlaElemQX>(
1321 q, sz, machInst, vd, vn, vm_fp, index_fp);
1322 else
1323 return new Unknown64(machInst);
1324 case 0x2:
1325 if (size == 0x0 || size == 0x3)
1326 return new Unknown64(machInst);
1327 if (u)
1328 return decodeNeonUThreeImmHAndWReg<UmlalElemX, UmlalElem2X>(
1329 q, size, machInst, vd, vn, vm, index);
1330 else
1331 return decodeNeonSThreeImmHAndWReg<SmlalElemX, SmlalElem2X>(
1332 q, size, machInst, vd, vn, vm, index);
1333 case 0x3:
1334 if (u || (size == 0x0 || size == 0x3))
1335 return new Unknown64(machInst);
1336 else
1337 return decodeNeonSThreeImmHAndWReg<SqdmlalElemX,
1338 SqdmlalElem2X>(
1339 q, size, machInst, vd, vn, vm, index);
1340 case 0x4:
1341 if (u && !(size == 0x0 || size == 0x3))
1342 return decodeNeonUThreeImmHAndWReg<MlsElemDX, MlsElemQX>(
1343 q, size, machInst, vd, vn, vm, index);
1344 else
1345 return new Unknown64(machInst);
1346 case 0x5:
1347 if (!u && size >= 0x2 && sz_L != 0x3 && sz_q != 0x2)
1348 return decodeNeonUThreeImmFpReg<FmlsElemDX, FmlsElemQX>(
1349 q, sz, machInst, vd, vn, vm_fp, index_fp);
1350 else
1351 return new Unknown64(machInst);
1352 case 0x6:
1353 if (size == 0x0 || size == 0x3)
1354 return new Unknown64(machInst);
1355 if (u)
1356 return decodeNeonUThreeImmHAndWReg<UmlslElemX, UmlslElem2X>(
1357 q, size, machInst, vd, vn, vm, index);
1358 else
1359 return decodeNeonSThreeImmHAndWReg<SmlslElemX, SmlslElem2X>(
1360 q, size, machInst, vd, vn, vm, index);
1361 case 0x7:
1362 if (u || (size == 0x0 || size == 0x3))
1363 return new Unknown64(machInst);
1364 else
1365 return decodeNeonSThreeImmHAndWReg<SqdmlslElemX,
1366 SqdmlslElem2X>(
1367 q, size, machInst, vd, vn, vm, index);
1368 case 0x8:
1369 if (u || (size == 0x0 || size == 0x3))
1370 return new Unknown64(machInst);
1371 else
1372 return decodeNeonUThreeImmHAndWReg<MulElemDX, MulElemQX>(
1373 q, size, machInst, vd, vn, vm, index);
1374 case 0x9:
1375 if (size >= 2 && sz_q != 0x2 && sz_L != 0x3) {
1376 if (u)
1377 return decodeNeonUThreeImmFpReg<FmulxElemDX, FmulxElemQX>(
1378 q, sz, machInst, vd, vn, vm_fp, index_fp);
1379 else
1380 return decodeNeonUThreeImmFpReg<FmulElemDX, FmulElemQX>(
1381 q, sz, machInst, vd, vn, vm_fp, index_fp);
1382 } else {
1383 return new Unknown64(machInst);
1384 }
1385 case 0xa:
1386 if (size == 0x0 || size == 0x3)
1387 return new Unknown64(machInst);
1388 if (u)
1389 return decodeNeonUThreeImmHAndWReg<UmullElemX, UmullElem2X>(
1390 q, size, machInst, vd, vn, vm, index);
1391 else
1392 return decodeNeonSThreeImmHAndWReg<SmullElemX, SmullElem2X>(
1393 q, size, machInst, vd, vn, vm, index);
1394 case 0xb:
1395 if (u || (size == 0x0 || size == 0x3))
1396 return new Unknown64(machInst);
1397 else
1398 return decodeNeonSThreeImmHAndWReg<SqdmullElemX, SqdmullElem2X>(
1399 q, size, machInst, vd, vn, vm, index);
1400 case 0xc:
1401 if (u || (size == 0x0 || size == 0x3))
1402 return new Unknown64(machInst);
1403 else
1404 return decodeNeonSThreeImmHAndWReg<SqdmulhElemDX, SqdmulhElemQX>(
1405 q, size, machInst, vd, vn, vm, index);
1406 case 0xd:
1407 if (u || (size == 0x0 || size == 0x3))
1408 return new Unknown64(machInst);
1409 else
1410 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemDX, SqrdmulhElemQX>(
1411 q, size, machInst, vd, vn, vm, index);
1412 default:
1413 return new Unknown64(machInst);
1414 }
1415 }
1416
1417 StaticInstPtr
1418 decodeNeonModImm(ExtMachInst machInst)
1419 {
1420 uint8_t q = bits(machInst, 30);
1421 uint8_t op = bits(machInst, 29);
1422 uint8_t abcdefgh = (bits(machInst, 18, 16) << 5) |
1423 bits(machInst, 9, 5);
1424 uint8_t cmode = bits(machInst, 15, 12);
1425 uint8_t o2 = bits(machInst, 11);
1426
1427 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1428
1429 if (o2 == 0x1 || (op == 0x1 && cmode == 0xf && !q))
1430 return new Unknown64(machInst);
1431
1432 bool immValid = true;
1433 const uint64_t bigImm = simd_modified_imm(op, cmode, abcdefgh,
1434 immValid,
1435 true /* isAarch64 */);
1436 if (!immValid) {
1437 return new Unknown(machInst);
1438 }
1439
1440 if (op) {
1441 if (bits(cmode, 3) == 0) {
1442 if (bits(cmode, 0) == 0) {
1443 if (q)
1444 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1445 else
1446 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1447 } else {
1448 if (q)
1449 return new BicImmQX<uint64_t>(machInst, vd, bigImm);
1450 else
1451 return new BicImmDX<uint64_t>(machInst, vd, bigImm);
1452 }
1453 } else {
1454 if (bits(cmode, 2) == 1) {
1455 switch (bits(cmode, 1, 0)) {
1456 case 0:
1457 case 1:
1458 if (q)
1459 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1460 else
1461 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1462 case 2:
1463 if (q)
1464 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1465 else
1466 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1467 case 3:
1468 if (q)
1469 return new FmovQX<uint64_t>(machInst, vd, bigImm);
1470 else
1471 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1472 }
1473 } else {
1474 if (bits(cmode, 0) == 0) {
1475 if (q)
1476 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1477 else
1478 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1479 } else {
1480 if (q)
1481 return new BicImmQX<uint64_t>(machInst, vd,
1482 bigImm);
1483 else
1484 return new BicImmDX<uint64_t>(machInst, vd,
1485 bigImm);
1486 }
1487 }
1488 }
1489 } else {
1490 if (bits(cmode, 3) == 0) {
1491 if (bits(cmode, 0) == 0) {
1492 if (q)
1493 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1494 else
1495 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1496 } else {
1497 if (q)
1498 return new OrrImmQX<uint64_t>(machInst, vd, bigImm);
1499 else
1500 return new OrrImmDX<uint64_t>(machInst, vd, bigImm);
1501 }
1502 } else {
1503 if (bits(cmode, 2) == 1) {
1504 if (bits(cmode, 1, 0) == 0x3) {
1505 if (q)
1506 return new FmovQX<uint32_t>(machInst, vd, bigImm);
1507 else
1508 return new FmovDX<uint32_t>(machInst, vd, bigImm);
1509 } else {
1510 if (q)
1511 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1512 else
1513 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1514 }
1515 } else {
1516 if (bits(cmode, 0) == 0) {
1517 if (q)
1518 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1519 else
1520 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1521 } else {
1522 if (q)
1523 return new OrrImmQX<uint64_t>(machInst, vd,
1524 bigImm);
1525 else
1526 return new OrrImmDX<uint64_t>(machInst, vd, bigImm);
1527 }
1528 }
1529 }
1530 }
1531 return new Unknown(machInst);
1532 }
1533
1534 StaticInstPtr
1535 decodeNeonShiftByImm(ExtMachInst machInst)
1536 {
1537 uint8_t q = bits(machInst, 30);
1538 uint8_t u = bits(machInst, 29);
1539 uint8_t immh = bits(machInst, 22, 19);
1540 uint8_t immb = bits(machInst, 18, 16);
1541 uint8_t opcode = bits(machInst, 15, 11);
1542
1543 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1544 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1545
1546 uint8_t immh3 = bits(machInst, 22);
1547 uint8_t immh3_q = (immh3 << 1) | q;
1548 uint8_t op_u = (bits(machInst, 12) << 1) | u;
1549 uint8_t size = findMsbSet(immh);
1550 int shiftAmt = 0;
1551
1552 switch (opcode) {
1553 case 0x00:
1554 if (immh3_q == 0x2)
1555 return new Unknown64(machInst);
1556 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1557 if (u)
1558 return decodeNeonUTwoShiftXReg<UshrDX, UshrQX>(
1559 q, size, machInst, vd, vn, shiftAmt);
1560 else
1561 return decodeNeonSTwoShiftXReg<SshrDX, SshrQX>(
1562 q, size, machInst, vd, vn, shiftAmt);
1563 case 0x02:
1564 if (immh3_q == 0x2)
1565 return new Unknown64(machInst);
1566 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1567 if (u)
1568 return decodeNeonUTwoShiftXReg<UsraDX, UsraQX>(
1569 q, size, machInst, vd, vn, shiftAmt);
1570 else
1571 return decodeNeonSTwoShiftXReg<SsraDX, SsraQX>(
1572 q, size, machInst, vd, vn, shiftAmt);
1573 case 0x04:
1574 if (immh3_q == 0x2)
1575 return new Unknown64(machInst);
1576 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1577 if (u)
1578 return decodeNeonUTwoShiftXReg<UrshrDX, UrshrQX>(
1579 q, size, machInst, vd, vn, shiftAmt);
1580 else
1581 return decodeNeonSTwoShiftXReg<SrshrDX, SrshrQX>(
1582 q, size, machInst, vd, vn, shiftAmt);
1583 case 0x06:
1584 if (immh3_q == 0x2)
1585 return new Unknown64(machInst);
1586 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1587 if (u)
1588 return decodeNeonUTwoShiftXReg<UrsraDX, UrsraQX>(
1589 q, size, machInst, vd, vn, shiftAmt);
1590 else
1591 return decodeNeonSTwoShiftXReg<SrsraDX, SrsraQX>(
1592 q, size, machInst, vd, vn, shiftAmt);
1593 case 0x08:
1594 if (u && !(immh3_q == 0x2)) {
1595 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1596 return decodeNeonUTwoShiftXReg<SriDX, SriQX>(
1597 q, size, machInst, vd, vn, shiftAmt);
1598 } else {
1599 return new Unknown64(machInst);
1600 }
1601 case 0x0a:
1602 if (immh3_q == 0x2)
1603 return new Unknown64(machInst);
1604 shiftAmt = ((immh << 3) | immb) - (8 << size);
1605 if (u)
1606 return decodeNeonUTwoShiftXReg<SliDX, SliQX>(
1607 q, size, machInst, vd, vn, shiftAmt);
1608 else
1609 return decodeNeonUTwoShiftXReg<ShlDX, ShlQX>(
1610 q, size, machInst, vd, vn, shiftAmt);
1611 case 0x0c:
1612 if (u && !(immh3_q == 0x2 || op_u == 0x0)) {
1613 shiftAmt = ((immh << 3) | immb) - (8 << size);
1614 return decodeNeonSTwoShiftXReg<SqshluDX, SqshluQX>(
1615 q, size, machInst, vd, vn, shiftAmt);
1616 } else {
1617 return new Unknown64(machInst);
1618 }
1619 case 0x0e:
1620 if (immh3_q == 0x2 || op_u == 0x0)
1621 return new Unknown64(machInst);
1622 shiftAmt = ((immh << 3) | immb) - (8 << size);
1623 if (u)
1624 return decodeNeonUTwoShiftXReg<UqshlImmDX, UqshlImmQX>(
1625 q, size, machInst, vd, vn, shiftAmt);
1626 else
1627 return decodeNeonSTwoShiftXReg<SqshlImmDX, SqshlImmQX>(
1628 q, size, machInst, vd, vn, shiftAmt);
1629 case 0x10:
1630 if (immh3)
1631 return new Unknown64(machInst);
1632 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1633 if (u)
1634 return decodeNeonSTwoShiftSReg<SqshrunX, Sqshrun2X>(
1635 q, size, machInst, vd, vn, shiftAmt);
1636 else
1637 return decodeNeonUTwoShiftSReg<ShrnX, Shrn2X>(
1638 q, size, machInst, vd, vn, shiftAmt);
1639 case 0x11:
1640 if (immh3)
1641 return new Unknown64(machInst);
1642 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1643 if (u)
1644 return decodeNeonSTwoShiftSReg<SqrshrunX, Sqrshrun2X>(
1645 q, size, machInst, vd, vn, shiftAmt);
1646 else
1647 return decodeNeonUTwoShiftSReg<RshrnX, Rshrn2X>(
1648 q, size, machInst, vd, vn, shiftAmt);
1649 case 0x12:
1650 if (immh3)
1651 return new Unknown64(machInst);
1652 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1653 if (u)
1654 return decodeNeonUTwoShiftSReg<UqshrnX, Uqshrn2X>(
1655 q, size, machInst, vd, vn, shiftAmt);
1656 else
1657 return decodeNeonSTwoShiftSReg<SqshrnX, Sqshrn2X>(
1658 q, size, machInst, vd, vn, shiftAmt);
1659 case 0x13:
1660 if (immh3)
1661 return new Unknown64(machInst);
1662 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1663 if (u)
1664 return decodeNeonUTwoShiftSReg<UqrshrnX, Uqrshrn2X>(
1665 q, size, machInst, vd, vn, shiftAmt);
1666 else
1667 return decodeNeonSTwoShiftSReg<SqrshrnX, Sqrshrn2X>(
1668 q, size, machInst, vd, vn, shiftAmt);
1669 case 0x14:
1670 if (immh3)
1671 return new Unknown64(machInst);
1672 shiftAmt = ((immh << 3) | immb) - (8 << size);
1673 if (u)
1674 return decodeNeonUTwoShiftSReg<UshllX, Ushll2X>(
1675 q, size, machInst, vd, vn, shiftAmt);
1676 else
1677 return decodeNeonSTwoShiftSReg<SshllX, Sshll2X>(
1678 q, size, machInst, vd, vn, shiftAmt);
1679 case 0x1c:
1680 if (immh < 0x4 || immh3_q == 0x2)
1681 return new Unknown64(machInst);
1682 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1683 if (u) {
1684 return decodeNeonUTwoShiftFpReg<UcvtfFixedDX, UcvtfFixedQX>(
1685 q, size & 0x1, machInst, vd, vn, shiftAmt);
1686 } else {
1687 if (q) {
1688 if (size & 0x1)
1689 return new ScvtfFixedDQX<uint64_t>(machInst, vd, vn,
1690 shiftAmt);
1691 else
1692 return new ScvtfFixedSQX<uint32_t>(machInst, vd, vn,
1693 shiftAmt);
1694 } else {
1695 if (size & 0x1)
1696 return new Unknown(machInst);
1697 else
1698 return new ScvtfFixedDX<uint32_t>(machInst, vd, vn,
1699 shiftAmt);
1700 }
1701 }
1702 case 0x1f:
1703 if (immh < 0x4 || immh3_q == 0x2)
1704 return new Unknown64(machInst);
1705 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1706 if (u)
1707 return decodeNeonUTwoShiftFpReg<FcvtzuFixedDX, FcvtzuFixedQX>(
1708 q, size & 0x1, machInst, vd, vn, shiftAmt);
1709 else
1710 return decodeNeonUTwoShiftFpReg<FcvtzsFixedDX, FcvtzsFixedQX>(
1711 q, size & 0x1, machInst, vd, vn, shiftAmt);
1712 default:
1713 return new Unknown64(machInst);
1714 }
1715 }
1716
1717 StaticInstPtr
1718 decodeNeonTblTbx(ExtMachInst machInst)
1719 {
1720 uint8_t q = bits(machInst, 30);
1721
1722 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1723 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1724 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1725
1726 uint8_t switchVal = bits(machInst, 14, 12);
1727
1728 switch (switchVal) {
1729 case 0x0:
1730 if (q)
1731 return new Tbl1QX<uint8_t>(machInst, vd, vn, vm);
1732 else
1733 return new Tbl1DX<uint8_t>(machInst, vd, vn, vm);
1734 case 0x1:
1735 if (q)
1736 return new Tbx1QX<uint8_t>(machInst, vd, vn, vm);
1737 else
1738 return new Tbx1DX<uint8_t>(machInst, vd, vn, vm);
1739 case 0x2:
1740 if (q)
1741 return new Tbl2QX<uint8_t>(machInst, vd, vn, vm);
1742 else
1743 return new Tbl2DX<uint8_t>(machInst, vd, vn, vm);
1744 case 0x3:
1745 if (q)
1746 return new Tbx2QX<uint8_t>(machInst, vd, vn, vm);
1747 else
1748 return new Tbx2DX<uint8_t>(machInst, vd, vn, vm);
1749 case 0x4:
1750 if (q)
1751 return new Tbl3QX<uint8_t>(machInst, vd, vn, vm);
1752 else
1753 return new Tbl3DX<uint8_t>(machInst, vd, vn, vm);
1754 case 0x5:
1755 if (q)
1756 return new Tbx3QX<uint8_t>(machInst, vd, vn, vm);
1757 else
1758 return new Tbx3DX<uint8_t>(machInst, vd, vn, vm);
1759 case 0x6:
1760 if (q)
1761 return new Tbl4QX<uint8_t>(machInst, vd, vn, vm);
1762 else
1763 return new Tbl4DX<uint8_t>(machInst, vd, vn, vm);
1764 case 0x7:
1765 if (q)
1766 return new Tbx4QX<uint8_t>(machInst, vd, vn, vm);
1767 else
1768 return new Tbx4DX<uint8_t>(machInst, vd, vn, vm);
1769 default:
1770 return new Unknown64(machInst);
1771 }
1772
1773 return new Unknown64(machInst);
1774 }
1775
1776 StaticInstPtr
1777 decodeNeonZipUzpTrn(ExtMachInst machInst)
1778 {
1779 uint8_t q = bits(machInst, 30);
1780 uint8_t size = bits(machInst, 23, 22);
1781 uint8_t opcode = bits(machInst, 14, 12);
1782
1783 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1784 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1785 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1786
1787 switch (opcode) {
1788 case 0x1:
1789 return decodeNeonUThreeXReg<Uzp1DX, Uzp1QX>(
1790 q, size, machInst, vd, vn, vm);
1791 case 0x2:
1792 return decodeNeonUThreeXReg<Trn1DX, Trn1QX>(
1793 q, size, machInst, vd, vn, vm);
1794 case 0x3:
1795 return decodeNeonUThreeXReg<Zip1DX, Zip1QX>(
1796 q, size, machInst, vd, vn, vm);
1797 case 0x5:
1798 return decodeNeonUThreeXReg<Uzp2DX, Uzp2QX>(
1799 q, size, machInst, vd, vn, vm);
1800 case 0x6:
1801 return decodeNeonUThreeXReg<Trn2DX, Trn2QX>(
1802 q, size, machInst, vd, vn, vm);
1803 case 0x7:
1804 return decodeNeonUThreeXReg<Zip2DX, Zip2QX>(
1805 q, size, machInst, vd, vn, vm);
1806 default:
1807 return new Unknown64(machInst);
1808 }
1809 return new Unknown64(machInst);
1810 }
1811
1812 StaticInstPtr
1813 decodeNeonExt(ExtMachInst machInst)
1814 {
1815 uint8_t q = bits(machInst, 30);
1816 uint8_t op2 = bits(machInst, 23, 22);
1817 uint8_t imm4 = bits(machInst, 14, 11);
1818
1819 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1820 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1821 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1822
1823 if (op2 != 0 || (q == 0x0 && bits(imm4, 3) == 0x1))
1824 return new Unknown64(machInst);
1825
1826 uint8_t index = q ? imm4 : imm4 & 0x7;
1827
1828 if (q) {
1829 return new ExtQX<uint8_t>(machInst, vd, vn, vm, index);
1830 } else {
1831 return new ExtDX<uint8_t>(machInst, vd, vn, vm, index);
1832 }
1833 }
1834
1835 StaticInstPtr
1836 decodeNeonSc3Same(ExtMachInst machInst)
1837 {
1838 uint8_t u = bits(machInst, 29);
1839 uint8_t size = bits(machInst, 23, 22);
1840 uint8_t opcode = bits(machInst, 15, 11);
1841 uint8_t s = bits(machInst, 11);
1842
1843 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1844 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1845 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1846
1847 switch (opcode) {
1848 case 0x01:
1849 if (u)
1850 return decodeNeonUThreeUReg<UqaddScX>(
1851 size, machInst, vd, vn, vm);
1852 else
1853 return decodeNeonSThreeUReg<SqaddScX>(
1854 size, machInst, vd, vn, vm);
1855 case 0x05:
1856 if (u)
1857 return decodeNeonUThreeUReg<UqsubScX>(
1858 size, machInst, vd, vn, vm);
1859 else
1860 return decodeNeonSThreeUReg<SqsubScX>(
1861 size, machInst, vd, vn, vm);
1862 case 0x06:
1863 if (size != 0x3)
1864 return new Unknown64(machInst);
1865 if (u)
1866 return new CmhiDX<uint64_t>(machInst, vd, vn, vm);
1867 else
1868 return new CmgtDX<int64_t>(machInst, vd, vn, vm);
1869 case 0x07:
1870 if (size != 0x3)
1871 return new Unknown64(machInst);
1872 if (u)
1873 return new CmhsDX<uint64_t>(machInst, vd, vn, vm);
1874 else
1875 return new CmgeDX<int64_t>(machInst, vd, vn, vm);
1876 case 0x08:
1877 if (!s && size != 0x3)
1878 return new Unknown64(machInst);
1879 if (u)
1880 return new UshlDX<uint64_t>(machInst, vd, vn, vm);
1881 else
1882 return new SshlDX<int64_t>(machInst, vd, vn, vm);
1883 case 0x09:
1884 if (!s && size != 0x3)
1885 return new Unknown64(machInst);
1886 if (u)
1887 return decodeNeonUThreeUReg<UqshlScX>(
1888 size, machInst, vd, vn, vm);
1889 else
1890 return decodeNeonSThreeUReg<SqshlScX>(
1891 size, machInst, vd, vn, vm);
1892 case 0x0a:
1893 if (!s && size != 0x3)
1894 return new Unknown64(machInst);
1895 if (u)
1896 return new UrshlDX<uint64_t>(machInst, vd, vn, vm);
1897 else
1898 return new SrshlDX<int64_t>(machInst, vd, vn, vm);
1899 case 0x0b:
1900 if (!s && size != 0x3)
1901 return new Unknown64(machInst);
1902 if (u)
1903 return decodeNeonUThreeUReg<UqrshlScX>(
1904 size, machInst, vd, vn, vm);
1905 else
1906 return decodeNeonSThreeUReg<SqrshlScX>(
1907 size, machInst, vd, vn, vm);
1908 case 0x10:
1909 if (size != 0x3)
1910 return new Unknown64(machInst);
1911 if (u)
1912 return new SubDX<uint64_t>(machInst, vd, vn, vm);
1913 else
1914 return new AddDX<uint64_t>(machInst, vd, vn, vm);
1915 case 0x11:
1916 if (size != 0x3)
1917 return new Unknown64(machInst);
1918 if (u)
1919 return new CmeqDX<uint64_t>(machInst, vd, vn, vm);
1920 else
1921 return new CmtstDX<uint64_t>(machInst, vd, vn, vm);
1922 case 0x16:
1923 if (size == 0x3 || size == 0x0)
1924 return new Unknown64(machInst);
1925 if (u)
1926 return decodeNeonSThreeHAndWReg<SqrdmulhScX>(
1927 size, machInst, vd, vn, vm);
1928 else
1929 return decodeNeonSThreeHAndWReg<SqdmulhScX>(
1930 size, machInst, vd, vn, vm);
1931 case 0x1a:
1932 if (!u || size < 0x2)
1933 return new Unknown64(machInst);
1934 else
1935 return decodeNeonUThreeScFpReg<FabdScX>(
1936 size & 0x1, machInst, vd, vn, vm);
1937 case 0x1b:
1938 if (u || size > 0x1)
1939 return new Unknown64(machInst);
1940 else
1941 return decodeNeonUThreeScFpReg<FmulxScX>(
1942 size & 0x1, machInst, vd, vn, vm);
1943 case 0x1c:
1944 if (size < 0x2) {
1945 if (u)
1946 return decodeNeonUThreeScFpReg<FcmgeScX>(
1947 size & 0x1, machInst, vd, vn, vm);
1948 else
1949 return decodeNeonUThreeScFpReg<FcmeqScX>(
1950 size & 0x1, machInst, vd, vn, vm);
1951 } else {
1952 if (u)
1953 return decodeNeonUThreeScFpReg<FcmgtScX>(
1954 size & 0x1, machInst, vd, vn, vm);
1955 else
1956 return new Unknown64(machInst);
1957 }
1958 case 0x1d:
1959 if (!u)
1960 return new Unknown64(machInst);
1961 if (size < 0x2)
1962 return decodeNeonUThreeScFpReg<FacgeScX>(
1963 size & 0x1, machInst, vd, vn, vm);
1964 else
1965 return decodeNeonUThreeScFpReg<FacgtScX>(
1966 size & 0x1, machInst, vd, vn, vm);
1967 case 0x1f:
1968 if (u)
1969 return new Unknown64(machInst);
1970 if (size < 0x2)
1971 return decodeNeonUThreeScFpReg<FrecpsScX>(
1972 size & 0x1, machInst, vd, vn, vm);
1973 else
1974 return decodeNeonUThreeScFpReg<FrsqrtsScX>(
1975 size & 0x1, machInst, vd, vn, vm);
1976 default:
1977 return new Unknown64(machInst);
1978 }
1979 }
1980
1981 StaticInstPtr
1982 decodeNeonSc3Diff(ExtMachInst machInst)
1983 {
1984 if (bits(machInst, 29))
1985 return new Unknown64(machInst);
1986
1987 uint8_t size = bits(machInst, 23, 22);
1988 if (size == 0x0 || size == 0x3)
1989 return new Unknown64(machInst);
1990
1991 uint8_t opcode = bits(machInst, 15, 12);
1992
1993 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1994 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1995 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1996
1997 switch (opcode) {
1998 case 0x9:
1999 return decodeNeonSThreeHAndWReg<SqdmlalScX>(size, machInst, vd, vn, vm);
2000 case 0xb:
2001 return decodeNeonSThreeHAndWReg<SqdmlslScX>(size, machInst, vd, vn, vm);
2002 case 0xd:
2003 return decodeNeonSThreeHAndWReg<SqdmullScX>(size, machInst, vd, vn, vm);
2004 default:
2005 return new Unknown64(machInst);
2006 }
2007 }
2008
2009 StaticInstPtr
2010 decodeNeonSc2RegMisc(ExtMachInst machInst)
2011 {
2012 uint8_t u = bits(machInst, 29);
2013 uint8_t size = bits(machInst, 23, 22);
2014 uint8_t opcode = bits(machInst, 16, 12);
2015
2016 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2017 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2018
2019 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
2020 switch (switchVal) {
2021 case 0x03:
2022 return decodeNeonUTwoMiscUReg<SuqaddScX>(size, machInst, vd, vn);
2023 case 0x07:
2024 return decodeNeonSTwoMiscUReg<SqabsScX>(size, machInst, vd, vn);
2025 case 0x08:
2026 if (size != 0x3)
2027 return new Unknown64(machInst);
2028 else
2029 return new CmgtZeroDX<int64_t>(machInst, vd, vn);
2030 case 0x09:
2031 if (size != 0x3)
2032 return new Unknown64(machInst);
2033 else
2034 return new CmeqZeroDX<int64_t>(machInst, vd, vn);
2035 case 0x0a:
2036 if (size != 0x3)
2037 return new Unknown64(machInst);
2038 else
2039 return new CmltZeroDX<int64_t>(machInst, vd, vn);
2040 case 0x0b:
2041 if (size != 0x3)
2042 return new Unknown64(machInst);
2043 else
2044 return new AbsDX<int64_t>(machInst, vd, vn);
2045 case 0x0c:
2046 if (size < 0x2)
2047 return new Unknown64(machInst);
2048 else
2049 return decodeNeonUTwoMiscScFpReg<FcmgtZeroScX>(
2050 size & 0x1, machInst, vd, vn);
2051 case 0x0d:
2052 if (size < 0x2)
2053 return new Unknown64(machInst);
2054 else
2055 return decodeNeonUTwoMiscScFpReg<FcmeqZeroScX>(
2056 size & 0x1, machInst, vd, vn);
2057 case 0x0e:
2058 if (size < 0x2)
2059 return new Unknown64(machInst);
2060 else
2061 return decodeNeonUTwoMiscScFpReg<FcmltZeroScX>(
2062 size & 0x1, machInst, vd, vn);
2063 case 0x14:
2064 if (size == 0x3) {
2065 return new Unknown64(machInst);
2066 } else {
2067 switch (size) {
2068 case 0x0:
2069 return new SqxtnScX<int8_t>(machInst, vd, vn);
2070 case 0x1:
2071 return new SqxtnScX<int16_t>(machInst, vd, vn);
2072 case 0x2:
2073 return new SqxtnScX<int32_t>(machInst, vd, vn);
2074 }
2075 }
2076 case 0x1a:
2077 if (size < 0x2)
2078 return decodeNeonUTwoMiscScFpReg<FcvtnsScX>(
2079 size & 0x1, machInst, vd, vn);
2080 else
2081 return decodeNeonUTwoMiscScFpReg<FcvtpsScX>(
2082 size & 0x1, machInst, vd, vn);
2083 case 0x1b:
2084 if (size < 0x2)
2085 return decodeNeonUTwoMiscScFpReg<FcvtmsScX>(
2086 size & 0x1, machInst, vd, vn);
2087 else
2088 return decodeNeonUTwoMiscScFpReg<FcvtzsIntScX>(
2089 size & 0x1, machInst, vd, vn);
2090 case 0x1c:
2091 if (size < 0x2)
2092 return decodeNeonUTwoMiscScFpReg<FcvtasScX>(
2093 size & 0x1, machInst, vd, vn);
2094 else
2095 return new Unknown64(machInst);
2096 case 0x1d:
2097 if (size < 0x2) {
2098 if (size & 0x1)
2099 return new ScvtfIntScDX<uint64_t>(machInst, vd, vn);
2100 else
2101 return new ScvtfIntScSX<uint32_t>(machInst, vd, vn);
2102 } else {
2103 return decodeNeonUTwoMiscScFpReg<FrecpeScX>(
2104 size & 0x1, machInst, vd, vn);
2105 }
2106 case 0x1f:
2107 if (size < 0x2)
2108 return new Unknown64(machInst);
2109 else
2110 return decodeNeonUTwoMiscScFpReg<FrecpxX>(
2111 size & 0x1, machInst, vd, vn);
2112 case 0x23:
2113 return decodeNeonUTwoMiscUReg<UsqaddScX>(size, machInst, vd, vn);
2114 case 0x27:
2115 return decodeNeonSTwoMiscUReg<SqnegScX>(size, machInst, vd, vn);
2116 case 0x28:
2117 if (size != 0x3)
2118 return new Unknown64(machInst);
2119 else
2120 return new CmgeZeroDX<int64_t>(machInst, vd, vn);
2121 case 0x29:
2122 if (size != 0x3)
2123 return new Unknown64(machInst);
2124 else
2125 return new CmleZeroDX<int64_t>(machInst, vd, vn);
2126 case 0x2b:
2127 if (size != 0x3)
2128 return new Unknown64(machInst);
2129 else
2130 return new NegDX<int64_t>(machInst, vd, vn);
2131 case 0x2c:
2132 if (size < 0x2)
2133 return new Unknown64(machInst);
2134 else
2135 return decodeNeonUTwoMiscScFpReg<FcmgeZeroScX>(
2136 size & 0x1, machInst, vd, vn);
2137 case 0x2d:
2138 if (size < 0x2)
2139 return new Unknown64(machInst);
2140 else
2141 return decodeNeonUTwoMiscScFpReg<FcmleZeroScX>(
2142 size & 0x1, machInst, vd, vn);
2143 case 0x32:
2144 if (size == 0x3) {
2145 return new Unknown64(machInst);
2146 } else {
2147 switch (size) {
2148 case 0x0:
2149 return new SqxtunScX<int8_t>(machInst, vd, vn);
2150 case 0x1:
2151 return new SqxtunScX<int16_t>(machInst, vd, vn);
2152 case 0x2:
2153 return new SqxtunScX<int32_t>(machInst, vd, vn);
2154 }
2155 }
2156 case 0x34:
2157 if (size == 0x3) {
2158 return new Unknown64(machInst);
2159 } else {
2160 switch (size) {
2161 case 0x0:
2162 return new UqxtnScX<uint8_t>(machInst, vd, vn);
2163 case 0x1:
2164 return new UqxtnScX<uint16_t>(machInst, vd, vn);
2165 case 0x2:
2166 return new UqxtnScX<uint32_t>(machInst, vd, vn);
2167 }
2168 }
2169 case 0x36:
2170 if (size != 0x1) {
2171 return new Unknown64(machInst);
2172 } else {
2173 return new FcvtxnScX<uint32_t>(machInst, vd, vn);
2174 }
2175 case 0x3a:
2176 if (size < 0x2)
2177 return decodeNeonUTwoMiscScFpReg<FcvtnuScX>(
2178 size & 0x1, machInst, vd, vn);
2179 else
2180 return decodeNeonUTwoMiscScFpReg<FcvtpuScX>(
2181 size & 0x1, machInst, vd, vn);
2182 case 0x3b:
2183 if (size < 0x2)
2184 return decodeNeonUTwoMiscScFpReg<FcvtmuScX>(
2185 size & 0x1, machInst, vd, vn);
2186 else
2187 return decodeNeonUTwoMiscScFpReg<FcvtzuIntScX>(
2188 size & 0x1, machInst, vd, vn);
2189 case 0x3c:
2190 if (size < 0x2)
2191 return decodeNeonUTwoMiscScFpReg<FcvtauScX>(
2192 size & 0x1, machInst, vd, vn);
2193 else
2194 return new Unknown64(machInst);
2195 case 0x3d:
2196 if (size < 0x2)
2197 return decodeNeonUTwoMiscScFpReg<UcvtfIntScX>(
2198 size & 0x1, machInst, vd, vn);
2199 else
2200 return decodeNeonUTwoMiscScFpReg<FrsqrteScX>(
2201 size & 0x1, machInst, vd, vn);
2202 default:
2203 return new Unknown64(machInst);
2204 }
2205 }
2206
2207 StaticInstPtr
2208 decodeNeonScPwise(ExtMachInst machInst)
2209 {
2210 uint8_t u = bits(machInst, 29);
2211 uint8_t size = bits(machInst, 23, 22);
2212 uint8_t opcode = bits(machInst, 16, 12);
2213
2214 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2215 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2216
2217 if (!u) {
2218 if (opcode == 0x1b && size == 0x3)
2219 return new AddpScQX<uint64_t>(machInst, vd, vn);
2220 else
2221 return new Unknown64(machInst);
2222 }
2223
2224 uint8_t switchVal = (opcode << 0) | (size << 5);
2225 switch (switchVal) {
2226 case 0x0c:
2227 case 0x2c:
2228 return decodeNeonUTwoMiscPwiseScFpReg<FmaxnmpScDX, FmaxnmpScQX>(
2229 size & 0x1, machInst, vd, vn);
2230 case 0x0d:
2231 case 0x2d:
2232 return decodeNeonUTwoMiscPwiseScFpReg<FaddpScDX, FaddpScQX>(
2233 size & 0x1, machInst, vd, vn);
2234 case 0x0f:
2235 case 0x2f:
2236 return decodeNeonUTwoMiscPwiseScFpReg<FmaxpScDX, FmaxpScQX>(
2237 size & 0x1, machInst, vd, vn);
2238 case 0x4c:
2239 case 0x6c:
2240 return decodeNeonUTwoMiscPwiseScFpReg<FminnmpScDX, FminnmpScQX>(
2241 size & 0x1, machInst, vd, vn);
2242 case 0x4f:
2243 case 0x6f:
2244 return decodeNeonUTwoMiscPwiseScFpReg<FminpScDX, FminpScQX>(
2245 size & 0x1, machInst, vd, vn);
2246 default:
2247 return new Unknown64(machInst);
2248 }
2249 }
2250
2251 StaticInstPtr
2252 decodeNeonScCopy(ExtMachInst machInst)
2253 {
2254 if (bits(machInst, 14, 11) != 0 || bits(machInst, 29))
2255 return new Unknown64(machInst);
2256
2257 uint8_t imm5 = bits(machInst, 20, 16);
2258
2259 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2260 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2261
2262 uint8_t size = findLsbSet(imm5);
2263 uint8_t index = bits(imm5, 4, size + 1);
2264
2265 return decodeNeonUTwoShiftUReg<DupElemScX>(
2266 size, machInst, vd, vn, index);
2267 }
2268
2269 StaticInstPtr
2270 decodeNeonScIndexedElem(ExtMachInst machInst)
2271 {
2272 uint8_t u = bits(machInst, 29);
2273 uint8_t size = bits(machInst, 23, 22);
2274 uint8_t L = bits(machInst, 21);
2275 uint8_t M = bits(machInst, 20);
2276 uint8_t opcode = bits(machInst, 15, 12);
2277 uint8_t H = bits(machInst, 11);
2278
2279 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2280 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2281 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16);
2282
2283 uint8_t index = 0;
2284 uint8_t index_fp = 0;
2285 uint8_t vmh = 0;
2286 uint8_t sz_L = bits(machInst, 22, 21);
2287
2288 // Index and 2nd register operand for integer instructions
2289 if (size == 0x1) {
2290 index = (H << 2) | (L << 1) | M;
2291 // vmh = 0;
2292 } else if (size == 0x2) {
2293 index = (H << 1) | L;
2294 vmh = M;
2295 } else if (size == 0x3) {
2296 index = H;
2297 vmh = M;
2298 }
2299 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
2300
2301 // Index and 2nd register operand for FP instructions
2302 vmh = M;
2303 if ((size & 0x1) == 0) {
2304 index_fp = (H << 1) | L;
2305 } else if (L == 0) {
2306 index_fp = H;
2307 }
2308 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
2309
2310 if (u && opcode != 9)
2311 return new Unknown64(machInst);
2312
2313 switch (opcode) {
2314 case 0x1:
2315 if (size < 2 || sz_L == 0x3)
2316 return new Unknown64(machInst);
2317 else
2318 return decodeNeonUThreeImmScFpReg<FmlaElemScX>(
2319 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2320 case 0x3:
2321 if (size == 0x0 || size == 0x3)
2322 return new Unknown64(machInst);
2323 else
2324 return decodeNeonSThreeImmHAndWReg<SqdmlalElemScX>(
2325 size, machInst, vd, vn, vm, index);
2326 case 0x5:
2327 if (size < 2 || sz_L == 0x3)
2328 return new Unknown64(machInst);
2329 else
2330 return decodeNeonUThreeImmScFpReg<FmlsElemScX>(
2331 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2332 case 0x7:
2333 if (size == 0x0 || size == 0x3)
2334 return new Unknown64(machInst);
2335 else
2336 return decodeNeonSThreeImmHAndWReg<SqdmlslElemScX>(
2337 size, machInst, vd, vn, vm, index);
2338 case 0x9:
2339 if (size < 2 || sz_L == 0x3)
2340 return new Unknown64(machInst);
2341 if (u)
2342 return decodeNeonUThreeImmScFpReg<FmulxElemScX>(
2343 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2344 else
2345 return decodeNeonUThreeImmScFpReg<FmulElemScX>(
2346 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2347 case 0xb:
2348 if (size == 0x0 || size == 0x3)
2349 return new Unknown64(machInst);
2350 else
2351 return decodeNeonSThreeImmHAndWReg<SqdmullElemScX>(
2352 size, machInst, vd, vn, vm, index);
2353 case 0xc:
2354 if (size == 0x0 || size == 0x3)
2355 return new Unknown64(machInst);
2356 else
2357 return decodeNeonSThreeImmHAndWReg<SqdmulhElemScX>(
2358 size, machInst, vd, vn, vm, index);
2359 case 0xd:
2360 if (size == 0x0 || size == 0x3)
2361 return new Unknown64(machInst);
2362 else
2363 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemScX>(
2364 size, machInst, vd, vn, vm, index);
2365 default:
2366 return new Unknown64(machInst);
2367 }
2368 }
2369
2370 StaticInstPtr
2371 decodeNeonScShiftByImm(ExtMachInst machInst)
2372 {
2373 bool u = bits(machInst, 29);
2374 uint8_t immh = bits(machInst, 22, 19);
2375 uint8_t immb = bits(machInst, 18, 16);
2376 uint8_t opcode = bits(machInst, 15, 11);
2377
2378 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2379 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2380
2381 uint8_t immh3 = bits(machInst, 22);
2382 uint8_t size = findMsbSet(immh);
2383 int shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2384
2385 if (immh == 0x0)
2386 return new Unknown64(machInst);
2387
2388 switch (opcode) {
2389 case 0x00:
2390 if (!immh3)
2391 return new Unknown64(machInst);
2392 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2393 if (u)
2394 return new UshrDX<uint64_t>(machInst, vd, vn, shiftAmt);
2395 else
2396 return new SshrDX<int64_t>(machInst, vd, vn, shiftAmt);
2397 case 0x02:
2398 if (!immh3)
2399 return new Unknown64(machInst);
2400 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2401 if (u)
2402 return new UsraDX<uint64_t>(machInst, vd, vn, shiftAmt);
2403 else
2404 return new SsraDX<int64_t>(machInst, vd, vn, shiftAmt);
2405 case 0x04:
2406 if (!immh3)
2407 return new Unknown64(machInst);
2408 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2409 if (u)
2410 return new UrshrDX<uint64_t>(machInst, vd, vn, shiftAmt);
2411 else
2412 return new SrshrDX<int64_t>(machInst, vd, vn, shiftAmt);
2413 case 0x06:
2414 if (!immh3)
2415 return new Unknown64(machInst);
2416 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2417 if (u)
2418 return new UrsraDX<uint64_t>(machInst, vd, vn, shiftAmt);
2419 else
2420 return new SrsraDX<int64_t>(machInst, vd, vn, shiftAmt);
2421 case 0x08:
2422 if (!immh3)
2423 return new Unknown64(machInst);
2424 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2425 if (u)
2426 return new SriDX<uint64_t>(machInst, vd, vn, shiftAmt);
2427 else
2428 return new Unknown64(machInst);
2429 case 0x0a:
2430 if (!immh3)
2431 return new Unknown64(machInst);
2432 shiftAmt = ((immh << 3) | immb) - (8 << size);
2433 if (u)
2434 return new SliDX<uint64_t>(machInst, vd, vn, shiftAmt);
2435 else
2436 return new ShlDX<uint64_t>(machInst, vd, vn, shiftAmt);
2437 case 0x0c:
2438 if (u) {
2439 shiftAmt = ((immh << 3) | immb) - (8 << size);
2440 return decodeNeonSTwoShiftUReg<SqshluScX>(
2441 size, machInst, vd, vn, shiftAmt);
2442 } else {
2443 return new Unknown64(machInst);
2444 }
2445 case 0x0e:
2446 shiftAmt = ((immh << 3) | immb) - (8 << size);
2447 if (u)
2448 return decodeNeonUTwoShiftUReg<UqshlImmScX>(
2449 size, machInst, vd, vn, shiftAmt);
2450 else
2451 return decodeNeonSTwoShiftUReg<SqshlImmScX>(
2452 size, machInst, vd, vn, shiftAmt);
2453 case 0x10:
2454 if (!u || immh3)
2455 return new Unknown64(machInst);
2456 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2457 return decodeNeonSTwoShiftUSReg<SqshrunScX>(
2458 size, machInst, vd, vn, shiftAmt);
2459 case 0x11:
2460 if (!u || immh3)
2461 return new Unknown64(machInst);
2462 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2463 return decodeNeonSTwoShiftUSReg<SqrshrunScX>(
2464 size, machInst, vd, vn, shiftAmt);
2465 case 0x12:
2466 if (immh3)
2467 return new Unknown64(machInst);
2468 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2469 if (u)
2470 return decodeNeonUTwoShiftUSReg<UqshrnScX>(
2471 size, machInst, vd, vn, shiftAmt);
2472 else
2473 return decodeNeonSTwoShiftUSReg<SqshrnScX>(
2474 size, machInst, vd, vn, shiftAmt);
2475 case 0x13:
2476 if (immh3)
2477 return new Unknown64(machInst);
2478 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2479 if (u)
2480 return decodeNeonUTwoShiftUSReg<UqrshrnScX>(
2481 size, machInst, vd, vn, shiftAmt);
2482 else
2483 return decodeNeonSTwoShiftUSReg<SqrshrnScX>(
2484 size, machInst, vd, vn, shiftAmt);
2485 case 0x1c:
2486 if (immh < 0x4)
2487 return new Unknown64(machInst);
2488 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2489 if (u) {
2490 return decodeNeonUTwoShiftUFpReg<UcvtfFixedScX>(
2491 size & 0x1, machInst, vd, vn, shiftAmt);
2492 } else {
2493 if (size & 0x1)
2494 return new ScvtfFixedScDX<uint64_t>(machInst, vd, vn,
2495 shiftAmt);
2496 else
2497 return new ScvtfFixedScSX<uint32_t>(machInst, vd, vn,
2498 shiftAmt);
2499 }
2500 case 0x1f:
2501 if (immh < 0x4)
2502 return new Unknown64(machInst);
2503 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2504 if (u)
2505 return decodeNeonUTwoShiftUFpReg<FcvtzuFixedScX>(
2506 size & 0x1, machInst, vd, vn, shiftAmt);
2507 else
2508 return decodeNeonUTwoShiftUFpReg<FcvtzsFixedScX>(
2509 size & 0x1, machInst, vd, vn, shiftAmt);
2510 default:
2511 return new Unknown64(machInst);
2512 }
2513 }
2514
2515 StaticInstPtr
2516 decodeNeonMem(ExtMachInst machInst)
2517 {
2518 uint8_t dataSize = bits(machInst, 30) ? 128 : 64;
2519 bool multiple = bits(machInst, 24, 23) < 0x2;
2520 bool load = bits(machInst, 22);
2521
2522 uint8_t numStructElems = 0;
2523 uint8_t numRegs = 0;
2524
2525 if (multiple) { // AdvSIMD load/store multiple structures
2526 uint8_t opcode = bits(machInst, 15, 12);
2527 uint8_t eSize = bits(machInst, 11, 10);
2528 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23));
2529
2530 switch (opcode) {
2531 case 0x0: // LD/ST4 (4 regs)
2532 numStructElems = 4;
2533 numRegs = 4;
2534 break;
2535 case 0x2: // LD/ST1 (4 regs)
2536 numStructElems = 1;
2537 numRegs = 4;
2538 break;
2539 case 0x4: // LD/ST3 (3 regs)
2540 numStructElems = 3;
2541 numRegs = 3;
2542 break;
2543 case 0x6: // LD/ST1 (3 regs)
2544 numStructElems = 1;
2545 numRegs = 3;
2546 break;
2547 case 0x7: // LD/ST1 (1 reg)
2548 numStructElems = 1;
2549 numRegs = 1;
2550 break;
2551 case 0x8: // LD/ST2 (2 regs)
2552 numStructElems = 2;
2553 numRegs = 2;
2554 break;
2555 case 0xa: // LD/ST1 (2 regs)
2556 numStructElems = 1;
2557 numRegs = 2;
2558 break;
2559 default:
2560 return new Unknown64(machInst);
2561 }
2562
2563 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2564 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2565 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
2566
2567 if (load) {
2568 return new VldMult64(machInst, rn, vd, rm, eSize, dataSize,
2569 numStructElems, numRegs, wb);
2570 } else {
2571 return new VstMult64(machInst, rn, vd, rm, eSize, dataSize,
2572 numStructElems, numRegs, wb);
2573 }
2574 } else { // AdvSIMD load/store single structure
2575 uint8_t scale = bits(machInst, 15, 14);
2576 uint8_t numStructElems = (((uint8_t) bits(machInst, 13) << 1) |
2577 (uint8_t) bits(machInst, 21)) + 1;
2578 uint8_t index = 0;
2579 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23));
2580 bool replicate = false;
2581
2582 switch (scale) {
2583 case 0x0:
2584 index = ((uint8_t) bits(machInst, 30) << 3) |
2585 ((uint8_t) bits(machInst, 12) << 2) |
2586 (uint8_t) bits(machInst, 11, 10);
2587 break;
2588 case 0x1:
2589 index = ((uint8_t) bits(machInst, 30) << 2) |
2590 ((uint8_t) bits(machInst, 12) << 1) |
2591 (uint8_t) bits(machInst, 11);
2592 break;
2593 case 0x2:
2594 if (bits(machInst, 10) == 0x0) {
2595 index = ((uint8_t) bits(machInst, 30) << 1) |
2596 bits(machInst, 12);
2597 } else {
2598 index = (uint8_t) bits(machInst, 30);
2599 scale = 0x3;
2600 }
2601 break;
2602 case 0x3:
2603 scale = bits(machInst, 11, 10);
2604 replicate = true;
2605 break;
2606 default:
2607 return new Unknown64(machInst);
2608 }
2609
2610 uint8_t eSize = scale;
2611
2612 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2613 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2614 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
2615
2616 if (load) {
2617 return new VldSingle64(machInst, rn, vd, rm, eSize, dataSize,
2618 numStructElems, index, wb, replicate);
2619 } else {
2620 return new VstSingle64(machInst, rn, vd, rm, eSize, dataSize,
2621 numStructElems, index, wb, replicate);
2622 }
2623 }
2624 }
2625}
2626}};
1274 StaticInstPtr
1275 decodeNeonIndexedElem(ExtMachInst machInst)
1276 {
1277 uint8_t q = bits(machInst, 30);
1278 uint8_t u = bits(machInst, 29);
1279 uint8_t size = bits(machInst, 23, 22);
1280 uint8_t L = bits(machInst, 21);
1281 uint8_t M = bits(machInst, 20);
1282 uint8_t opcode = bits(machInst, 15, 12);
1283 uint8_t H = bits(machInst, 11);
1284
1285 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1286 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1287 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16);
1288
1289 uint8_t index = 0;
1290 uint8_t index_fp = 0;
1291 uint8_t vmh = 0;
1292 uint8_t sz = size & 0x1;
1293 uint8_t sz_q = (sz << 1) | bits(machInst, 30);
1294 uint8_t sz_L = (sz << 1) | L;
1295
1296 // Index and 2nd register operand for integer instructions
1297 if (size == 0x1) {
1298 index = (H << 2) | (L << 1) | M;
1299 // vmh = 0;
1300 } else if (size == 0x2) {
1301 index = (H << 1) | L;
1302 vmh = M;
1303 }
1304 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
1305
1306 // Index and 2nd register operand for FP instructions
1307 vmh = M;
1308 if ((size & 0x1) == 0) {
1309 index_fp = (H << 1) | L;
1310 } else if (L == 0) {
1311 index_fp = H;
1312 }
1313 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
1314
1315 switch (opcode) {
1316 case 0x0:
1317 if (!u || (size == 0x0 || size == 0x3))
1318 return new Unknown64(machInst);
1319 else
1320 return decodeNeonUThreeImmHAndWReg<MlaElemDX, MlaElemQX>(
1321 q, size, machInst, vd, vn, vm, index);
1322 case 0x1:
1323 if (!u && size >= 2 && sz_q != 0x2 && sz_L != 0x3)
1324 return decodeNeonUThreeImmFpReg<FmlaElemDX, FmlaElemQX>(
1325 q, sz, machInst, vd, vn, vm_fp, index_fp);
1326 else
1327 return new Unknown64(machInst);
1328 case 0x2:
1329 if (size == 0x0 || size == 0x3)
1330 return new Unknown64(machInst);
1331 if (u)
1332 return decodeNeonUThreeImmHAndWReg<UmlalElemX, UmlalElem2X>(
1333 q, size, machInst, vd, vn, vm, index);
1334 else
1335 return decodeNeonSThreeImmHAndWReg<SmlalElemX, SmlalElem2X>(
1336 q, size, machInst, vd, vn, vm, index);
1337 case 0x3:
1338 if (u || (size == 0x0 || size == 0x3))
1339 return new Unknown64(machInst);
1340 else
1341 return decodeNeonSThreeImmHAndWReg<SqdmlalElemX,
1342 SqdmlalElem2X>(
1343 q, size, machInst, vd, vn, vm, index);
1344 case 0x4:
1345 if (u && !(size == 0x0 || size == 0x3))
1346 return decodeNeonUThreeImmHAndWReg<MlsElemDX, MlsElemQX>(
1347 q, size, machInst, vd, vn, vm, index);
1348 else
1349 return new Unknown64(machInst);
1350 case 0x5:
1351 if (!u && size >= 0x2 && sz_L != 0x3 && sz_q != 0x2)
1352 return decodeNeonUThreeImmFpReg<FmlsElemDX, FmlsElemQX>(
1353 q, sz, machInst, vd, vn, vm_fp, index_fp);
1354 else
1355 return new Unknown64(machInst);
1356 case 0x6:
1357 if (size == 0x0 || size == 0x3)
1358 return new Unknown64(machInst);
1359 if (u)
1360 return decodeNeonUThreeImmHAndWReg<UmlslElemX, UmlslElem2X>(
1361 q, size, machInst, vd, vn, vm, index);
1362 else
1363 return decodeNeonSThreeImmHAndWReg<SmlslElemX, SmlslElem2X>(
1364 q, size, machInst, vd, vn, vm, index);
1365 case 0x7:
1366 if (u || (size == 0x0 || size == 0x3))
1367 return new Unknown64(machInst);
1368 else
1369 return decodeNeonSThreeImmHAndWReg<SqdmlslElemX,
1370 SqdmlslElem2X>(
1371 q, size, machInst, vd, vn, vm, index);
1372 case 0x8:
1373 if (u || (size == 0x0 || size == 0x3))
1374 return new Unknown64(machInst);
1375 else
1376 return decodeNeonUThreeImmHAndWReg<MulElemDX, MulElemQX>(
1377 q, size, machInst, vd, vn, vm, index);
1378 case 0x9:
1379 if (size >= 2 && sz_q != 0x2 && sz_L != 0x3) {
1380 if (u)
1381 return decodeNeonUThreeImmFpReg<FmulxElemDX, FmulxElemQX>(
1382 q, sz, machInst, vd, vn, vm_fp, index_fp);
1383 else
1384 return decodeNeonUThreeImmFpReg<FmulElemDX, FmulElemQX>(
1385 q, sz, machInst, vd, vn, vm_fp, index_fp);
1386 } else {
1387 return new Unknown64(machInst);
1388 }
1389 case 0xa:
1390 if (size == 0x0 || size == 0x3)
1391 return new Unknown64(machInst);
1392 if (u)
1393 return decodeNeonUThreeImmHAndWReg<UmullElemX, UmullElem2X>(
1394 q, size, machInst, vd, vn, vm, index);
1395 else
1396 return decodeNeonSThreeImmHAndWReg<SmullElemX, SmullElem2X>(
1397 q, size, machInst, vd, vn, vm, index);
1398 case 0xb:
1399 if (u || (size == 0x0 || size == 0x3))
1400 return new Unknown64(machInst);
1401 else
1402 return decodeNeonSThreeImmHAndWReg<SqdmullElemX, SqdmullElem2X>(
1403 q, size, machInst, vd, vn, vm, index);
1404 case 0xc:
1405 if (u || (size == 0x0 || size == 0x3))
1406 return new Unknown64(machInst);
1407 else
1408 return decodeNeonSThreeImmHAndWReg<SqdmulhElemDX, SqdmulhElemQX>(
1409 q, size, machInst, vd, vn, vm, index);
1410 case 0xd:
1411 if (u || (size == 0x0 || size == 0x3))
1412 return new Unknown64(machInst);
1413 else
1414 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemDX, SqrdmulhElemQX>(
1415 q, size, machInst, vd, vn, vm, index);
1416 default:
1417 return new Unknown64(machInst);
1418 }
1419 }
1420
1421 StaticInstPtr
1422 decodeNeonModImm(ExtMachInst machInst)
1423 {
1424 uint8_t q = bits(machInst, 30);
1425 uint8_t op = bits(machInst, 29);
1426 uint8_t abcdefgh = (bits(machInst, 18, 16) << 5) |
1427 bits(machInst, 9, 5);
1428 uint8_t cmode = bits(machInst, 15, 12);
1429 uint8_t o2 = bits(machInst, 11);
1430
1431 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1432
1433 if (o2 == 0x1 || (op == 0x1 && cmode == 0xf && !q))
1434 return new Unknown64(machInst);
1435
1436 bool immValid = true;
1437 const uint64_t bigImm = simd_modified_imm(op, cmode, abcdefgh,
1438 immValid,
1439 true /* isAarch64 */);
1440 if (!immValid) {
1441 return new Unknown(machInst);
1442 }
1443
1444 if (op) {
1445 if (bits(cmode, 3) == 0) {
1446 if (bits(cmode, 0) == 0) {
1447 if (q)
1448 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1449 else
1450 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1451 } else {
1452 if (q)
1453 return new BicImmQX<uint64_t>(machInst, vd, bigImm);
1454 else
1455 return new BicImmDX<uint64_t>(machInst, vd, bigImm);
1456 }
1457 } else {
1458 if (bits(cmode, 2) == 1) {
1459 switch (bits(cmode, 1, 0)) {
1460 case 0:
1461 case 1:
1462 if (q)
1463 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1464 else
1465 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1466 case 2:
1467 if (q)
1468 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1469 else
1470 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1471 case 3:
1472 if (q)
1473 return new FmovQX<uint64_t>(machInst, vd, bigImm);
1474 else
1475 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1476 }
1477 } else {
1478 if (bits(cmode, 0) == 0) {
1479 if (q)
1480 return new MvniQX<uint64_t>(machInst, vd, bigImm);
1481 else
1482 return new MvniDX<uint64_t>(machInst, vd, bigImm);
1483 } else {
1484 if (q)
1485 return new BicImmQX<uint64_t>(machInst, vd,
1486 bigImm);
1487 else
1488 return new BicImmDX<uint64_t>(machInst, vd,
1489 bigImm);
1490 }
1491 }
1492 }
1493 } else {
1494 if (bits(cmode, 3) == 0) {
1495 if (bits(cmode, 0) == 0) {
1496 if (q)
1497 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1498 else
1499 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1500 } else {
1501 if (q)
1502 return new OrrImmQX<uint64_t>(machInst, vd, bigImm);
1503 else
1504 return new OrrImmDX<uint64_t>(machInst, vd, bigImm);
1505 }
1506 } else {
1507 if (bits(cmode, 2) == 1) {
1508 if (bits(cmode, 1, 0) == 0x3) {
1509 if (q)
1510 return new FmovQX<uint32_t>(machInst, vd, bigImm);
1511 else
1512 return new FmovDX<uint32_t>(machInst, vd, bigImm);
1513 } else {
1514 if (q)
1515 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1516 else
1517 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1518 }
1519 } else {
1520 if (bits(cmode, 0) == 0) {
1521 if (q)
1522 return new MoviQX<uint64_t>(machInst, vd, bigImm);
1523 else
1524 return new MoviDX<uint64_t>(machInst, vd, bigImm);
1525 } else {
1526 if (q)
1527 return new OrrImmQX<uint64_t>(machInst, vd,
1528 bigImm);
1529 else
1530 return new OrrImmDX<uint64_t>(machInst, vd, bigImm);
1531 }
1532 }
1533 }
1534 }
1535 return new Unknown(machInst);
1536 }
1537
1538 StaticInstPtr
1539 decodeNeonShiftByImm(ExtMachInst machInst)
1540 {
1541 uint8_t q = bits(machInst, 30);
1542 uint8_t u = bits(machInst, 29);
1543 uint8_t immh = bits(machInst, 22, 19);
1544 uint8_t immb = bits(machInst, 18, 16);
1545 uint8_t opcode = bits(machInst, 15, 11);
1546
1547 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1548 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1549
1550 uint8_t immh3 = bits(machInst, 22);
1551 uint8_t immh3_q = (immh3 << 1) | q;
1552 uint8_t op_u = (bits(machInst, 12) << 1) | u;
1553 uint8_t size = findMsbSet(immh);
1554 int shiftAmt = 0;
1555
1556 switch (opcode) {
1557 case 0x00:
1558 if (immh3_q == 0x2)
1559 return new Unknown64(machInst);
1560 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1561 if (u)
1562 return decodeNeonUTwoShiftXReg<UshrDX, UshrQX>(
1563 q, size, machInst, vd, vn, shiftAmt);
1564 else
1565 return decodeNeonSTwoShiftXReg<SshrDX, SshrQX>(
1566 q, size, machInst, vd, vn, shiftAmt);
1567 case 0x02:
1568 if (immh3_q == 0x2)
1569 return new Unknown64(machInst);
1570 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1571 if (u)
1572 return decodeNeonUTwoShiftXReg<UsraDX, UsraQX>(
1573 q, size, machInst, vd, vn, shiftAmt);
1574 else
1575 return decodeNeonSTwoShiftXReg<SsraDX, SsraQX>(
1576 q, size, machInst, vd, vn, shiftAmt);
1577 case 0x04:
1578 if (immh3_q == 0x2)
1579 return new Unknown64(machInst);
1580 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1581 if (u)
1582 return decodeNeonUTwoShiftXReg<UrshrDX, UrshrQX>(
1583 q, size, machInst, vd, vn, shiftAmt);
1584 else
1585 return decodeNeonSTwoShiftXReg<SrshrDX, SrshrQX>(
1586 q, size, machInst, vd, vn, shiftAmt);
1587 case 0x06:
1588 if (immh3_q == 0x2)
1589 return new Unknown64(machInst);
1590 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1591 if (u)
1592 return decodeNeonUTwoShiftXReg<UrsraDX, UrsraQX>(
1593 q, size, machInst, vd, vn, shiftAmt);
1594 else
1595 return decodeNeonSTwoShiftXReg<SrsraDX, SrsraQX>(
1596 q, size, machInst, vd, vn, shiftAmt);
1597 case 0x08:
1598 if (u && !(immh3_q == 0x2)) {
1599 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1600 return decodeNeonUTwoShiftXReg<SriDX, SriQX>(
1601 q, size, machInst, vd, vn, shiftAmt);
1602 } else {
1603 return new Unknown64(machInst);
1604 }
1605 case 0x0a:
1606 if (immh3_q == 0x2)
1607 return new Unknown64(machInst);
1608 shiftAmt = ((immh << 3) | immb) - (8 << size);
1609 if (u)
1610 return decodeNeonUTwoShiftXReg<SliDX, SliQX>(
1611 q, size, machInst, vd, vn, shiftAmt);
1612 else
1613 return decodeNeonUTwoShiftXReg<ShlDX, ShlQX>(
1614 q, size, machInst, vd, vn, shiftAmt);
1615 case 0x0c:
1616 if (u && !(immh3_q == 0x2 || op_u == 0x0)) {
1617 shiftAmt = ((immh << 3) | immb) - (8 << size);
1618 return decodeNeonSTwoShiftXReg<SqshluDX, SqshluQX>(
1619 q, size, machInst, vd, vn, shiftAmt);
1620 } else {
1621 return new Unknown64(machInst);
1622 }
1623 case 0x0e:
1624 if (immh3_q == 0x2 || op_u == 0x0)
1625 return new Unknown64(machInst);
1626 shiftAmt = ((immh << 3) | immb) - (8 << size);
1627 if (u)
1628 return decodeNeonUTwoShiftXReg<UqshlImmDX, UqshlImmQX>(
1629 q, size, machInst, vd, vn, shiftAmt);
1630 else
1631 return decodeNeonSTwoShiftXReg<SqshlImmDX, SqshlImmQX>(
1632 q, size, machInst, vd, vn, shiftAmt);
1633 case 0x10:
1634 if (immh3)
1635 return new Unknown64(machInst);
1636 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1637 if (u)
1638 return decodeNeonSTwoShiftSReg<SqshrunX, Sqshrun2X>(
1639 q, size, machInst, vd, vn, shiftAmt);
1640 else
1641 return decodeNeonUTwoShiftSReg<ShrnX, Shrn2X>(
1642 q, size, machInst, vd, vn, shiftAmt);
1643 case 0x11:
1644 if (immh3)
1645 return new Unknown64(machInst);
1646 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1647 if (u)
1648 return decodeNeonSTwoShiftSReg<SqrshrunX, Sqrshrun2X>(
1649 q, size, machInst, vd, vn, shiftAmt);
1650 else
1651 return decodeNeonUTwoShiftSReg<RshrnX, Rshrn2X>(
1652 q, size, machInst, vd, vn, shiftAmt);
1653 case 0x12:
1654 if (immh3)
1655 return new Unknown64(machInst);
1656 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1657 if (u)
1658 return decodeNeonUTwoShiftSReg<UqshrnX, Uqshrn2X>(
1659 q, size, machInst, vd, vn, shiftAmt);
1660 else
1661 return decodeNeonSTwoShiftSReg<SqshrnX, Sqshrn2X>(
1662 q, size, machInst, vd, vn, shiftAmt);
1663 case 0x13:
1664 if (immh3)
1665 return new Unknown64(machInst);
1666 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1667 if (u)
1668 return decodeNeonUTwoShiftSReg<UqrshrnX, Uqrshrn2X>(
1669 q, size, machInst, vd, vn, shiftAmt);
1670 else
1671 return decodeNeonSTwoShiftSReg<SqrshrnX, Sqrshrn2X>(
1672 q, size, machInst, vd, vn, shiftAmt);
1673 case 0x14:
1674 if (immh3)
1675 return new Unknown64(machInst);
1676 shiftAmt = ((immh << 3) | immb) - (8 << size);
1677 if (u)
1678 return decodeNeonUTwoShiftSReg<UshllX, Ushll2X>(
1679 q, size, machInst, vd, vn, shiftAmt);
1680 else
1681 return decodeNeonSTwoShiftSReg<SshllX, Sshll2X>(
1682 q, size, machInst, vd, vn, shiftAmt);
1683 case 0x1c:
1684 if (immh < 0x4 || immh3_q == 0x2)
1685 return new Unknown64(machInst);
1686 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1687 if (u) {
1688 return decodeNeonUTwoShiftFpReg<UcvtfFixedDX, UcvtfFixedQX>(
1689 q, size & 0x1, machInst, vd, vn, shiftAmt);
1690 } else {
1691 if (q) {
1692 if (size & 0x1)
1693 return new ScvtfFixedDQX<uint64_t>(machInst, vd, vn,
1694 shiftAmt);
1695 else
1696 return new ScvtfFixedSQX<uint32_t>(machInst, vd, vn,
1697 shiftAmt);
1698 } else {
1699 if (size & 0x1)
1700 return new Unknown(machInst);
1701 else
1702 return new ScvtfFixedDX<uint32_t>(machInst, vd, vn,
1703 shiftAmt);
1704 }
1705 }
1706 case 0x1f:
1707 if (immh < 0x4 || immh3_q == 0x2)
1708 return new Unknown64(machInst);
1709 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
1710 if (u)
1711 return decodeNeonUTwoShiftFpReg<FcvtzuFixedDX, FcvtzuFixedQX>(
1712 q, size & 0x1, machInst, vd, vn, shiftAmt);
1713 else
1714 return decodeNeonUTwoShiftFpReg<FcvtzsFixedDX, FcvtzsFixedQX>(
1715 q, size & 0x1, machInst, vd, vn, shiftAmt);
1716 default:
1717 return new Unknown64(machInst);
1718 }
1719 }
1720
1721 StaticInstPtr
1722 decodeNeonTblTbx(ExtMachInst machInst)
1723 {
1724 uint8_t q = bits(machInst, 30);
1725
1726 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1727 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1728 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1729
1730 uint8_t switchVal = bits(machInst, 14, 12);
1731
1732 switch (switchVal) {
1733 case 0x0:
1734 if (q)
1735 return new Tbl1QX<uint8_t>(machInst, vd, vn, vm);
1736 else
1737 return new Tbl1DX<uint8_t>(machInst, vd, vn, vm);
1738 case 0x1:
1739 if (q)
1740 return new Tbx1QX<uint8_t>(machInst, vd, vn, vm);
1741 else
1742 return new Tbx1DX<uint8_t>(machInst, vd, vn, vm);
1743 case 0x2:
1744 if (q)
1745 return new Tbl2QX<uint8_t>(machInst, vd, vn, vm);
1746 else
1747 return new Tbl2DX<uint8_t>(machInst, vd, vn, vm);
1748 case 0x3:
1749 if (q)
1750 return new Tbx2QX<uint8_t>(machInst, vd, vn, vm);
1751 else
1752 return new Tbx2DX<uint8_t>(machInst, vd, vn, vm);
1753 case 0x4:
1754 if (q)
1755 return new Tbl3QX<uint8_t>(machInst, vd, vn, vm);
1756 else
1757 return new Tbl3DX<uint8_t>(machInst, vd, vn, vm);
1758 case 0x5:
1759 if (q)
1760 return new Tbx3QX<uint8_t>(machInst, vd, vn, vm);
1761 else
1762 return new Tbx3DX<uint8_t>(machInst, vd, vn, vm);
1763 case 0x6:
1764 if (q)
1765 return new Tbl4QX<uint8_t>(machInst, vd, vn, vm);
1766 else
1767 return new Tbl4DX<uint8_t>(machInst, vd, vn, vm);
1768 case 0x7:
1769 if (q)
1770 return new Tbx4QX<uint8_t>(machInst, vd, vn, vm);
1771 else
1772 return new Tbx4DX<uint8_t>(machInst, vd, vn, vm);
1773 default:
1774 return new Unknown64(machInst);
1775 }
1776
1777 return new Unknown64(machInst);
1778 }
1779
1780 StaticInstPtr
1781 decodeNeonZipUzpTrn(ExtMachInst machInst)
1782 {
1783 uint8_t q = bits(machInst, 30);
1784 uint8_t size = bits(machInst, 23, 22);
1785 uint8_t opcode = bits(machInst, 14, 12);
1786
1787 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1788 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1789 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1790
1791 switch (opcode) {
1792 case 0x1:
1793 return decodeNeonUThreeXReg<Uzp1DX, Uzp1QX>(
1794 q, size, machInst, vd, vn, vm);
1795 case 0x2:
1796 return decodeNeonUThreeXReg<Trn1DX, Trn1QX>(
1797 q, size, machInst, vd, vn, vm);
1798 case 0x3:
1799 return decodeNeonUThreeXReg<Zip1DX, Zip1QX>(
1800 q, size, machInst, vd, vn, vm);
1801 case 0x5:
1802 return decodeNeonUThreeXReg<Uzp2DX, Uzp2QX>(
1803 q, size, machInst, vd, vn, vm);
1804 case 0x6:
1805 return decodeNeonUThreeXReg<Trn2DX, Trn2QX>(
1806 q, size, machInst, vd, vn, vm);
1807 case 0x7:
1808 return decodeNeonUThreeXReg<Zip2DX, Zip2QX>(
1809 q, size, machInst, vd, vn, vm);
1810 default:
1811 return new Unknown64(machInst);
1812 }
1813 return new Unknown64(machInst);
1814 }
1815
1816 StaticInstPtr
1817 decodeNeonExt(ExtMachInst machInst)
1818 {
1819 uint8_t q = bits(machInst, 30);
1820 uint8_t op2 = bits(machInst, 23, 22);
1821 uint8_t imm4 = bits(machInst, 14, 11);
1822
1823 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1824 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1825 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1826
1827 if (op2 != 0 || (q == 0x0 && bits(imm4, 3) == 0x1))
1828 return new Unknown64(machInst);
1829
1830 uint8_t index = q ? imm4 : imm4 & 0x7;
1831
1832 if (q) {
1833 return new ExtQX<uint8_t>(machInst, vd, vn, vm, index);
1834 } else {
1835 return new ExtDX<uint8_t>(machInst, vd, vn, vm, index);
1836 }
1837 }
1838
1839 StaticInstPtr
1840 decodeNeonSc3Same(ExtMachInst machInst)
1841 {
1842 uint8_t u = bits(machInst, 29);
1843 uint8_t size = bits(machInst, 23, 22);
1844 uint8_t opcode = bits(machInst, 15, 11);
1845 uint8_t s = bits(machInst, 11);
1846
1847 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1848 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1849 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
1850
1851 switch (opcode) {
1852 case 0x01:
1853 if (u)
1854 return decodeNeonUThreeUReg<UqaddScX>(
1855 size, machInst, vd, vn, vm);
1856 else
1857 return decodeNeonSThreeUReg<SqaddScX>(
1858 size, machInst, vd, vn, vm);
1859 case 0x05:
1860 if (u)
1861 return decodeNeonUThreeUReg<UqsubScX>(
1862 size, machInst, vd, vn, vm);
1863 else
1864 return decodeNeonSThreeUReg<SqsubScX>(
1865 size, machInst, vd, vn, vm);
1866 case 0x06:
1867 if (size != 0x3)
1868 return new Unknown64(machInst);
1869 if (u)
1870 return new CmhiDX<uint64_t>(machInst, vd, vn, vm);
1871 else
1872 return new CmgtDX<int64_t>(machInst, vd, vn, vm);
1873 case 0x07:
1874 if (size != 0x3)
1875 return new Unknown64(machInst);
1876 if (u)
1877 return new CmhsDX<uint64_t>(machInst, vd, vn, vm);
1878 else
1879 return new CmgeDX<int64_t>(machInst, vd, vn, vm);
1880 case 0x08:
1881 if (!s && size != 0x3)
1882 return new Unknown64(machInst);
1883 if (u)
1884 return new UshlDX<uint64_t>(machInst, vd, vn, vm);
1885 else
1886 return new SshlDX<int64_t>(machInst, vd, vn, vm);
1887 case 0x09:
1888 if (!s && size != 0x3)
1889 return new Unknown64(machInst);
1890 if (u)
1891 return decodeNeonUThreeUReg<UqshlScX>(
1892 size, machInst, vd, vn, vm);
1893 else
1894 return decodeNeonSThreeUReg<SqshlScX>(
1895 size, machInst, vd, vn, vm);
1896 case 0x0a:
1897 if (!s && size != 0x3)
1898 return new Unknown64(machInst);
1899 if (u)
1900 return new UrshlDX<uint64_t>(machInst, vd, vn, vm);
1901 else
1902 return new SrshlDX<int64_t>(machInst, vd, vn, vm);
1903 case 0x0b:
1904 if (!s && size != 0x3)
1905 return new Unknown64(machInst);
1906 if (u)
1907 return decodeNeonUThreeUReg<UqrshlScX>(
1908 size, machInst, vd, vn, vm);
1909 else
1910 return decodeNeonSThreeUReg<SqrshlScX>(
1911 size, machInst, vd, vn, vm);
1912 case 0x10:
1913 if (size != 0x3)
1914 return new Unknown64(machInst);
1915 if (u)
1916 return new SubDX<uint64_t>(machInst, vd, vn, vm);
1917 else
1918 return new AddDX<uint64_t>(machInst, vd, vn, vm);
1919 case 0x11:
1920 if (size != 0x3)
1921 return new Unknown64(machInst);
1922 if (u)
1923 return new CmeqDX<uint64_t>(machInst, vd, vn, vm);
1924 else
1925 return new CmtstDX<uint64_t>(machInst, vd, vn, vm);
1926 case 0x16:
1927 if (size == 0x3 || size == 0x0)
1928 return new Unknown64(machInst);
1929 if (u)
1930 return decodeNeonSThreeHAndWReg<SqrdmulhScX>(
1931 size, machInst, vd, vn, vm);
1932 else
1933 return decodeNeonSThreeHAndWReg<SqdmulhScX>(
1934 size, machInst, vd, vn, vm);
1935 case 0x1a:
1936 if (!u || size < 0x2)
1937 return new Unknown64(machInst);
1938 else
1939 return decodeNeonUThreeScFpReg<FabdScX>(
1940 size & 0x1, machInst, vd, vn, vm);
1941 case 0x1b:
1942 if (u || size > 0x1)
1943 return new Unknown64(machInst);
1944 else
1945 return decodeNeonUThreeScFpReg<FmulxScX>(
1946 size & 0x1, machInst, vd, vn, vm);
1947 case 0x1c:
1948 if (size < 0x2) {
1949 if (u)
1950 return decodeNeonUThreeScFpReg<FcmgeScX>(
1951 size & 0x1, machInst, vd, vn, vm);
1952 else
1953 return decodeNeonUThreeScFpReg<FcmeqScX>(
1954 size & 0x1, machInst, vd, vn, vm);
1955 } else {
1956 if (u)
1957 return decodeNeonUThreeScFpReg<FcmgtScX>(
1958 size & 0x1, machInst, vd, vn, vm);
1959 else
1960 return new Unknown64(machInst);
1961 }
1962 case 0x1d:
1963 if (!u)
1964 return new Unknown64(machInst);
1965 if (size < 0x2)
1966 return decodeNeonUThreeScFpReg<FacgeScX>(
1967 size & 0x1, machInst, vd, vn, vm);
1968 else
1969 return decodeNeonUThreeScFpReg<FacgtScX>(
1970 size & 0x1, machInst, vd, vn, vm);
1971 case 0x1f:
1972 if (u)
1973 return new Unknown64(machInst);
1974 if (size < 0x2)
1975 return decodeNeonUThreeScFpReg<FrecpsScX>(
1976 size & 0x1, machInst, vd, vn, vm);
1977 else
1978 return decodeNeonUThreeScFpReg<FrsqrtsScX>(
1979 size & 0x1, machInst, vd, vn, vm);
1980 default:
1981 return new Unknown64(machInst);
1982 }
1983 }
1984
1985 StaticInstPtr
1986 decodeNeonSc3Diff(ExtMachInst machInst)
1987 {
1988 if (bits(machInst, 29))
1989 return new Unknown64(machInst);
1990
1991 uint8_t size = bits(machInst, 23, 22);
1992 if (size == 0x0 || size == 0x3)
1993 return new Unknown64(machInst);
1994
1995 uint8_t opcode = bits(machInst, 15, 12);
1996
1997 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
1998 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
1999 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
2000
2001 switch (opcode) {
2002 case 0x9:
2003 return decodeNeonSThreeHAndWReg<SqdmlalScX>(size, machInst, vd, vn, vm);
2004 case 0xb:
2005 return decodeNeonSThreeHAndWReg<SqdmlslScX>(size, machInst, vd, vn, vm);
2006 case 0xd:
2007 return decodeNeonSThreeHAndWReg<SqdmullScX>(size, machInst, vd, vn, vm);
2008 default:
2009 return new Unknown64(machInst);
2010 }
2011 }
2012
2013 StaticInstPtr
2014 decodeNeonSc2RegMisc(ExtMachInst machInst)
2015 {
2016 uint8_t u = bits(machInst, 29);
2017 uint8_t size = bits(machInst, 23, 22);
2018 uint8_t opcode = bits(machInst, 16, 12);
2019
2020 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2021 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2022
2023 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5);
2024 switch (switchVal) {
2025 case 0x03:
2026 return decodeNeonUTwoMiscUReg<SuqaddScX>(size, machInst, vd, vn);
2027 case 0x07:
2028 return decodeNeonSTwoMiscUReg<SqabsScX>(size, machInst, vd, vn);
2029 case 0x08:
2030 if (size != 0x3)
2031 return new Unknown64(machInst);
2032 else
2033 return new CmgtZeroDX<int64_t>(machInst, vd, vn);
2034 case 0x09:
2035 if (size != 0x3)
2036 return new Unknown64(machInst);
2037 else
2038 return new CmeqZeroDX<int64_t>(machInst, vd, vn);
2039 case 0x0a:
2040 if (size != 0x3)
2041 return new Unknown64(machInst);
2042 else
2043 return new CmltZeroDX<int64_t>(machInst, vd, vn);
2044 case 0x0b:
2045 if (size != 0x3)
2046 return new Unknown64(machInst);
2047 else
2048 return new AbsDX<int64_t>(machInst, vd, vn);
2049 case 0x0c:
2050 if (size < 0x2)
2051 return new Unknown64(machInst);
2052 else
2053 return decodeNeonUTwoMiscScFpReg<FcmgtZeroScX>(
2054 size & 0x1, machInst, vd, vn);
2055 case 0x0d:
2056 if (size < 0x2)
2057 return new Unknown64(machInst);
2058 else
2059 return decodeNeonUTwoMiscScFpReg<FcmeqZeroScX>(
2060 size & 0x1, machInst, vd, vn);
2061 case 0x0e:
2062 if (size < 0x2)
2063 return new Unknown64(machInst);
2064 else
2065 return decodeNeonUTwoMiscScFpReg<FcmltZeroScX>(
2066 size & 0x1, machInst, vd, vn);
2067 case 0x14:
2068 if (size == 0x3) {
2069 return new Unknown64(machInst);
2070 } else {
2071 switch (size) {
2072 case 0x0:
2073 return new SqxtnScX<int8_t>(machInst, vd, vn);
2074 case 0x1:
2075 return new SqxtnScX<int16_t>(machInst, vd, vn);
2076 case 0x2:
2077 return new SqxtnScX<int32_t>(machInst, vd, vn);
2078 }
2079 }
2080 case 0x1a:
2081 if (size < 0x2)
2082 return decodeNeonUTwoMiscScFpReg<FcvtnsScX>(
2083 size & 0x1, machInst, vd, vn);
2084 else
2085 return decodeNeonUTwoMiscScFpReg<FcvtpsScX>(
2086 size & 0x1, machInst, vd, vn);
2087 case 0x1b:
2088 if (size < 0x2)
2089 return decodeNeonUTwoMiscScFpReg<FcvtmsScX>(
2090 size & 0x1, machInst, vd, vn);
2091 else
2092 return decodeNeonUTwoMiscScFpReg<FcvtzsIntScX>(
2093 size & 0x1, machInst, vd, vn);
2094 case 0x1c:
2095 if (size < 0x2)
2096 return decodeNeonUTwoMiscScFpReg<FcvtasScX>(
2097 size & 0x1, machInst, vd, vn);
2098 else
2099 return new Unknown64(machInst);
2100 case 0x1d:
2101 if (size < 0x2) {
2102 if (size & 0x1)
2103 return new ScvtfIntScDX<uint64_t>(machInst, vd, vn);
2104 else
2105 return new ScvtfIntScSX<uint32_t>(machInst, vd, vn);
2106 } else {
2107 return decodeNeonUTwoMiscScFpReg<FrecpeScX>(
2108 size & 0x1, machInst, vd, vn);
2109 }
2110 case 0x1f:
2111 if (size < 0x2)
2112 return new Unknown64(machInst);
2113 else
2114 return decodeNeonUTwoMiscScFpReg<FrecpxX>(
2115 size & 0x1, machInst, vd, vn);
2116 case 0x23:
2117 return decodeNeonUTwoMiscUReg<UsqaddScX>(size, machInst, vd, vn);
2118 case 0x27:
2119 return decodeNeonSTwoMiscUReg<SqnegScX>(size, machInst, vd, vn);
2120 case 0x28:
2121 if (size != 0x3)
2122 return new Unknown64(machInst);
2123 else
2124 return new CmgeZeroDX<int64_t>(machInst, vd, vn);
2125 case 0x29:
2126 if (size != 0x3)
2127 return new Unknown64(machInst);
2128 else
2129 return new CmleZeroDX<int64_t>(machInst, vd, vn);
2130 case 0x2b:
2131 if (size != 0x3)
2132 return new Unknown64(machInst);
2133 else
2134 return new NegDX<int64_t>(machInst, vd, vn);
2135 case 0x2c:
2136 if (size < 0x2)
2137 return new Unknown64(machInst);
2138 else
2139 return decodeNeonUTwoMiscScFpReg<FcmgeZeroScX>(
2140 size & 0x1, machInst, vd, vn);
2141 case 0x2d:
2142 if (size < 0x2)
2143 return new Unknown64(machInst);
2144 else
2145 return decodeNeonUTwoMiscScFpReg<FcmleZeroScX>(
2146 size & 0x1, machInst, vd, vn);
2147 case 0x32:
2148 if (size == 0x3) {
2149 return new Unknown64(machInst);
2150 } else {
2151 switch (size) {
2152 case 0x0:
2153 return new SqxtunScX<int8_t>(machInst, vd, vn);
2154 case 0x1:
2155 return new SqxtunScX<int16_t>(machInst, vd, vn);
2156 case 0x2:
2157 return new SqxtunScX<int32_t>(machInst, vd, vn);
2158 }
2159 }
2160 case 0x34:
2161 if (size == 0x3) {
2162 return new Unknown64(machInst);
2163 } else {
2164 switch (size) {
2165 case 0x0:
2166 return new UqxtnScX<uint8_t>(machInst, vd, vn);
2167 case 0x1:
2168 return new UqxtnScX<uint16_t>(machInst, vd, vn);
2169 case 0x2:
2170 return new UqxtnScX<uint32_t>(machInst, vd, vn);
2171 }
2172 }
2173 case 0x36:
2174 if (size != 0x1) {
2175 return new Unknown64(machInst);
2176 } else {
2177 return new FcvtxnScX<uint32_t>(machInst, vd, vn);
2178 }
2179 case 0x3a:
2180 if (size < 0x2)
2181 return decodeNeonUTwoMiscScFpReg<FcvtnuScX>(
2182 size & 0x1, machInst, vd, vn);
2183 else
2184 return decodeNeonUTwoMiscScFpReg<FcvtpuScX>(
2185 size & 0x1, machInst, vd, vn);
2186 case 0x3b:
2187 if (size < 0x2)
2188 return decodeNeonUTwoMiscScFpReg<FcvtmuScX>(
2189 size & 0x1, machInst, vd, vn);
2190 else
2191 return decodeNeonUTwoMiscScFpReg<FcvtzuIntScX>(
2192 size & 0x1, machInst, vd, vn);
2193 case 0x3c:
2194 if (size < 0x2)
2195 return decodeNeonUTwoMiscScFpReg<FcvtauScX>(
2196 size & 0x1, machInst, vd, vn);
2197 else
2198 return new Unknown64(machInst);
2199 case 0x3d:
2200 if (size < 0x2)
2201 return decodeNeonUTwoMiscScFpReg<UcvtfIntScX>(
2202 size & 0x1, machInst, vd, vn);
2203 else
2204 return decodeNeonUTwoMiscScFpReg<FrsqrteScX>(
2205 size & 0x1, machInst, vd, vn);
2206 default:
2207 return new Unknown64(machInst);
2208 }
2209 }
2210
2211 StaticInstPtr
2212 decodeNeonScPwise(ExtMachInst machInst)
2213 {
2214 uint8_t u = bits(machInst, 29);
2215 uint8_t size = bits(machInst, 23, 22);
2216 uint8_t opcode = bits(machInst, 16, 12);
2217
2218 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2219 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2220
2221 if (!u) {
2222 if (opcode == 0x1b && size == 0x3)
2223 return new AddpScQX<uint64_t>(machInst, vd, vn);
2224 else
2225 return new Unknown64(machInst);
2226 }
2227
2228 uint8_t switchVal = (opcode << 0) | (size << 5);
2229 switch (switchVal) {
2230 case 0x0c:
2231 case 0x2c:
2232 return decodeNeonUTwoMiscPwiseScFpReg<FmaxnmpScDX, FmaxnmpScQX>(
2233 size & 0x1, machInst, vd, vn);
2234 case 0x0d:
2235 case 0x2d:
2236 return decodeNeonUTwoMiscPwiseScFpReg<FaddpScDX, FaddpScQX>(
2237 size & 0x1, machInst, vd, vn);
2238 case 0x0f:
2239 case 0x2f:
2240 return decodeNeonUTwoMiscPwiseScFpReg<FmaxpScDX, FmaxpScQX>(
2241 size & 0x1, machInst, vd, vn);
2242 case 0x4c:
2243 case 0x6c:
2244 return decodeNeonUTwoMiscPwiseScFpReg<FminnmpScDX, FminnmpScQX>(
2245 size & 0x1, machInst, vd, vn);
2246 case 0x4f:
2247 case 0x6f:
2248 return decodeNeonUTwoMiscPwiseScFpReg<FminpScDX, FminpScQX>(
2249 size & 0x1, machInst, vd, vn);
2250 default:
2251 return new Unknown64(machInst);
2252 }
2253 }
2254
2255 StaticInstPtr
2256 decodeNeonScCopy(ExtMachInst machInst)
2257 {
2258 if (bits(machInst, 14, 11) != 0 || bits(machInst, 29))
2259 return new Unknown64(machInst);
2260
2261 uint8_t imm5 = bits(machInst, 20, 16);
2262
2263 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2264 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2265
2266 uint8_t size = findLsbSet(imm5);
2267 uint8_t index = bits(imm5, 4, size + 1);
2268
2269 return decodeNeonUTwoShiftUReg<DupElemScX>(
2270 size, machInst, vd, vn, index);
2271 }
2272
2273 StaticInstPtr
2274 decodeNeonScIndexedElem(ExtMachInst machInst)
2275 {
2276 uint8_t u = bits(machInst, 29);
2277 uint8_t size = bits(machInst, 23, 22);
2278 uint8_t L = bits(machInst, 21);
2279 uint8_t M = bits(machInst, 20);
2280 uint8_t opcode = bits(machInst, 15, 12);
2281 uint8_t H = bits(machInst, 11);
2282
2283 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2284 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2285 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16);
2286
2287 uint8_t index = 0;
2288 uint8_t index_fp = 0;
2289 uint8_t vmh = 0;
2290 uint8_t sz_L = bits(machInst, 22, 21);
2291
2292 // Index and 2nd register operand for integer instructions
2293 if (size == 0x1) {
2294 index = (H << 2) | (L << 1) | M;
2295 // vmh = 0;
2296 } else if (size == 0x2) {
2297 index = (H << 1) | L;
2298 vmh = M;
2299 } else if (size == 0x3) {
2300 index = H;
2301 vmh = M;
2302 }
2303 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
2304
2305 // Index and 2nd register operand for FP instructions
2306 vmh = M;
2307 if ((size & 0x1) == 0) {
2308 index_fp = (H << 1) | L;
2309 } else if (L == 0) {
2310 index_fp = H;
2311 }
2312 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf);
2313
2314 if (u && opcode != 9)
2315 return new Unknown64(machInst);
2316
2317 switch (opcode) {
2318 case 0x1:
2319 if (size < 2 || sz_L == 0x3)
2320 return new Unknown64(machInst);
2321 else
2322 return decodeNeonUThreeImmScFpReg<FmlaElemScX>(
2323 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2324 case 0x3:
2325 if (size == 0x0 || size == 0x3)
2326 return new Unknown64(machInst);
2327 else
2328 return decodeNeonSThreeImmHAndWReg<SqdmlalElemScX>(
2329 size, machInst, vd, vn, vm, index);
2330 case 0x5:
2331 if (size < 2 || sz_L == 0x3)
2332 return new Unknown64(machInst);
2333 else
2334 return decodeNeonUThreeImmScFpReg<FmlsElemScX>(
2335 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2336 case 0x7:
2337 if (size == 0x0 || size == 0x3)
2338 return new Unknown64(machInst);
2339 else
2340 return decodeNeonSThreeImmHAndWReg<SqdmlslElemScX>(
2341 size, machInst, vd, vn, vm, index);
2342 case 0x9:
2343 if (size < 2 || sz_L == 0x3)
2344 return new Unknown64(machInst);
2345 if (u)
2346 return decodeNeonUThreeImmScFpReg<FmulxElemScX>(
2347 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2348 else
2349 return decodeNeonUThreeImmScFpReg<FmulElemScX>(
2350 size & 0x1, machInst, vd, vn, vm_fp, index_fp);
2351 case 0xb:
2352 if (size == 0x0 || size == 0x3)
2353 return new Unknown64(machInst);
2354 else
2355 return decodeNeonSThreeImmHAndWReg<SqdmullElemScX>(
2356 size, machInst, vd, vn, vm, index);
2357 case 0xc:
2358 if (size == 0x0 || size == 0x3)
2359 return new Unknown64(machInst);
2360 else
2361 return decodeNeonSThreeImmHAndWReg<SqdmulhElemScX>(
2362 size, machInst, vd, vn, vm, index);
2363 case 0xd:
2364 if (size == 0x0 || size == 0x3)
2365 return new Unknown64(machInst);
2366 else
2367 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemScX>(
2368 size, machInst, vd, vn, vm, index);
2369 default:
2370 return new Unknown64(machInst);
2371 }
2372 }
2373
2374 StaticInstPtr
2375 decodeNeonScShiftByImm(ExtMachInst machInst)
2376 {
2377 bool u = bits(machInst, 29);
2378 uint8_t immh = bits(machInst, 22, 19);
2379 uint8_t immb = bits(machInst, 18, 16);
2380 uint8_t opcode = bits(machInst, 15, 11);
2381
2382 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2383 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2384
2385 uint8_t immh3 = bits(machInst, 22);
2386 uint8_t size = findMsbSet(immh);
2387 int shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2388
2389 if (immh == 0x0)
2390 return new Unknown64(machInst);
2391
2392 switch (opcode) {
2393 case 0x00:
2394 if (!immh3)
2395 return new Unknown64(machInst);
2396 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2397 if (u)
2398 return new UshrDX<uint64_t>(machInst, vd, vn, shiftAmt);
2399 else
2400 return new SshrDX<int64_t>(machInst, vd, vn, shiftAmt);
2401 case 0x02:
2402 if (!immh3)
2403 return new Unknown64(machInst);
2404 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2405 if (u)
2406 return new UsraDX<uint64_t>(machInst, vd, vn, shiftAmt);
2407 else
2408 return new SsraDX<int64_t>(machInst, vd, vn, shiftAmt);
2409 case 0x04:
2410 if (!immh3)
2411 return new Unknown64(machInst);
2412 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2413 if (u)
2414 return new UrshrDX<uint64_t>(machInst, vd, vn, shiftAmt);
2415 else
2416 return new SrshrDX<int64_t>(machInst, vd, vn, shiftAmt);
2417 case 0x06:
2418 if (!immh3)
2419 return new Unknown64(machInst);
2420 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2421 if (u)
2422 return new UrsraDX<uint64_t>(machInst, vd, vn, shiftAmt);
2423 else
2424 return new SrsraDX<int64_t>(machInst, vd, vn, shiftAmt);
2425 case 0x08:
2426 if (!immh3)
2427 return new Unknown64(machInst);
2428 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2429 if (u)
2430 return new SriDX<uint64_t>(machInst, vd, vn, shiftAmt);
2431 else
2432 return new Unknown64(machInst);
2433 case 0x0a:
2434 if (!immh3)
2435 return new Unknown64(machInst);
2436 shiftAmt = ((immh << 3) | immb) - (8 << size);
2437 if (u)
2438 return new SliDX<uint64_t>(machInst, vd, vn, shiftAmt);
2439 else
2440 return new ShlDX<uint64_t>(machInst, vd, vn, shiftAmt);
2441 case 0x0c:
2442 if (u) {
2443 shiftAmt = ((immh << 3) | immb) - (8 << size);
2444 return decodeNeonSTwoShiftUReg<SqshluScX>(
2445 size, machInst, vd, vn, shiftAmt);
2446 } else {
2447 return new Unknown64(machInst);
2448 }
2449 case 0x0e:
2450 shiftAmt = ((immh << 3) | immb) - (8 << size);
2451 if (u)
2452 return decodeNeonUTwoShiftUReg<UqshlImmScX>(
2453 size, machInst, vd, vn, shiftAmt);
2454 else
2455 return decodeNeonSTwoShiftUReg<SqshlImmScX>(
2456 size, machInst, vd, vn, shiftAmt);
2457 case 0x10:
2458 if (!u || immh3)
2459 return new Unknown64(machInst);
2460 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2461 return decodeNeonSTwoShiftUSReg<SqshrunScX>(
2462 size, machInst, vd, vn, shiftAmt);
2463 case 0x11:
2464 if (!u || immh3)
2465 return new Unknown64(machInst);
2466 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2467 return decodeNeonSTwoShiftUSReg<SqrshrunScX>(
2468 size, machInst, vd, vn, shiftAmt);
2469 case 0x12:
2470 if (immh3)
2471 return new Unknown64(machInst);
2472 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2473 if (u)
2474 return decodeNeonUTwoShiftUSReg<UqshrnScX>(
2475 size, machInst, vd, vn, shiftAmt);
2476 else
2477 return decodeNeonSTwoShiftUSReg<SqshrnScX>(
2478 size, machInst, vd, vn, shiftAmt);
2479 case 0x13:
2480 if (immh3)
2481 return new Unknown64(machInst);
2482 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2483 if (u)
2484 return decodeNeonUTwoShiftUSReg<UqrshrnScX>(
2485 size, machInst, vd, vn, shiftAmt);
2486 else
2487 return decodeNeonSTwoShiftUSReg<SqrshrnScX>(
2488 size, machInst, vd, vn, shiftAmt);
2489 case 0x1c:
2490 if (immh < 0x4)
2491 return new Unknown64(machInst);
2492 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2493 if (u) {
2494 return decodeNeonUTwoShiftUFpReg<UcvtfFixedScX>(
2495 size & 0x1, machInst, vd, vn, shiftAmt);
2496 } else {
2497 if (size & 0x1)
2498 return new ScvtfFixedScDX<uint64_t>(machInst, vd, vn,
2499 shiftAmt);
2500 else
2501 return new ScvtfFixedScSX<uint32_t>(machInst, vd, vn,
2502 shiftAmt);
2503 }
2504 case 0x1f:
2505 if (immh < 0x4)
2506 return new Unknown64(machInst);
2507 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb);
2508 if (u)
2509 return decodeNeonUTwoShiftUFpReg<FcvtzuFixedScX>(
2510 size & 0x1, machInst, vd, vn, shiftAmt);
2511 else
2512 return decodeNeonUTwoShiftUFpReg<FcvtzsFixedScX>(
2513 size & 0x1, machInst, vd, vn, shiftAmt);
2514 default:
2515 return new Unknown64(machInst);
2516 }
2517 }
2518
2519 StaticInstPtr
2520 decodeNeonMem(ExtMachInst machInst)
2521 {
2522 uint8_t dataSize = bits(machInst, 30) ? 128 : 64;
2523 bool multiple = bits(machInst, 24, 23) < 0x2;
2524 bool load = bits(machInst, 22);
2525
2526 uint8_t numStructElems = 0;
2527 uint8_t numRegs = 0;
2528
2529 if (multiple) { // AdvSIMD load/store multiple structures
2530 uint8_t opcode = bits(machInst, 15, 12);
2531 uint8_t eSize = bits(machInst, 11, 10);
2532 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23));
2533
2534 switch (opcode) {
2535 case 0x0: // LD/ST4 (4 regs)
2536 numStructElems = 4;
2537 numRegs = 4;
2538 break;
2539 case 0x2: // LD/ST1 (4 regs)
2540 numStructElems = 1;
2541 numRegs = 4;
2542 break;
2543 case 0x4: // LD/ST3 (3 regs)
2544 numStructElems = 3;
2545 numRegs = 3;
2546 break;
2547 case 0x6: // LD/ST1 (3 regs)
2548 numStructElems = 1;
2549 numRegs = 3;
2550 break;
2551 case 0x7: // LD/ST1 (1 reg)
2552 numStructElems = 1;
2553 numRegs = 1;
2554 break;
2555 case 0x8: // LD/ST2 (2 regs)
2556 numStructElems = 2;
2557 numRegs = 2;
2558 break;
2559 case 0xa: // LD/ST1 (2 regs)
2560 numStructElems = 1;
2561 numRegs = 2;
2562 break;
2563 default:
2564 return new Unknown64(machInst);
2565 }
2566
2567 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2568 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2569 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
2570
2571 if (load) {
2572 return new VldMult64(machInst, rn, vd, rm, eSize, dataSize,
2573 numStructElems, numRegs, wb);
2574 } else {
2575 return new VstMult64(machInst, rn, vd, rm, eSize, dataSize,
2576 numStructElems, numRegs, wb);
2577 }
2578 } else { // AdvSIMD load/store single structure
2579 uint8_t scale = bits(machInst, 15, 14);
2580 uint8_t numStructElems = (((uint8_t) bits(machInst, 13) << 1) |
2581 (uint8_t) bits(machInst, 21)) + 1;
2582 uint8_t index = 0;
2583 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23));
2584 bool replicate = false;
2585
2586 switch (scale) {
2587 case 0x0:
2588 index = ((uint8_t) bits(machInst, 30) << 3) |
2589 ((uint8_t) bits(machInst, 12) << 2) |
2590 (uint8_t) bits(machInst, 11, 10);
2591 break;
2592 case 0x1:
2593 index = ((uint8_t) bits(machInst, 30) << 2) |
2594 ((uint8_t) bits(machInst, 12) << 1) |
2595 (uint8_t) bits(machInst, 11);
2596 break;
2597 case 0x2:
2598 if (bits(machInst, 10) == 0x0) {
2599 index = ((uint8_t) bits(machInst, 30) << 1) |
2600 bits(machInst, 12);
2601 } else {
2602 index = (uint8_t) bits(machInst, 30);
2603 scale = 0x3;
2604 }
2605 break;
2606 case 0x3:
2607 scale = bits(machInst, 11, 10);
2608 replicate = true;
2609 break;
2610 default:
2611 return new Unknown64(machInst);
2612 }
2613
2614 uint8_t eSize = scale;
2615
2616 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
2617 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5);
2618 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16);
2619
2620 if (load) {
2621 return new VldSingle64(machInst, rn, vd, rm, eSize, dataSize,
2622 numStructElems, index, wb, replicate);
2623 } else {
2624 return new VstSingle64(machInst, rn, vd, rm, eSize, dataSize,
2625 numStructElems, index, wb, replicate);
2626 }
2627 }
2628 }
2629}
2630}};