fp.isa (10037:5cac77888310) fp.isa (11671:520509f3e66c)
1// -*- mode:c++ -*-
2
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011 ARM Limited
3// Copyright (c) 2010-2011,2016 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48output header {{
49
50 template<template <typename T> class Base>
51 StaticInstPtr
52 newNeonMemInst(const unsigned size,
53 const ExtMachInst &machInst,
54 const RegIndex dest, const RegIndex ra,
55 const uint32_t imm, const unsigned extraMemFlags)
56 {
57 switch (size) {
58 case 0:
59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
60 case 1:
61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
62 case 2:
63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
64 case 3:
65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
66 default:
67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
68 }
69 }
70
71 template<template <typename T> class Base>
72 StaticInstPtr
73 newNeonMixInst(const unsigned size,
74 const ExtMachInst &machInst,
75 const RegIndex dest, const RegIndex op1,
76 const uint32_t step)
77 {
78 switch (size) {
79 case 0:
80 return new Base<uint8_t>(machInst, dest, op1, step);
81 case 1:
82 return new Base<uint16_t>(machInst, dest, op1, step);
83 case 2:
84 return new Base<uint32_t>(machInst, dest, op1, step);
85 case 3:
86 return new Base<uint64_t>(machInst, dest, op1, step);
87 default:
88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
89 }
90 }
91
92}};
93
94let {{
95 header_output = '''
96 StaticInstPtr
97 decodeNeonMem(ExtMachInst machInst);
98
99 StaticInstPtr
100 decodeNeonData(ExtMachInst machInst);
101 '''
102
103 decoder_output = '''
104 StaticInstPtr
105 decodeNeonMem(ExtMachInst machInst)
106 {
107 const uint32_t b = bits(machInst, 11, 8);
108 const bool single = bits(machInst, 23);
109 const bool singleAll = single && (bits(b, 3, 2) == 3);
110 const bool load = bits(machInst, 21);
111
112 unsigned width = 0;
113
114 if (single) {
115 width = bits(b, 1, 0) + 1;
116 } else {
117 switch (bits(b, 3, 1)) {
118 case 0x0: width = 4;
119 break;
120 case 0x1: width = (b & 0x1) ? 2 : 1;
121 break;
122 case 0x2: width = 3;
123 break;
124 case 0x3: width = 1;
125 break;
126 case 0x4: width = 2;
127 break;
128 case 0x5:
129 if ((b & 0x1) == 0) {
130 width = 1;
131 break;
132 }
133 // Fall through on purpose.
134 default:
135 return new Unknown(machInst);
136 }
137 }
138 assert(width > 0 && width <= 4);
139
140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
143 bits(machInst, 22) << 4);
144 const uint32_t type = bits(machInst, 11, 8);
145 uint32_t size = 0;
146 uint32_t align = TLB::MustBeOne;
147 unsigned inc = 1;
148 unsigned regs = 1;
149 unsigned lane = 0;
150 if (single) {
151 if (singleAll) {
152 size = bits(machInst, 7, 6);
153 bool t = bits(machInst, 5);
154 align = size | TLB::AllowUnaligned;
155 if (width == 1) {
156 regs = t ? 2 : 1;
157 inc = 1;
158 } else {
159 regs = width;
160 inc = t ? 2 : 1;
161 }
162 switch (width) {
163 case 1:
164 case 2:
165 if (bits(machInst, 4))
166 align = size + width - 1;
167 break;
168 case 3:
169 break;
170 case 4:
171 if (size == 3) {
172 if (bits(machInst, 4) == 0)
173 return new Unknown(machInst);
174 size = 2;
175 align = 0x4;
176 } else if (size == 2) {
177 if (bits(machInst, 4))
178 align = 0x3;
179 } else {
180 if (bits(machInst, 4))
181 align = size + 2;
182 }
183 break;
184 }
185 } else {
186 size = bits(machInst, 11, 10);
187 align = size | TLB::AllowUnaligned;
188 regs = width;
189 unsigned indexAlign = bits(machInst, 7, 4);
190 // If width is 1, inc is always 1. That's overridden later.
191 switch (size) {
192 case 0:
193 inc = 1;
194 lane = bits(indexAlign, 3, 1);
195 break;
196 case 1:
197 inc = bits(indexAlign, 1) ? 2 : 1;
198 lane = bits(indexAlign, 3, 2);
199 break;
200 case 2:
201 inc = bits(indexAlign, 2) ? 2 : 1;
202 lane = bits(indexAlign, 3);
203 break;
204 }
205 // Override inc for width of 1.
206 if (width == 1) {
207 inc = 1;
208 }
209 switch (width) {
210 case 1:
211 switch (size) {
212 case 0:
213 break;
214 case 1:
215 if (bits(indexAlign, 0))
216 align = 1;
217 break;
218 case 2:
219 if (bits(indexAlign, 1, 0))
220 align = 2;
221 break;
222 }
223 break;
224 case 2:
225 if (bits(indexAlign, 0))
226 align = size + 1;
227 break;
228 case 3:
229 break;
230 case 4:
231 switch (size) {
232 case 0:
233 case 1:
234 if (bits(indexAlign, 0))
235 align = size + 2;
236 break;
237 case 2:
238 if (bits(indexAlign, 0))
239 align = bits(indexAlign, 1, 0) + 2;
240 break;
241 }
242 break;
243 }
244 }
245 if (size == 0x3) {
246 return new Unknown(machInst);
247 }
248 } else {
249 size = bits(machInst, 7, 6);
250 align = bits(machInst, 5, 4);
251 if (align == 0) {
252 // @align wasn't specified, so alignment can be turned off.
253 align = size | TLB::AllowUnaligned;
254 } else {
255 align = align + 2;
256 }
257 switch (width) {
258 case 1:
259 switch (type) {
260 case 0x7: regs = 1;
261 break;
262 case 0xa: regs = 2;
263 break;
264 case 0x6: regs = 3;
265 break;
266 case 0x2: regs = 4;
267 break;
268 default:
269 return new Unknown(machInst);
270 }
271 break;
272 case 2:
273 // Regs doesn't behave exactly as it does in the manual
274 // because they loop over regs registers twice and we break
275 // it down in the macroop.
276 switch (type) {
277 case 0x8: regs = 2; inc = 1;
278 break;
279 case 0x9: regs = 2; inc = 2;
280 break;
281 case 0x3: regs = 4; inc = 2;
282 break;
283 default:
284 return new Unknown(machInst);
285 }
286 break;
287 case 3:
288 regs = 3;
289 switch (type) {
290 case 0x4: inc = 1;
291 break;
292 case 0x5: inc = 2;;
293 break;
294 default:
295 return new Unknown(machInst);
296 }
297 break;
298 case 4:
299 regs = 4;
300 switch (type) {
301 case 0: inc = 1;
302 break;
303 case 1: inc = 2;
304 break;
305 default:
306 return new Unknown(machInst);
307 }
308 break;
309 }
310 }
311
312 if (load) {
313 // Load instructions.
314 if (single) {
315 return new VldSingle(machInst, singleAll, width, rn, vd,
316 regs, inc, size, align, rm, lane);
317 } else {
318 return new VldMult(machInst, width, rn, vd,
319 regs, inc, size, align, rm);
320 }
321 } else {
322 // Store instructions.
323 if (single) {
324 if (singleAll) {
325 return new Unknown(machInst);
326 } else {
327 return new VstSingle(machInst, false, width, rn, vd,
328 regs, inc, size, align, rm, lane);
329 }
330 } else {
331 return new VstMult(machInst, width, rn, vd,
332 regs, inc, size, align, rm);
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338
339 decoder_output += '''
340 static StaticInstPtr
341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
342 {
343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
344 const uint32_t a = bits(machInst, 11, 8);
345 const bool b = bits(machInst, 4);
346 const uint32_t c = bits(machInst, 21, 20);
347 const IntRegIndex vd =
348 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
349 (bits(machInst, 22) << 4)));
350 const IntRegIndex vn =
351 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
352 (bits(machInst, 7) << 4)));
353 const IntRegIndex vm =
354 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
355 (bits(machInst, 5) << 4)));
356 const unsigned size = bits(machInst, 21, 20);
357 const bool q = bits(machInst, 6);
358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
359 return new Unknown(machInst);
360 switch (a) {
361 case 0x0:
362 if (b) {
363 if (u) {
364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
365 q, size, machInst, vd, vn, vm);
366 } else {
367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
368 q, size, machInst, vd, vn, vm);
369 }
370 } else {
371 if (size == 3)
372 return new Unknown(machInst);
373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
374 q, u, size, machInst, vd, vn, vm);
375 }
376 case 0x1:
377 if (!b) {
378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
379 q, u, size, machInst, vd, vn, vm);
380 } else {
381 if (u) {
382 switch (c) {
383 case 0:
384 if (q) {
385 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
386 } else {
387 return new VeorD<uint64_t>(machInst, vd, vn, vm);
388 }
389 case 1:
390 if (q) {
391 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
392 } else {
393 return new VbslD<uint64_t>(machInst, vd, vn, vm);
394 }
395 case 2:
396 if (q) {
397 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
398 } else {
399 return new VbitD<uint64_t>(machInst, vd, vn, vm);
400 }
401 case 3:
402 if (q) {
403 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
404 } else {
405 return new VbifD<uint64_t>(machInst, vd, vn, vm);
406 }
407 }
408 } else {
409 switch (c) {
410 case 0:
411 if (q) {
412 return new VandQ<uint64_t>(machInst, vd, vn, vm);
413 } else {
414 return new VandD<uint64_t>(machInst, vd, vn, vm);
415 }
416 case 1:
417 if (q) {
418 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
419 } else {
420 return new VbicD<uint64_t>(machInst, vd, vn, vm);
421 }
422 case 2:
423 if (vn == vm) {
424 if (q) {
425 return new VmovQ<uint64_t>(
426 machInst, vd, vn, vm);
427 } else {
428 return new VmovD<uint64_t>(
429 machInst, vd, vn, vm);
430 }
431 } else {
432 if (q) {
433 return new VorrQ<uint64_t>(
434 machInst, vd, vn, vm);
435 } else {
436 return new VorrD<uint64_t>(
437 machInst, vd, vn, vm);
438 }
439 }
440 case 3:
441 if (q) {
442 return new VornQ<uint64_t>(
443 machInst, vd, vn, vm);
444 } else {
445 return new VornD<uint64_t>(
446 machInst, vd, vn, vm);
447 }
448 }
449 }
450 }
451 case 0x2:
452 if (b) {
453 if (u) {
454 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
455 q, size, machInst, vd, vn, vm);
456 } else {
457 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
458 q, size, machInst, vd, vn, vm);
459 }
460 } else {
461 if (size == 3)
462 return new Unknown(machInst);
463 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
464 q, u, size, machInst, vd, vn, vm);
465 }
466 case 0x3:
467 if (b) {
468 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
469 q, u, size, machInst, vd, vn, vm);
470 } else {
471 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
472 q, u, size, machInst, vd, vn, vm);
473 }
474 case 0x4:
475 if (b) {
476 if (u) {
477 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
478 q, size, machInst, vd, vm, vn);
479 } else {
480 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
481 q, size, machInst, vd, vm, vn);
482 }
483 } else {
484 return decodeNeonUSThreeReg<VshlD, VshlQ>(
485 q, u, size, machInst, vd, vm, vn);
486 }
487 case 0x5:
488 if (b) {
489 if (u) {
490 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
491 q, size, machInst, vd, vm, vn);
492 } else {
493 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
494 q, size, machInst, vd, vm, vn);
495 }
496 } else {
497 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
498 q, u, size, machInst, vd, vm, vn);
499 }
500 case 0x6:
501 if (b) {
502 return decodeNeonUSThreeReg<VminD, VminQ>(
503 q, u, size, machInst, vd, vn, vm);
504 } else {
505 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
506 q, u, size, machInst, vd, vn, vm);
507 }
508 case 0x7:
509 if (b) {
510 return decodeNeonUSThreeReg<VabaD, VabaQ>(
511 q, u, size, machInst, vd, vn, vm);
512 } else {
513 if (bits(machInst, 23) == 1) {
514 if (q) {
515 return new Unknown(machInst);
516 } else {
517 return decodeNeonUSThreeUSReg<Vabdl>(
518 u, size, machInst, vd, vn, vm);
519 }
520 } else {
521 return decodeNeonUSThreeReg<VabdD, VabdQ>(
522 q, u, size, machInst, vd, vn, vm);
523 }
524 }
525 case 0x8:
526 if (b) {
527 if (u) {
528 return decodeNeonUThreeReg<VceqD, VceqQ>(
529 q, size, machInst, vd, vn, vm);
530 } else {
531 return decodeNeonUThreeReg<VtstD, VtstQ>(
532 q, size, machInst, vd, vn, vm);
533 }
534 } else {
535 if (u) {
536 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
537 q, size, machInst, vd, vn, vm);
538 } else {
539 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
540 q, size, machInst, vd, vn, vm);
541 }
542 }
543 case 0x9:
544 if (b) {
545 if (u) {
546 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
547 q, size, machInst, vd, vn, vm);
548 } else {
549 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
550 q, size, machInst, vd, vn, vm);
551 }
552 } else {
553 if (u) {
554 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
555 q, u, size, machInst, vd, vn, vm);
556 } else {
557 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
558 q, u, size, machInst, vd, vn, vm);
559 }
560 }
561 case 0xa:
562 if (q)
563 return new Unknown(machInst);
564 if (b) {
565 return decodeNeonUSThreeUSReg<VpminD>(
566 u, size, machInst, vd, vn, vm);
567 } else {
568 return decodeNeonUSThreeUSReg<VpmaxD>(
569 u, size, machInst, vd, vn, vm);
570 }
571 case 0xb:
572 if (b) {
573 if (u || q) {
574 return new Unknown(machInst);
575 } else {
576 return decodeNeonUThreeUSReg<NVpaddD>(
577 size, machInst, vd, vn, vm);
578 }
579 } else {
580 if (u) {
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582 q, size, machInst, vd, vn, vm);
583 } else {
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585 q, size, machInst, vd, vn, vm);
586 }
587 }
588 case 0xc:
589 if (b) {
590 if (!u) {
591 if (bits(c, 1) == 0) {
592 if (q) {
593 return new NVfmaQFp<float>(machInst, vd, vn, vm);
594 } else {
595 return new NVfmaDFp<float>(machInst, vd, vn, vm);
596 }
597 } else {
598 if (q) {
599 return new NVfmsQFp<float>(machInst, vd, vn, vm);
600 } else {
601 return new NVfmsDFp<float>(machInst, vd, vn, vm);
602 }
603 }
604 }
605 }
606 return new Unknown(machInst);
607 case 0xd:
608 if (b) {
609 if (u) {
610 if (bits(c, 1) == 0) {
611 if (q) {
612 return new NVmulQFp<float>(machInst, vd, vn, vm);
613 } else {
614 return new NVmulDFp<float>(machInst, vd, vn, vm);
615 }
616 } else {
617 return new Unknown(machInst);
618 }
619 } else {
620 if (bits(c, 1) == 0) {
621 if (q) {
622 return new NVmlaQFp<float>(machInst, vd, vn, vm);
623 } else {
624 return new NVmlaDFp<float>(machInst, vd, vn, vm);
625 }
626 } else {
627 if (q) {
628 return new NVmlsQFp<float>(machInst, vd, vn, vm);
629 } else {
630 return new NVmlsDFp<float>(machInst, vd, vn, vm);
631 }
632 }
633 }
634 } else {
635 if (u) {
636 if (bits(c, 1) == 0) {
637 if (q) {
638 return new VpaddQFp<float>(machInst, vd, vn, vm);
639 } else {
640 return new VpaddDFp<float>(machInst, vd, vn, vm);
641 }
642 } else {
643 if (q) {
644 return new VabdQFp<float>(machInst, vd, vn, vm);
645 } else {
646 return new VabdDFp<float>(machInst, vd, vn, vm);
647 }
648 }
649 } else {
650 if (bits(c, 1) == 0) {
651 if (q) {
652 return new VaddQFp<float>(machInst, vd, vn, vm);
653 } else {
654 return new VaddDFp<float>(machInst, vd, vn, vm);
655 }
656 } else {
657 if (q) {
658 return new VsubQFp<float>(machInst, vd, vn, vm);
659 } else {
660 return new VsubDFp<float>(machInst, vd, vn, vm);
661 }
662 }
663 }
664 }
665 case 0xe:
666 if (b) {
667 if (u) {
668 if (bits(c, 1) == 0) {
669 if (q) {
670 return new VacgeQFp<float>(machInst, vd, vn, vm);
671 } else {
672 return new VacgeDFp<float>(machInst, vd, vn, vm);
673 }
674 } else {
675 if (q) {
676 return new VacgtQFp<float>(machInst, vd, vn, vm);
677 } else {
678 return new VacgtDFp<float>(machInst, vd, vn, vm);
679 }
680 }
681 } else {
682 return new Unknown(machInst);
683 }
684 } else {
685 if (u) {
686 if (bits(c, 1) == 0) {
687 if (q) {
688 return new VcgeQFp<float>(machInst, vd, vn, vm);
689 } else {
690 return new VcgeDFp<float>(machInst, vd, vn, vm);
691 }
692 } else {
693 if (q) {
694 return new VcgtQFp<float>(machInst, vd, vn, vm);
695 } else {
696 return new VcgtDFp<float>(machInst, vd, vn, vm);
697 }
698 }
699 } else {
700 if (bits(c, 1) == 0) {
701 if (q) {
702 return new VceqQFp<float>(machInst, vd, vn, vm);
703 } else {
704 return new VceqDFp<float>(machInst, vd, vn, vm);
705 }
706 } else {
707 return new Unknown(machInst);
708 }
709 }
710 }
711 case 0xf:
712 if (b) {
713 if (u) {
714 return new Unknown(machInst);
715 } else {
716 if (bits(c, 1) == 0) {
717 if (q) {
718 return new VrecpsQFp<float>(machInst, vd, vn, vm);
719 } else {
720 return new VrecpsDFp<float>(machInst, vd, vn, vm);
721 }
722 } else {
723 if (q) {
724 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
725 } else {
726 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
727 }
728 }
729 }
730 } else {
731 if (u) {
732 if (bits(c, 1) == 0) {
733 if (q) {
734 return new VpmaxQFp<float>(machInst, vd, vn, vm);
735 } else {
736 return new VpmaxDFp<float>(machInst, vd, vn, vm);
737 }
738 } else {
739 if (q) {
740 return new VpminQFp<float>(machInst, vd, vn, vm);
741 } else {
742 return new VpminDFp<float>(machInst, vd, vn, vm);
743 }
744 }
745 } else {
746 if (bits(c, 1) == 0) {
747 if (q) {
748 return new VmaxQFp<float>(machInst, vd, vn, vm);
749 } else {
750 return new VmaxDFp<float>(machInst, vd, vn, vm);
751 }
752 } else {
753 if (q) {
754 return new VminQFp<float>(machInst, vd, vn, vm);
755 } else {
756 return new VminDFp<float>(machInst, vd, vn, vm);
757 }
758 }
759 }
760 }
761 }
762 return new Unknown(machInst);
763 }
764
765 static StaticInstPtr
766 decodeNeonOneRegModImm(ExtMachInst machInst)
767 {
768 const IntRegIndex vd =
769 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
770 (bits(machInst, 22) << 4)));
771 const bool q = bits(machInst, 6);
772 const bool op = bits(machInst, 5);
773 const uint8_t cmode = bits(machInst, 11, 8);
774 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
775 bits(machInst, 24)) << 7) |
776 (bits(machInst, 18, 16) << 4) |
777 (bits(machInst, 3, 0) << 0);
778
779 // Check for invalid immediate encodings and return an unknown op
780 // if it happens
781 bool immValid = true;
782 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
783 if (!immValid) {
784 return new Unknown(machInst);
785 }
786
787 if (op) {
788 if (bits(cmode, 3) == 0) {
789 if (bits(cmode, 0) == 0) {
790 if (q)
791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
792 else
793 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794 } else {
795 if (q)
796 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
797 else
798 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
799 }
800 } else {
801 if (bits(cmode, 2) == 1) {
802 switch (bits(cmode, 1, 0)) {
803 case 0:
804 case 1:
805 if (q)
806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
807 else
808 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
809 case 2:
810 if (q)
811 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
812 else
813 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
814 case 3:
815 if (q)
816 return new Unknown(machInst);
817 else
818 return new Unknown(machInst);
819 }
820 } else {
821 if (bits(cmode, 0) == 0) {
822 if (q)
823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
824 else
825 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
826 } else {
827 if (q)
828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
829 else
830 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
831 }
832 }
833 }
834 } else {
835 if (bits(cmode, 3) == 0) {
836 if (bits(cmode, 0) == 0) {
837 if (q)
838 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
839 else
840 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
841 } else {
842 if (q)
843 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
844 else
845 return new NVorriD<uint64_t>(machInst, vd, bigImm);
846 }
847 } else {
848 if (bits(cmode, 2) == 1) {
849 if (q)
850 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
851 else
852 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
853 } else {
854 if (bits(cmode, 0) == 0) {
855 if (q)
856 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
857 else
858 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
859 } else {
860 if (q)
861 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
862 else
863 return new NVorriD<uint64_t>(machInst, vd, bigImm);
864 }
865 }
866 }
867 }
868 return new Unknown(machInst);
869 }
870
871 static StaticInstPtr
872 decodeNeonTwoRegAndShift(ExtMachInst machInst)
873 {
874 const uint32_t a = bits(machInst, 11, 8);
875 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
876 const bool b = bits(machInst, 6);
877 const bool l = bits(machInst, 7);
878 const IntRegIndex vd =
879 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
880 (bits(machInst, 22) << 4)));
881 const IntRegIndex vm =
882 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
883 (bits(machInst, 5) << 4)));
884 unsigned imm6 = bits(machInst, 21, 16);
885 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
886 unsigned size = 3;
887 unsigned lShiftAmt = 0;
888 unsigned bitSel;
889 for (bitSel = 1 << 6; true; bitSel >>= 1) {
890 if (bitSel & imm)
891 break;
892 else if (!size)
893 return new Unknown(machInst);
894 size--;
895 }
896 lShiftAmt = imm6 & ~bitSel;
897 unsigned rShiftAmt = 0;
898 if (a != 0xe && a != 0xf) {
899 if (size > 2)
900 rShiftAmt = 64 - imm6;
901 else
902 rShiftAmt = 2 * (8 << size) - imm6;
903 }
904
905 switch (a) {
906 case 0x0:
907 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
908 b, u, size, machInst, vd, vm, rShiftAmt);
909 case 0x1:
910 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
911 b, u, size, machInst, vd, vm, rShiftAmt);
912 case 0x2:
913 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
914 b, u, size, machInst, vd, vm, rShiftAmt);
915 case 0x3:
916 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
917 b, u, size, machInst, vd, vm, rShiftAmt);
918 case 0x4:
919 if (u) {
920 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
921 b, size, machInst, vd, vm, rShiftAmt);
922 } else {
923 return new Unknown(machInst);
924 }
925 case 0x5:
926 if (u) {
927 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
928 b, size, machInst, vd, vm, lShiftAmt);
929 } else {
930 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
931 b, size, machInst, vd, vm, lShiftAmt);
932 }
933 case 0x6:
934 case 0x7:
935 if (u) {
936 if (a == 0x6) {
937 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
938 b, size, machInst, vd, vm, lShiftAmt);
939 } else {
940 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
941 b, size, machInst, vd, vm, lShiftAmt);
942 }
943 } else {
944 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
945 b, size, machInst, vd, vm, lShiftAmt);
946 }
947 case 0x8:
948 if (l) {
949 return new Unknown(machInst);
950 } else if (u) {
951 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
952 b, size, machInst, vd, vm, rShiftAmt);
953 } else {
954 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
955 b, size, machInst, vd, vm, rShiftAmt);
956 }
957 case 0x9:
958 if (l) {
959 return new Unknown(machInst);
960 } else if (u) {
961 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
962 b, size, machInst, vd, vm, rShiftAmt);
963 } else {
964 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
965 b, size, machInst, vd, vm, rShiftAmt);
966 }
967 case 0xa:
968 if (l || b) {
969 return new Unknown(machInst);
970 } else {
971 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
972 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
973 }
974 case 0xe:
975 if (l) {
976 return new Unknown(machInst);
977 } else {
978 if (bits(imm6, 5) == 0)
979 return new Unknown(machInst);
980 if (u) {
981 if (b) {
982 return new NVcvtu2fpQ<float>(
983 machInst, vd, vm, 64 - imm6);
984 } else {
985 return new NVcvtu2fpD<float>(
986 machInst, vd, vm, 64 - imm6);
987 }
988 } else {
989 if (b) {
990 return new NVcvts2fpQ<float>(
991 machInst, vd, vm, 64 - imm6);
992 } else {
993 return new NVcvts2fpD<float>(
994 machInst, vd, vm, 64 - imm6);
995 }
996 }
997 }
998 case 0xf:
999 if (l) {
1000 return new Unknown(machInst);
1001 } else {
1002 if (bits(imm6, 5) == 0)
1003 return new Unknown(machInst);
1004 if (u) {
1005 if (b) {
1006 return new NVcvt2ufxQ<float>(
1007 machInst, vd, vm, 64 - imm6);
1008 } else {
1009 return new NVcvt2ufxD<float>(
1010 machInst, vd, vm, 64 - imm6);
1011 }
1012 } else {
1013 if (b) {
1014 return new NVcvt2sfxQ<float>(
1015 machInst, vd, vm, 64 - imm6);
1016 } else {
1017 return new NVcvt2sfxD<float>(
1018 machInst, vd, vm, 64 - imm6);
1019 }
1020 }
1021 }
1022 }
1023 return new Unknown(machInst);
1024 }
1025
1026 static StaticInstPtr
1027 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1028 {
1029 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1030 const uint32_t a = bits(machInst, 11, 8);
1031 const IntRegIndex vd =
1032 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1033 (bits(machInst, 22) << 4)));
1034 const IntRegIndex vn =
1035 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1036 (bits(machInst, 7) << 4)));
1037 const IntRegIndex vm =
1038 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1039 (bits(machInst, 5) << 4)));
1040 const unsigned size = bits(machInst, 21, 20);
1041 switch (a) {
1042 case 0x0:
1043 return decodeNeonUSThreeUSReg<Vaddl>(
1044 u, size, machInst, vd, vn, vm);
1045 case 0x1:
1046 return decodeNeonUSThreeUSReg<Vaddw>(
1047 u, size, machInst, vd, vn, vm);
1048 case 0x2:
1049 return decodeNeonUSThreeUSReg<Vsubl>(
1050 u, size, machInst, vd, vn, vm);
1051 case 0x3:
1052 return decodeNeonUSThreeUSReg<Vsubw>(
1053 u, size, machInst, vd, vn, vm);
1054 case 0x4:
1055 if (u) {
1056 return decodeNeonUThreeUSReg<Vraddhn>(
1057 size, machInst, vd, vn, vm);
1058 } else {
1059 return decodeNeonUThreeUSReg<Vaddhn>(
1060 size, machInst, vd, vn, vm);
1061 }
1062 case 0x5:
1063 return decodeNeonUSThreeUSReg<Vabal>(
1064 u, size, machInst, vd, vn, vm);
1065 case 0x6:
1066 if (u) {
1067 return decodeNeonUThreeUSReg<Vrsubhn>(
1068 size, machInst, vd, vn, vm);
1069 } else {
1070 return decodeNeonUThreeUSReg<Vsubhn>(
1071 size, machInst, vd, vn, vm);
1072 }
1073 case 0x7:
1074 if (bits(machInst, 23)) {
1075 return decodeNeonUSThreeUSReg<Vabdl>(
1076 u, size, machInst, vd, vn, vm);
1077 } else {
1078 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1079 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1080 }
1081 case 0x8:
1082 return decodeNeonUSThreeUSReg<Vmlal>(
1083 u, size, machInst, vd, vn, vm);
1084 case 0xa:
1085 return decodeNeonUSThreeUSReg<Vmlsl>(
1086 u, size, machInst, vd, vn, vm);
1087 case 0x9:
1088 if (u) {
1089 return new Unknown(machInst);
1090 } else {
1091 return decodeNeonSThreeUSReg<Vqdmlal>(
1092 size, machInst, vd, vn, vm);
1093 }
1094 case 0xb:
1095 if (u) {
1096 return new Unknown(machInst);
1097 } else {
1098 return decodeNeonSThreeUSReg<Vqdmlsl>(
1099 size, machInst, vd, vn, vm);
1100 }
1101 case 0xc:
1102 return decodeNeonUSThreeUSReg<Vmull>(
1103 u, size, machInst, vd, vn, vm);
1104 case 0xd:
1105 if (u) {
1106 return new Unknown(machInst);
1107 } else {
1108 return decodeNeonSThreeUSReg<Vqdmull>(
1109 size, machInst, vd, vn, vm);
1110 }
1111 case 0xe:
1112 return decodeNeonUThreeUSReg<Vmullp>(
1113 size, machInst, vd, vn, vm);
1114 }
1115 return new Unknown(machInst);
1116 }
1117
1118 static StaticInstPtr
1119 decodeNeonTwoRegScalar(ExtMachInst machInst)
1120 {
1121 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1122 const uint32_t a = bits(machInst, 11, 8);
1123 const unsigned size = bits(machInst, 21, 20);
1124 const IntRegIndex vd =
1125 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1126 (bits(machInst, 22) << 4)));
1127 const IntRegIndex vn =
1128 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1129 (bits(machInst, 7) << 4)));
1130 const IntRegIndex vm = (size == 2) ?
1131 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1132 (IntRegIndex)(2 * bits(machInst, 2, 0));
1133 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1134 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1135 switch (a) {
1136 case 0x0:
1137 if (u) {
1138 switch (size) {
1139 case 1:
1140 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1141 case 2:
1142 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1143 default:
1144 return new Unknown(machInst);
1145 }
1146 } else {
1147 switch (size) {
1148 case 1:
1149 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1150 case 2:
1151 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1152 default:
1153 return new Unknown(machInst);
1154 }
1155 }
1156 case 0x1:
1157 if (u)
1158 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1159 else
1160 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1161 case 0x4:
1162 if (u) {
1163 switch (size) {
1164 case 1:
1165 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1166 case 2:
1167 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1168 default:
1169 return new Unknown(machInst);
1170 }
1171 } else {
1172 switch (size) {
1173 case 1:
1174 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1175 case 2:
1176 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1177 default:
1178 return new Unknown(machInst);
1179 }
1180 }
1181 case 0x5:
1182 if (u)
1183 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1184 else
1185 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1186 case 0x2:
1187 if (u) {
1188 switch (size) {
1189 case 1:
1190 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1191 case 2:
1192 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1193 default:
1194 return new Unknown(machInst);
1195 }
1196 } else {
1197 switch (size) {
1198 case 1:
1199 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1200 case 2:
1201 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1202 default:
1203 return new Unknown(machInst);
1204 }
1205 }
1206 case 0x6:
1207 if (u) {
1208 switch (size) {
1209 case 1:
1210 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1211 case 2:
1212 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1213 default:
1214 return new Unknown(machInst);
1215 }
1216 } else {
1217 switch (size) {
1218 case 1:
1219 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1220 case 2:
1221 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1222 default:
1223 return new Unknown(machInst);
1224 }
1225 }
1226 case 0x3:
1227 if (u) {
1228 return new Unknown(machInst);
1229 } else {
1230 switch (size) {
1231 case 1:
1232 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1233 case 2:
1234 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1235 default:
1236 return new Unknown(machInst);
1237 }
1238 }
1239 case 0x7:
1240 if (u) {
1241 return new Unknown(machInst);
1242 } else {
1243 switch (size) {
1244 case 1:
1245 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1246 case 2:
1247 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1248 default:
1249 return new Unknown(machInst);
1250 }
1251 }
1252 case 0x8:
1253 if (u) {
1254 switch (size) {
1255 case 1:
1256 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1257 case 2:
1258 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1259 default:
1260 return new Unknown(machInst);
1261 }
1262 } else {
1263 switch (size) {
1264 case 1:
1265 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1266 case 2:
1267 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1268 default:
1269 return new Unknown(machInst);
1270 }
1271 }
1272 case 0x9:
1273 if (u)
1274 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1275 else
1276 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1277 case 0xa:
1278 if (u) {
1279 switch (size) {
1280 case 1:
1281 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1282 case 2:
1283 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1284 default:
1285 return new Unknown(machInst);
1286 }
1287 } else {
1288 switch (size) {
1289 case 1:
1290 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1291 case 2:
1292 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1293 default:
1294 return new Unknown(machInst);
1295 }
1296 }
1297 case 0xb:
1298 if (u) {
1299 return new Unknown(machInst);
1300 } else {
1301 if (u) {
1302 switch (size) {
1303 case 1:
1304 return new Vqdmulls<uint16_t>(
1305 machInst, vd, vn, vm, index);
1306 case 2:
1307 return new Vqdmulls<uint32_t>(
1308 machInst, vd, vn, vm, index);
1309 default:
1310 return new Unknown(machInst);
1311 }
1312 } else {
1313 switch (size) {
1314 case 1:
1315 return new Vqdmulls<int16_t>(
1316 machInst, vd, vn, vm, index);
1317 case 2:
1318 return new Vqdmulls<int32_t>(
1319 machInst, vd, vn, vm, index);
1320 default:
1321 return new Unknown(machInst);
1322 }
1323 }
1324 }
1325 case 0xc:
1326 if (u) {
1327 switch (size) {
1328 case 1:
1329 return new VqdmulhsQ<int16_t>(
1330 machInst, vd, vn, vm, index);
1331 case 2:
1332 return new VqdmulhsQ<int32_t>(
1333 machInst, vd, vn, vm, index);
1334 default:
1335 return new Unknown(machInst);
1336 }
1337 } else {
1338 switch (size) {
1339 case 1:
1340 return new VqdmulhsD<int16_t>(
1341 machInst, vd, vn, vm, index);
1342 case 2:
1343 return new VqdmulhsD<int32_t>(
1344 machInst, vd, vn, vm, index);
1345 default:
1346 return new Unknown(machInst);
1347 }
1348 }
1349 case 0xd:
1350 if (u) {
1351 switch (size) {
1352 case 1:
1353 return new VqrdmulhsQ<int16_t>(
1354 machInst, vd, vn, vm, index);
1355 case 2:
1356 return new VqrdmulhsQ<int32_t>(
1357 machInst, vd, vn, vm, index);
1358 default:
1359 return new Unknown(machInst);
1360 }
1361 } else {
1362 switch (size) {
1363 case 1:
1364 return new VqrdmulhsD<int16_t>(
1365 machInst, vd, vn, vm, index);
1366 case 2:
1367 return new VqrdmulhsD<int32_t>(
1368 machInst, vd, vn, vm, index);
1369 default:
1370 return new Unknown(machInst);
1371 }
1372 }
1373 }
1374 return new Unknown(machInst);
1375 }
1376
1377 static StaticInstPtr
1378 decodeNeonTwoRegMisc(ExtMachInst machInst)
1379 {
1380 const uint32_t a = bits(machInst, 17, 16);
1381 const uint32_t b = bits(machInst, 10, 6);
1382 const bool q = bits(machInst, 6);
1383 const IntRegIndex vd =
1384 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1385 (bits(machInst, 22) << 4)));
1386 const IntRegIndex vm =
1387 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1388 (bits(machInst, 5) << 4)));
1389 const unsigned size = bits(machInst, 19, 18);
1390 switch (a) {
1391 case 0x0:
1392 switch (bits(b, 4, 1)) {
1393 case 0x0:
1394 switch (size) {
1395 case 0:
1396 if (q) {
1397 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1398 } else {
1399 return new NVrev64D<uint8_t>(machInst, vd, vm);
1400 }
1401 case 1:
1402 if (q) {
1403 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1404 } else {
1405 return new NVrev64D<uint16_t>(machInst, vd, vm);
1406 }
1407 case 2:
1408 if (q) {
1409 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1410 } else {
1411 return new NVrev64D<uint32_t>(machInst, vd, vm);
1412 }
1413 default:
1414 return new Unknown(machInst);
1415 }
1416 case 0x1:
1417 switch (size) {
1418 case 0:
1419 if (q) {
1420 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1421 } else {
1422 return new NVrev32D<uint8_t>(machInst, vd, vm);
1423 }
1424 case 1:
1425 if (q) {
1426 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1427 } else {
1428 return new NVrev32D<uint16_t>(machInst, vd, vm);
1429 }
1430 default:
1431 return new Unknown(machInst);
1432 }
1433 case 0x2:
1434 if (size != 0) {
1435 return new Unknown(machInst);
1436 } else if (q) {
1437 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1438 } else {
1439 return new NVrev16D<uint8_t>(machInst, vd, vm);
1440 }
1441 case 0x4:
1442 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1443 q, size, machInst, vd, vm);
1444 case 0x5:
1445 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1446 q, size, machInst, vd, vm);
1447 case 0x8:
1448 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1449 q, size, machInst, vd, vm);
1450 case 0x9:
1451 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1452 q, size, machInst, vd, vm);
1453 case 0xa:
1454 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1455 q, size, machInst, vd, vm);
1456 case 0xb:
1457 if (q)
1458 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1459 else
1460 return new NVmvnD<uint64_t>(machInst, vd, vm);
1461 case 0xc:
1462 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1463 q, size, machInst, vd, vm);
1464 case 0xd:
1465 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1466 q, size, machInst, vd, vm);
1467 case 0xe:
1468 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1469 q, size, machInst, vd, vm);
1470 case 0xf:
1471 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1472 q, size, machInst, vd, vm);
1473 default:
1474 return new Unknown(machInst);
1475 }
1476 case 0x1:
1477 switch (bits(b, 3, 1)) {
1478 case 0x0:
1479 if (bits(b, 4)) {
1480 if (q) {
1481 return new NVcgtQFp<float>(machInst, vd, vm);
1482 } else {
1483 return new NVcgtDFp<float>(machInst, vd, vm);
1484 }
1485 } else {
1486 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1487 q, size, machInst, vd, vm);
1488 }
1489 case 0x1:
1490 if (bits(b, 4)) {
1491 if (q) {
1492 return new NVcgeQFp<float>(machInst, vd, vm);
1493 } else {
1494 return new NVcgeDFp<float>(machInst, vd, vm);
1495 }
1496 } else {
1497 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1498 q, size, machInst, vd, vm);
1499 }
1500 case 0x2:
1501 if (bits(b, 4)) {
1502 if (q) {
1503 return new NVceqQFp<float>(machInst, vd, vm);
1504 } else {
1505 return new NVceqDFp<float>(machInst, vd, vm);
1506 }
1507 } else {
1508 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1509 q, size, machInst, vd, vm);
1510 }
1511 case 0x3:
1512 if (bits(b, 4)) {
1513 if (q) {
1514 return new NVcleQFp<float>(machInst, vd, vm);
1515 } else {
1516 return new NVcleDFp<float>(machInst, vd, vm);
1517 }
1518 } else {
1519 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1520 q, size, machInst, vd, vm);
1521 }
1522 case 0x4:
1523 if (bits(b, 4)) {
1524 if (q) {
1525 return new NVcltQFp<float>(machInst, vd, vm);
1526 } else {
1527 return new NVcltDFp<float>(machInst, vd, vm);
1528 }
1529 } else {
1530 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1531 q, size, machInst, vd, vm);
1532 }
1533 case 0x6:
1534 if (bits(machInst, 10)) {
1535 if (q)
1536 return new NVabsQFp<float>(machInst, vd, vm);
1537 else
1538 return new NVabsDFp<float>(machInst, vd, vm);
1539 } else {
1540 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1541 q, size, machInst, vd, vm);
1542 }
1543 case 0x7:
1544 if (bits(machInst, 10)) {
1545 if (q)
1546 return new NVnegQFp<float>(machInst, vd, vm);
1547 else
1548 return new NVnegDFp<float>(machInst, vd, vm);
1549 } else {
1550 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1551 q, size, machInst, vd, vm);
1552 }
1553 }
1554 case 0x2:
1555 switch (bits(b, 4, 1)) {
1556 case 0x0:
1557 if (q)
1558 return new NVswpQ<uint64_t>(machInst, vd, vm);
1559 else
1560 return new NVswpD<uint64_t>(machInst, vd, vm);
1561 case 0x1:
1562 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1563 q, size, machInst, vd, vm);
1564 case 0x2:
1565 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1566 q, size, machInst, vd, vm);
1567 case 0x3:
1568 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1569 q, size, machInst, vd, vm);
1570 case 0x4:
1571 if (b == 0x8) {
1572 return decodeNeonUTwoMiscUSReg<NVmovn>(
1573 size, machInst, vd, vm);
1574 } else {
1575 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1576 size, machInst, vd, vm);
1577 }
1578 case 0x5:
1579 if (q) {
1580 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1581 size, machInst, vd, vm);
1582 } else {
1583 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1584 size, machInst, vd, vm);
1585 }
1586 case 0x6:
1587 if (b == 0xc) {
1588 return decodeNeonSTwoShiftUSReg<NVshll>(
1589 size, machInst, vd, vm, 8 << size);
1590 } else {
1591 return new Unknown(machInst);
1592 }
1593 case 0xc:
1594 case 0xe:
1595 if (b == 0x18) {
1596 if (size != 1 || (vm % 2))
1597 return new Unknown(machInst);
1598 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1599 } else if (b == 0x1c) {
1600 if (size != 1 || (vd % 2))
1601 return new Unknown(machInst);
1602 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1603 } else {
1604 return new Unknown(machInst);
1605 }
1606 default:
1607 return new Unknown(machInst);
1608 }
1609 case 0x3:
1610 if (bits(b, 4, 3) == 0x3) {
1611 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1612 return new Unknown(machInst);
1613 } else {
1614 if (bits(b, 2)) {
1615 if (bits(b, 1)) {
1616 if (q) {
1617 return new NVcvt2ufxQ<float>(
1618 machInst, vd, vm, 0);
1619 } else {
1620 return new NVcvt2ufxD<float>(
1621 machInst, vd, vm, 0);
1622 }
1623 } else {
1624 if (q) {
1625 return new NVcvt2sfxQ<float>(
1626 machInst, vd, vm, 0);
1627 } else {
1628 return new NVcvt2sfxD<float>(
1629 machInst, vd, vm, 0);
1630 }
1631 }
1632 } else {
1633 if (bits(b, 1)) {
1634 if (q) {
1635 return new NVcvtu2fpQ<float>(
1636 machInst, vd, vm, 0);
1637 } else {
1638 return new NVcvtu2fpD<float>(
1639 machInst, vd, vm, 0);
1640 }
1641 } else {
1642 if (q) {
1643 return new NVcvts2fpQ<float>(
1644 machInst, vd, vm, 0);
1645 } else {
1646 return new NVcvts2fpD<float>(
1647 machInst, vd, vm, 0);
1648 }
1649 }
1650 }
1651 }
1652 } else if ((b & 0x1a) == 0x10) {
1653 if (bits(b, 2)) {
1654 if (q) {
1655 return new NVrecpeQFp<float>(machInst, vd, vm);
1656 } else {
1657 return new NVrecpeDFp<float>(machInst, vd, vm);
1658 }
1659 } else {
1660 if (q) {
1661 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1662 } else {
1663 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1664 }
1665 }
1666 } else if ((b & 0x1a) == 0x12) {
1667 if (bits(b, 2)) {
1668 if (q) {
1669 return new NVrsqrteQFp<float>(machInst, vd, vm);
1670 } else {
1671 return new NVrsqrteDFp<float>(machInst, vd, vm);
1672 }
1673 } else {
1674 if (q) {
1675 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1676 } else {
1677 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1678 }
1679 }
1680 } else {
1681 return new Unknown(machInst);
1682 }
1683 }
1684 return new Unknown(machInst);
1685 }
1686
1687 StaticInstPtr
1688 decodeNeonData(ExtMachInst machInst)
1689 {
1690 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1691 const uint32_t a = bits(machInst, 23, 19);
1692 const uint32_t b = bits(machInst, 11, 8);
1693 const uint32_t c = bits(machInst, 7, 4);
1694 if (bits(a, 4) == 0) {
1695 return decodeNeonThreeRegistersSameLength(machInst);
1696 } else if ((c & 0x9) == 1) {
1697 if ((a & 0x7) == 0) {
1698 return decodeNeonOneRegModImm(machInst);
1699 } else {
1700 return decodeNeonTwoRegAndShift(machInst);
1701 }
1702 } else if ((c & 0x9) == 9) {
1703 return decodeNeonTwoRegAndShift(machInst);
1704 } else if (bits(a, 2, 1) != 0x3) {
1705 if ((c & 0x5) == 0) {
1706 return decodeNeonThreeRegDiffLengths(machInst);
1707 } else if ((c & 0x5) == 4) {
1708 return decodeNeonTwoRegScalar(machInst);
1709 }
1710 } else if ((a & 0x16) == 0x16) {
1711 const IntRegIndex vd =
1712 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1713 (bits(machInst, 22) << 4)));
1714 const IntRegIndex vn =
1715 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1716 (bits(machInst, 7) << 4)));
1717 const IntRegIndex vm =
1718 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1719 (bits(machInst, 5) << 4)));
1720 if (!u) {
1721 if (bits(c, 0) == 0) {
1722 unsigned imm4 = bits(machInst, 11, 8);
1723 bool q = bits(machInst, 6);
1724 if (imm4 >= 16 && !q)
1725 return new Unknown(machInst);
1726 if (q) {
1727 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1728 } else {
1729 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1730 }
1731 }
1732 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1733 return decodeNeonTwoRegMisc(machInst);
1734 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1735 unsigned length = bits(machInst, 9, 8) + 1;
1736 if ((uint32_t)vn / 2 + length > 32)
1737 return new Unknown(machInst);
1738 if (bits(machInst, 6) == 0) {
1739 switch (length) {
1740 case 1:
1741 return new NVtbl1(machInst, vd, vn, vm);
1742 case 2:
1743 return new NVtbl2(machInst, vd, vn, vm);
1744 case 3:
1745 return new NVtbl3(machInst, vd, vn, vm);
1746 case 4:
1747 return new NVtbl4(machInst, vd, vn, vm);
1748 }
1749 } else {
1750 switch (length) {
1751 case 1:
1752 return new NVtbx1(machInst, vd, vn, vm);
1753 case 2:
1754 return new NVtbx2(machInst, vd, vn, vm);
1755 case 3:
1756 return new NVtbx3(machInst, vd, vn, vm);
1757 case 4:
1758 return new NVtbx4(machInst, vd, vn, vm);
1759 }
1760 }
1761 } else if (b == 0xc && (c & 0x9) == 0) {
1762 unsigned imm4 = bits(machInst, 19, 16);
1763 if (bits(imm4, 2, 0) == 0)
1764 return new Unknown(machInst);
1765 unsigned size = 0;
1766 while ((imm4 & 0x1) == 0) {
1767 size++;
1768 imm4 >>= 1;
1769 }
1770 unsigned index = imm4 >> 1;
1771 const bool q = bits(machInst, 6);
1772 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1773 q, size, machInst, vd, vm, index);
1774 }
1775 }
1776 return new Unknown(machInst);
1777 }
1778 '''
1779}};
1780
1781def format ThumbNeonMem() {{
1782 decode_block = '''
1783 return decodeNeonMem(machInst);
1784 '''
1785}};
1786
1787def format ThumbNeonData() {{
1788 decode_block = '''
1789 return decodeNeonData(machInst);
1790 '''
1791}};
1792
1793let {{
1794 header_output = '''
1795 StaticInstPtr
1796 decodeExtensionRegLoadStore(ExtMachInst machInst);
1797 '''
1798 decoder_output = '''
1799 StaticInstPtr
1800 decodeExtensionRegLoadStore(ExtMachInst machInst)
1801 {
1802 const uint32_t opcode = bits(machInst, 24, 20);
1803 const uint32_t offset = bits(machInst, 7, 0);
1804 const bool single = (bits(machInst, 8) == 0);
1805 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1806 RegIndex vd;
1807 if (single) {
1808 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1809 bits(machInst, 22));
1810 } else {
1811 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1812 (bits(machInst, 22) << 5));
1813 }
1814 switch (bits(opcode, 4, 3)) {
1815 case 0x0:
1816 if (bits(opcode, 4, 1) == 0x2 &&
1817 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1818 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1819 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1820 break;
1821 }
1822 const IntRegIndex rt =
1823 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1824 const IntRegIndex rt2 =
1825 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1826 const bool op = bits(machInst, 20);
1827 uint32_t vm;
1828 if (single) {
1829 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1830 } else {
1831 vm = (bits(machInst, 3, 0) << 1) |
1832 (bits(machInst, 5) << 5);
1833 }
1834 if (op) {
1835 return new Vmov2Core2Reg(machInst, rt, rt2,
1836 (IntRegIndex)vm);
1837 } else {
1838 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1839 rt, rt2);
1840 }
1841 }
1842 break;
1843 case 0x1:
1844 {
1845 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1846 break;
1847 }
1848 switch (bits(opcode, 1, 0)) {
1849 case 0x0:
1850 return new VLdmStm(machInst, rn, vd, single,
1851 true, false, false, offset);
1852 case 0x1:
1853 return new VLdmStm(machInst, rn, vd, single,
1854 true, false, true, offset);
1855 case 0x2:
1856 return new VLdmStm(machInst, rn, vd, single,
1857 true, true, false, offset);
1858 case 0x3:
1859 // If rn == sp, then this is called vpop.
1860 return new VLdmStm(machInst, rn, vd, single,
1861 true, true, true, offset);
1862 }
1863 }
1864 case 0x2:
1865 if (bits(opcode, 1, 0) == 0x2) {
1866 // If rn == sp, then this is called vpush.
1867 return new VLdmStm(machInst, rn, vd, single,
1868 false, true, false, offset);
1869 } else if (bits(opcode, 1, 0) == 0x3) {
1870 return new VLdmStm(machInst, rn, vd, single,
1871 false, true, true, offset);
1872 }
1873 // Fall through on purpose
1874 case 0x3:
1875 const bool up = (bits(machInst, 23) == 1);
1876 const uint32_t imm = bits(machInst, 7, 0) << 2;
1877 if (single) {
1878 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1879 (bits(machInst, 22)));
1880 } else {
1881 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1882 (bits(machInst, 22) << 5));
1883 }
1884 if (bits(opcode, 1, 0) == 0x0) {
1885 if (single) {
1886 if (up) {
1887 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1888 } else {
1889 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1890 }
1891 } else {
1892 if (up) {
1893 return new %(vstr_ud)s(machInst, vd, vd + 1,
1894 rn, up, imm);
1895 } else {
1896 return new %(vstr_d)s(machInst, vd, vd + 1,
1897 rn, up, imm);
1898 }
1899 }
1900 } else if (bits(opcode, 1, 0) == 0x1) {
1901 if (single) {
1902 if (up) {
1903 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1904 } else {
1905 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1906 }
1907 } else {
1908 if (up) {
1909 return new %(vldr_ud)s(machInst, vd, vd + 1,
1910 rn, up, imm);
1911 } else {
1912 return new %(vldr_d)s(machInst, vd, vd + 1,
1913 rn, up, imm);
1914 }
1915 }
1916 }
1917 }
1918 return new Unknown(machInst);
1919 }
1920 ''' % {
1921 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1922 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1923 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1924 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1925 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1926 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1927 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1928 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1929 }
1930}};
1931
1932def format ExtensionRegLoadStore() {{
1933 decode_block = '''
1934 return decodeExtensionRegLoadStore(machInst);
1935 '''
1936}};
1937
1938let {{
1939 header_output = '''
1940 StaticInstPtr
1941 decodeShortFpTransfer(ExtMachInst machInst);
1942 '''
1943 decoder_output = '''
1944 StaticInstPtr
1945 decodeShortFpTransfer(ExtMachInst machInst)
1946 {
1947 const uint32_t l = bits(machInst, 20);
1948 const uint32_t c = bits(machInst, 8);
1949 const uint32_t a = bits(machInst, 23, 21);
1950 const uint32_t b = bits(machInst, 6, 5);
1951 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1952 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48output header {{
49
50 template<template <typename T> class Base>
51 StaticInstPtr
52 newNeonMemInst(const unsigned size,
53 const ExtMachInst &machInst,
54 const RegIndex dest, const RegIndex ra,
55 const uint32_t imm, const unsigned extraMemFlags)
56 {
57 switch (size) {
58 case 0:
59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
60 case 1:
61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
62 case 2:
63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
64 case 3:
65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
66 default:
67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
68 }
69 }
70
71 template<template <typename T> class Base>
72 StaticInstPtr
73 newNeonMixInst(const unsigned size,
74 const ExtMachInst &machInst,
75 const RegIndex dest, const RegIndex op1,
76 const uint32_t step)
77 {
78 switch (size) {
79 case 0:
80 return new Base<uint8_t>(machInst, dest, op1, step);
81 case 1:
82 return new Base<uint16_t>(machInst, dest, op1, step);
83 case 2:
84 return new Base<uint32_t>(machInst, dest, op1, step);
85 case 3:
86 return new Base<uint64_t>(machInst, dest, op1, step);
87 default:
88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
89 }
90 }
91
92}};
93
94let {{
95 header_output = '''
96 StaticInstPtr
97 decodeNeonMem(ExtMachInst machInst);
98
99 StaticInstPtr
100 decodeNeonData(ExtMachInst machInst);
101 '''
102
103 decoder_output = '''
104 StaticInstPtr
105 decodeNeonMem(ExtMachInst machInst)
106 {
107 const uint32_t b = bits(machInst, 11, 8);
108 const bool single = bits(machInst, 23);
109 const bool singleAll = single && (bits(b, 3, 2) == 3);
110 const bool load = bits(machInst, 21);
111
112 unsigned width = 0;
113
114 if (single) {
115 width = bits(b, 1, 0) + 1;
116 } else {
117 switch (bits(b, 3, 1)) {
118 case 0x0: width = 4;
119 break;
120 case 0x1: width = (b & 0x1) ? 2 : 1;
121 break;
122 case 0x2: width = 3;
123 break;
124 case 0x3: width = 1;
125 break;
126 case 0x4: width = 2;
127 break;
128 case 0x5:
129 if ((b & 0x1) == 0) {
130 width = 1;
131 break;
132 }
133 // Fall through on purpose.
134 default:
135 return new Unknown(machInst);
136 }
137 }
138 assert(width > 0 && width <= 4);
139
140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
143 bits(machInst, 22) << 4);
144 const uint32_t type = bits(machInst, 11, 8);
145 uint32_t size = 0;
146 uint32_t align = TLB::MustBeOne;
147 unsigned inc = 1;
148 unsigned regs = 1;
149 unsigned lane = 0;
150 if (single) {
151 if (singleAll) {
152 size = bits(machInst, 7, 6);
153 bool t = bits(machInst, 5);
154 align = size | TLB::AllowUnaligned;
155 if (width == 1) {
156 regs = t ? 2 : 1;
157 inc = 1;
158 } else {
159 regs = width;
160 inc = t ? 2 : 1;
161 }
162 switch (width) {
163 case 1:
164 case 2:
165 if (bits(machInst, 4))
166 align = size + width - 1;
167 break;
168 case 3:
169 break;
170 case 4:
171 if (size == 3) {
172 if (bits(machInst, 4) == 0)
173 return new Unknown(machInst);
174 size = 2;
175 align = 0x4;
176 } else if (size == 2) {
177 if (bits(machInst, 4))
178 align = 0x3;
179 } else {
180 if (bits(machInst, 4))
181 align = size + 2;
182 }
183 break;
184 }
185 } else {
186 size = bits(machInst, 11, 10);
187 align = size | TLB::AllowUnaligned;
188 regs = width;
189 unsigned indexAlign = bits(machInst, 7, 4);
190 // If width is 1, inc is always 1. That's overridden later.
191 switch (size) {
192 case 0:
193 inc = 1;
194 lane = bits(indexAlign, 3, 1);
195 break;
196 case 1:
197 inc = bits(indexAlign, 1) ? 2 : 1;
198 lane = bits(indexAlign, 3, 2);
199 break;
200 case 2:
201 inc = bits(indexAlign, 2) ? 2 : 1;
202 lane = bits(indexAlign, 3);
203 break;
204 }
205 // Override inc for width of 1.
206 if (width == 1) {
207 inc = 1;
208 }
209 switch (width) {
210 case 1:
211 switch (size) {
212 case 0:
213 break;
214 case 1:
215 if (bits(indexAlign, 0))
216 align = 1;
217 break;
218 case 2:
219 if (bits(indexAlign, 1, 0))
220 align = 2;
221 break;
222 }
223 break;
224 case 2:
225 if (bits(indexAlign, 0))
226 align = size + 1;
227 break;
228 case 3:
229 break;
230 case 4:
231 switch (size) {
232 case 0:
233 case 1:
234 if (bits(indexAlign, 0))
235 align = size + 2;
236 break;
237 case 2:
238 if (bits(indexAlign, 0))
239 align = bits(indexAlign, 1, 0) + 2;
240 break;
241 }
242 break;
243 }
244 }
245 if (size == 0x3) {
246 return new Unknown(machInst);
247 }
248 } else {
249 size = bits(machInst, 7, 6);
250 align = bits(machInst, 5, 4);
251 if (align == 0) {
252 // @align wasn't specified, so alignment can be turned off.
253 align = size | TLB::AllowUnaligned;
254 } else {
255 align = align + 2;
256 }
257 switch (width) {
258 case 1:
259 switch (type) {
260 case 0x7: regs = 1;
261 break;
262 case 0xa: regs = 2;
263 break;
264 case 0x6: regs = 3;
265 break;
266 case 0x2: regs = 4;
267 break;
268 default:
269 return new Unknown(machInst);
270 }
271 break;
272 case 2:
273 // Regs doesn't behave exactly as it does in the manual
274 // because they loop over regs registers twice and we break
275 // it down in the macroop.
276 switch (type) {
277 case 0x8: regs = 2; inc = 1;
278 break;
279 case 0x9: regs = 2; inc = 2;
280 break;
281 case 0x3: regs = 4; inc = 2;
282 break;
283 default:
284 return new Unknown(machInst);
285 }
286 break;
287 case 3:
288 regs = 3;
289 switch (type) {
290 case 0x4: inc = 1;
291 break;
292 case 0x5: inc = 2;;
293 break;
294 default:
295 return new Unknown(machInst);
296 }
297 break;
298 case 4:
299 regs = 4;
300 switch (type) {
301 case 0: inc = 1;
302 break;
303 case 1: inc = 2;
304 break;
305 default:
306 return new Unknown(machInst);
307 }
308 break;
309 }
310 }
311
312 if (load) {
313 // Load instructions.
314 if (single) {
315 return new VldSingle(machInst, singleAll, width, rn, vd,
316 regs, inc, size, align, rm, lane);
317 } else {
318 return new VldMult(machInst, width, rn, vd,
319 regs, inc, size, align, rm);
320 }
321 } else {
322 // Store instructions.
323 if (single) {
324 if (singleAll) {
325 return new Unknown(machInst);
326 } else {
327 return new VstSingle(machInst, false, width, rn, vd,
328 regs, inc, size, align, rm, lane);
329 }
330 } else {
331 return new VstMult(machInst, width, rn, vd,
332 regs, inc, size, align, rm);
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338
339 decoder_output += '''
340 static StaticInstPtr
341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
342 {
343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
344 const uint32_t a = bits(machInst, 11, 8);
345 const bool b = bits(machInst, 4);
346 const uint32_t c = bits(machInst, 21, 20);
347 const IntRegIndex vd =
348 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
349 (bits(machInst, 22) << 4)));
350 const IntRegIndex vn =
351 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
352 (bits(machInst, 7) << 4)));
353 const IntRegIndex vm =
354 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
355 (bits(machInst, 5) << 4)));
356 const unsigned size = bits(machInst, 21, 20);
357 const bool q = bits(machInst, 6);
358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
359 return new Unknown(machInst);
360 switch (a) {
361 case 0x0:
362 if (b) {
363 if (u) {
364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
365 q, size, machInst, vd, vn, vm);
366 } else {
367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
368 q, size, machInst, vd, vn, vm);
369 }
370 } else {
371 if (size == 3)
372 return new Unknown(machInst);
373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
374 q, u, size, machInst, vd, vn, vm);
375 }
376 case 0x1:
377 if (!b) {
378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
379 q, u, size, machInst, vd, vn, vm);
380 } else {
381 if (u) {
382 switch (c) {
383 case 0:
384 if (q) {
385 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
386 } else {
387 return new VeorD<uint64_t>(machInst, vd, vn, vm);
388 }
389 case 1:
390 if (q) {
391 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
392 } else {
393 return new VbslD<uint64_t>(machInst, vd, vn, vm);
394 }
395 case 2:
396 if (q) {
397 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
398 } else {
399 return new VbitD<uint64_t>(machInst, vd, vn, vm);
400 }
401 case 3:
402 if (q) {
403 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
404 } else {
405 return new VbifD<uint64_t>(machInst, vd, vn, vm);
406 }
407 }
408 } else {
409 switch (c) {
410 case 0:
411 if (q) {
412 return new VandQ<uint64_t>(machInst, vd, vn, vm);
413 } else {
414 return new VandD<uint64_t>(machInst, vd, vn, vm);
415 }
416 case 1:
417 if (q) {
418 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
419 } else {
420 return new VbicD<uint64_t>(machInst, vd, vn, vm);
421 }
422 case 2:
423 if (vn == vm) {
424 if (q) {
425 return new VmovQ<uint64_t>(
426 machInst, vd, vn, vm);
427 } else {
428 return new VmovD<uint64_t>(
429 machInst, vd, vn, vm);
430 }
431 } else {
432 if (q) {
433 return new VorrQ<uint64_t>(
434 machInst, vd, vn, vm);
435 } else {
436 return new VorrD<uint64_t>(
437 machInst, vd, vn, vm);
438 }
439 }
440 case 3:
441 if (q) {
442 return new VornQ<uint64_t>(
443 machInst, vd, vn, vm);
444 } else {
445 return new VornD<uint64_t>(
446 machInst, vd, vn, vm);
447 }
448 }
449 }
450 }
451 case 0x2:
452 if (b) {
453 if (u) {
454 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
455 q, size, machInst, vd, vn, vm);
456 } else {
457 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
458 q, size, machInst, vd, vn, vm);
459 }
460 } else {
461 if (size == 3)
462 return new Unknown(machInst);
463 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
464 q, u, size, machInst, vd, vn, vm);
465 }
466 case 0x3:
467 if (b) {
468 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
469 q, u, size, machInst, vd, vn, vm);
470 } else {
471 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
472 q, u, size, machInst, vd, vn, vm);
473 }
474 case 0x4:
475 if (b) {
476 if (u) {
477 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
478 q, size, machInst, vd, vm, vn);
479 } else {
480 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
481 q, size, machInst, vd, vm, vn);
482 }
483 } else {
484 return decodeNeonUSThreeReg<VshlD, VshlQ>(
485 q, u, size, machInst, vd, vm, vn);
486 }
487 case 0x5:
488 if (b) {
489 if (u) {
490 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
491 q, size, machInst, vd, vm, vn);
492 } else {
493 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
494 q, size, machInst, vd, vm, vn);
495 }
496 } else {
497 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
498 q, u, size, machInst, vd, vm, vn);
499 }
500 case 0x6:
501 if (b) {
502 return decodeNeonUSThreeReg<VminD, VminQ>(
503 q, u, size, machInst, vd, vn, vm);
504 } else {
505 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
506 q, u, size, machInst, vd, vn, vm);
507 }
508 case 0x7:
509 if (b) {
510 return decodeNeonUSThreeReg<VabaD, VabaQ>(
511 q, u, size, machInst, vd, vn, vm);
512 } else {
513 if (bits(machInst, 23) == 1) {
514 if (q) {
515 return new Unknown(machInst);
516 } else {
517 return decodeNeonUSThreeUSReg<Vabdl>(
518 u, size, machInst, vd, vn, vm);
519 }
520 } else {
521 return decodeNeonUSThreeReg<VabdD, VabdQ>(
522 q, u, size, machInst, vd, vn, vm);
523 }
524 }
525 case 0x8:
526 if (b) {
527 if (u) {
528 return decodeNeonUThreeReg<VceqD, VceqQ>(
529 q, size, machInst, vd, vn, vm);
530 } else {
531 return decodeNeonUThreeReg<VtstD, VtstQ>(
532 q, size, machInst, vd, vn, vm);
533 }
534 } else {
535 if (u) {
536 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
537 q, size, machInst, vd, vn, vm);
538 } else {
539 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
540 q, size, machInst, vd, vn, vm);
541 }
542 }
543 case 0x9:
544 if (b) {
545 if (u) {
546 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
547 q, size, machInst, vd, vn, vm);
548 } else {
549 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
550 q, size, machInst, vd, vn, vm);
551 }
552 } else {
553 if (u) {
554 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
555 q, u, size, machInst, vd, vn, vm);
556 } else {
557 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
558 q, u, size, machInst, vd, vn, vm);
559 }
560 }
561 case 0xa:
562 if (q)
563 return new Unknown(machInst);
564 if (b) {
565 return decodeNeonUSThreeUSReg<VpminD>(
566 u, size, machInst, vd, vn, vm);
567 } else {
568 return decodeNeonUSThreeUSReg<VpmaxD>(
569 u, size, machInst, vd, vn, vm);
570 }
571 case 0xb:
572 if (b) {
573 if (u || q) {
574 return new Unknown(machInst);
575 } else {
576 return decodeNeonUThreeUSReg<NVpaddD>(
577 size, machInst, vd, vn, vm);
578 }
579 } else {
580 if (u) {
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582 q, size, machInst, vd, vn, vm);
583 } else {
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585 q, size, machInst, vd, vn, vm);
586 }
587 }
588 case 0xc:
589 if (b) {
590 if (!u) {
591 if (bits(c, 1) == 0) {
592 if (q) {
593 return new NVfmaQFp<float>(machInst, vd, vn, vm);
594 } else {
595 return new NVfmaDFp<float>(machInst, vd, vn, vm);
596 }
597 } else {
598 if (q) {
599 return new NVfmsQFp<float>(machInst, vd, vn, vm);
600 } else {
601 return new NVfmsDFp<float>(machInst, vd, vn, vm);
602 }
603 }
604 }
605 }
606 return new Unknown(machInst);
607 case 0xd:
608 if (b) {
609 if (u) {
610 if (bits(c, 1) == 0) {
611 if (q) {
612 return new NVmulQFp<float>(machInst, vd, vn, vm);
613 } else {
614 return new NVmulDFp<float>(machInst, vd, vn, vm);
615 }
616 } else {
617 return new Unknown(machInst);
618 }
619 } else {
620 if (bits(c, 1) == 0) {
621 if (q) {
622 return new NVmlaQFp<float>(machInst, vd, vn, vm);
623 } else {
624 return new NVmlaDFp<float>(machInst, vd, vn, vm);
625 }
626 } else {
627 if (q) {
628 return new NVmlsQFp<float>(machInst, vd, vn, vm);
629 } else {
630 return new NVmlsDFp<float>(machInst, vd, vn, vm);
631 }
632 }
633 }
634 } else {
635 if (u) {
636 if (bits(c, 1) == 0) {
637 if (q) {
638 return new VpaddQFp<float>(machInst, vd, vn, vm);
639 } else {
640 return new VpaddDFp<float>(machInst, vd, vn, vm);
641 }
642 } else {
643 if (q) {
644 return new VabdQFp<float>(machInst, vd, vn, vm);
645 } else {
646 return new VabdDFp<float>(machInst, vd, vn, vm);
647 }
648 }
649 } else {
650 if (bits(c, 1) == 0) {
651 if (q) {
652 return new VaddQFp<float>(machInst, vd, vn, vm);
653 } else {
654 return new VaddDFp<float>(machInst, vd, vn, vm);
655 }
656 } else {
657 if (q) {
658 return new VsubQFp<float>(machInst, vd, vn, vm);
659 } else {
660 return new VsubDFp<float>(machInst, vd, vn, vm);
661 }
662 }
663 }
664 }
665 case 0xe:
666 if (b) {
667 if (u) {
668 if (bits(c, 1) == 0) {
669 if (q) {
670 return new VacgeQFp<float>(machInst, vd, vn, vm);
671 } else {
672 return new VacgeDFp<float>(machInst, vd, vn, vm);
673 }
674 } else {
675 if (q) {
676 return new VacgtQFp<float>(machInst, vd, vn, vm);
677 } else {
678 return new VacgtDFp<float>(machInst, vd, vn, vm);
679 }
680 }
681 } else {
682 return new Unknown(machInst);
683 }
684 } else {
685 if (u) {
686 if (bits(c, 1) == 0) {
687 if (q) {
688 return new VcgeQFp<float>(machInst, vd, vn, vm);
689 } else {
690 return new VcgeDFp<float>(machInst, vd, vn, vm);
691 }
692 } else {
693 if (q) {
694 return new VcgtQFp<float>(machInst, vd, vn, vm);
695 } else {
696 return new VcgtDFp<float>(machInst, vd, vn, vm);
697 }
698 }
699 } else {
700 if (bits(c, 1) == 0) {
701 if (q) {
702 return new VceqQFp<float>(machInst, vd, vn, vm);
703 } else {
704 return new VceqDFp<float>(machInst, vd, vn, vm);
705 }
706 } else {
707 return new Unknown(machInst);
708 }
709 }
710 }
711 case 0xf:
712 if (b) {
713 if (u) {
714 return new Unknown(machInst);
715 } else {
716 if (bits(c, 1) == 0) {
717 if (q) {
718 return new VrecpsQFp<float>(machInst, vd, vn, vm);
719 } else {
720 return new VrecpsDFp<float>(machInst, vd, vn, vm);
721 }
722 } else {
723 if (q) {
724 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
725 } else {
726 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
727 }
728 }
729 }
730 } else {
731 if (u) {
732 if (bits(c, 1) == 0) {
733 if (q) {
734 return new VpmaxQFp<float>(machInst, vd, vn, vm);
735 } else {
736 return new VpmaxDFp<float>(machInst, vd, vn, vm);
737 }
738 } else {
739 if (q) {
740 return new VpminQFp<float>(machInst, vd, vn, vm);
741 } else {
742 return new VpminDFp<float>(machInst, vd, vn, vm);
743 }
744 }
745 } else {
746 if (bits(c, 1) == 0) {
747 if (q) {
748 return new VmaxQFp<float>(machInst, vd, vn, vm);
749 } else {
750 return new VmaxDFp<float>(machInst, vd, vn, vm);
751 }
752 } else {
753 if (q) {
754 return new VminQFp<float>(machInst, vd, vn, vm);
755 } else {
756 return new VminDFp<float>(machInst, vd, vn, vm);
757 }
758 }
759 }
760 }
761 }
762 return new Unknown(machInst);
763 }
764
765 static StaticInstPtr
766 decodeNeonOneRegModImm(ExtMachInst machInst)
767 {
768 const IntRegIndex vd =
769 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
770 (bits(machInst, 22) << 4)));
771 const bool q = bits(machInst, 6);
772 const bool op = bits(machInst, 5);
773 const uint8_t cmode = bits(machInst, 11, 8);
774 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
775 bits(machInst, 24)) << 7) |
776 (bits(machInst, 18, 16) << 4) |
777 (bits(machInst, 3, 0) << 0);
778
779 // Check for invalid immediate encodings and return an unknown op
780 // if it happens
781 bool immValid = true;
782 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
783 if (!immValid) {
784 return new Unknown(machInst);
785 }
786
787 if (op) {
788 if (bits(cmode, 3) == 0) {
789 if (bits(cmode, 0) == 0) {
790 if (q)
791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
792 else
793 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794 } else {
795 if (q)
796 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
797 else
798 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
799 }
800 } else {
801 if (bits(cmode, 2) == 1) {
802 switch (bits(cmode, 1, 0)) {
803 case 0:
804 case 1:
805 if (q)
806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
807 else
808 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
809 case 2:
810 if (q)
811 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
812 else
813 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
814 case 3:
815 if (q)
816 return new Unknown(machInst);
817 else
818 return new Unknown(machInst);
819 }
820 } else {
821 if (bits(cmode, 0) == 0) {
822 if (q)
823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
824 else
825 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
826 } else {
827 if (q)
828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
829 else
830 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
831 }
832 }
833 }
834 } else {
835 if (bits(cmode, 3) == 0) {
836 if (bits(cmode, 0) == 0) {
837 if (q)
838 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
839 else
840 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
841 } else {
842 if (q)
843 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
844 else
845 return new NVorriD<uint64_t>(machInst, vd, bigImm);
846 }
847 } else {
848 if (bits(cmode, 2) == 1) {
849 if (q)
850 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
851 else
852 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
853 } else {
854 if (bits(cmode, 0) == 0) {
855 if (q)
856 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
857 else
858 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
859 } else {
860 if (q)
861 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
862 else
863 return new NVorriD<uint64_t>(machInst, vd, bigImm);
864 }
865 }
866 }
867 }
868 return new Unknown(machInst);
869 }
870
871 static StaticInstPtr
872 decodeNeonTwoRegAndShift(ExtMachInst machInst)
873 {
874 const uint32_t a = bits(machInst, 11, 8);
875 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
876 const bool b = bits(machInst, 6);
877 const bool l = bits(machInst, 7);
878 const IntRegIndex vd =
879 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
880 (bits(machInst, 22) << 4)));
881 const IntRegIndex vm =
882 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
883 (bits(machInst, 5) << 4)));
884 unsigned imm6 = bits(machInst, 21, 16);
885 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
886 unsigned size = 3;
887 unsigned lShiftAmt = 0;
888 unsigned bitSel;
889 for (bitSel = 1 << 6; true; bitSel >>= 1) {
890 if (bitSel & imm)
891 break;
892 else if (!size)
893 return new Unknown(machInst);
894 size--;
895 }
896 lShiftAmt = imm6 & ~bitSel;
897 unsigned rShiftAmt = 0;
898 if (a != 0xe && a != 0xf) {
899 if (size > 2)
900 rShiftAmt = 64 - imm6;
901 else
902 rShiftAmt = 2 * (8 << size) - imm6;
903 }
904
905 switch (a) {
906 case 0x0:
907 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
908 b, u, size, machInst, vd, vm, rShiftAmt);
909 case 0x1:
910 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
911 b, u, size, machInst, vd, vm, rShiftAmt);
912 case 0x2:
913 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
914 b, u, size, machInst, vd, vm, rShiftAmt);
915 case 0x3:
916 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
917 b, u, size, machInst, vd, vm, rShiftAmt);
918 case 0x4:
919 if (u) {
920 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
921 b, size, machInst, vd, vm, rShiftAmt);
922 } else {
923 return new Unknown(machInst);
924 }
925 case 0x5:
926 if (u) {
927 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
928 b, size, machInst, vd, vm, lShiftAmt);
929 } else {
930 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
931 b, size, machInst, vd, vm, lShiftAmt);
932 }
933 case 0x6:
934 case 0x7:
935 if (u) {
936 if (a == 0x6) {
937 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
938 b, size, machInst, vd, vm, lShiftAmt);
939 } else {
940 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
941 b, size, machInst, vd, vm, lShiftAmt);
942 }
943 } else {
944 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
945 b, size, machInst, vd, vm, lShiftAmt);
946 }
947 case 0x8:
948 if (l) {
949 return new Unknown(machInst);
950 } else if (u) {
951 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
952 b, size, machInst, vd, vm, rShiftAmt);
953 } else {
954 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
955 b, size, machInst, vd, vm, rShiftAmt);
956 }
957 case 0x9:
958 if (l) {
959 return new Unknown(machInst);
960 } else if (u) {
961 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
962 b, size, machInst, vd, vm, rShiftAmt);
963 } else {
964 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
965 b, size, machInst, vd, vm, rShiftAmt);
966 }
967 case 0xa:
968 if (l || b) {
969 return new Unknown(machInst);
970 } else {
971 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
972 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
973 }
974 case 0xe:
975 if (l) {
976 return new Unknown(machInst);
977 } else {
978 if (bits(imm6, 5) == 0)
979 return new Unknown(machInst);
980 if (u) {
981 if (b) {
982 return new NVcvtu2fpQ<float>(
983 machInst, vd, vm, 64 - imm6);
984 } else {
985 return new NVcvtu2fpD<float>(
986 machInst, vd, vm, 64 - imm6);
987 }
988 } else {
989 if (b) {
990 return new NVcvts2fpQ<float>(
991 machInst, vd, vm, 64 - imm6);
992 } else {
993 return new NVcvts2fpD<float>(
994 machInst, vd, vm, 64 - imm6);
995 }
996 }
997 }
998 case 0xf:
999 if (l) {
1000 return new Unknown(machInst);
1001 } else {
1002 if (bits(imm6, 5) == 0)
1003 return new Unknown(machInst);
1004 if (u) {
1005 if (b) {
1006 return new NVcvt2ufxQ<float>(
1007 machInst, vd, vm, 64 - imm6);
1008 } else {
1009 return new NVcvt2ufxD<float>(
1010 machInst, vd, vm, 64 - imm6);
1011 }
1012 } else {
1013 if (b) {
1014 return new NVcvt2sfxQ<float>(
1015 machInst, vd, vm, 64 - imm6);
1016 } else {
1017 return new NVcvt2sfxD<float>(
1018 machInst, vd, vm, 64 - imm6);
1019 }
1020 }
1021 }
1022 }
1023 return new Unknown(machInst);
1024 }
1025
1026 static StaticInstPtr
1027 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1028 {
1029 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1030 const uint32_t a = bits(machInst, 11, 8);
1031 const IntRegIndex vd =
1032 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1033 (bits(machInst, 22) << 4)));
1034 const IntRegIndex vn =
1035 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1036 (bits(machInst, 7) << 4)));
1037 const IntRegIndex vm =
1038 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1039 (bits(machInst, 5) << 4)));
1040 const unsigned size = bits(machInst, 21, 20);
1041 switch (a) {
1042 case 0x0:
1043 return decodeNeonUSThreeUSReg<Vaddl>(
1044 u, size, machInst, vd, vn, vm);
1045 case 0x1:
1046 return decodeNeonUSThreeUSReg<Vaddw>(
1047 u, size, machInst, vd, vn, vm);
1048 case 0x2:
1049 return decodeNeonUSThreeUSReg<Vsubl>(
1050 u, size, machInst, vd, vn, vm);
1051 case 0x3:
1052 return decodeNeonUSThreeUSReg<Vsubw>(
1053 u, size, machInst, vd, vn, vm);
1054 case 0x4:
1055 if (u) {
1056 return decodeNeonUThreeUSReg<Vraddhn>(
1057 size, machInst, vd, vn, vm);
1058 } else {
1059 return decodeNeonUThreeUSReg<Vaddhn>(
1060 size, machInst, vd, vn, vm);
1061 }
1062 case 0x5:
1063 return decodeNeonUSThreeUSReg<Vabal>(
1064 u, size, machInst, vd, vn, vm);
1065 case 0x6:
1066 if (u) {
1067 return decodeNeonUThreeUSReg<Vrsubhn>(
1068 size, machInst, vd, vn, vm);
1069 } else {
1070 return decodeNeonUThreeUSReg<Vsubhn>(
1071 size, machInst, vd, vn, vm);
1072 }
1073 case 0x7:
1074 if (bits(machInst, 23)) {
1075 return decodeNeonUSThreeUSReg<Vabdl>(
1076 u, size, machInst, vd, vn, vm);
1077 } else {
1078 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1079 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1080 }
1081 case 0x8:
1082 return decodeNeonUSThreeUSReg<Vmlal>(
1083 u, size, machInst, vd, vn, vm);
1084 case 0xa:
1085 return decodeNeonUSThreeUSReg<Vmlsl>(
1086 u, size, machInst, vd, vn, vm);
1087 case 0x9:
1088 if (u) {
1089 return new Unknown(machInst);
1090 } else {
1091 return decodeNeonSThreeUSReg<Vqdmlal>(
1092 size, machInst, vd, vn, vm);
1093 }
1094 case 0xb:
1095 if (u) {
1096 return new Unknown(machInst);
1097 } else {
1098 return decodeNeonSThreeUSReg<Vqdmlsl>(
1099 size, machInst, vd, vn, vm);
1100 }
1101 case 0xc:
1102 return decodeNeonUSThreeUSReg<Vmull>(
1103 u, size, machInst, vd, vn, vm);
1104 case 0xd:
1105 if (u) {
1106 return new Unknown(machInst);
1107 } else {
1108 return decodeNeonSThreeUSReg<Vqdmull>(
1109 size, machInst, vd, vn, vm);
1110 }
1111 case 0xe:
1112 return decodeNeonUThreeUSReg<Vmullp>(
1113 size, machInst, vd, vn, vm);
1114 }
1115 return new Unknown(machInst);
1116 }
1117
1118 static StaticInstPtr
1119 decodeNeonTwoRegScalar(ExtMachInst machInst)
1120 {
1121 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1122 const uint32_t a = bits(machInst, 11, 8);
1123 const unsigned size = bits(machInst, 21, 20);
1124 const IntRegIndex vd =
1125 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1126 (bits(machInst, 22) << 4)));
1127 const IntRegIndex vn =
1128 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1129 (bits(machInst, 7) << 4)));
1130 const IntRegIndex vm = (size == 2) ?
1131 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1132 (IntRegIndex)(2 * bits(machInst, 2, 0));
1133 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1134 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1135 switch (a) {
1136 case 0x0:
1137 if (u) {
1138 switch (size) {
1139 case 1:
1140 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1141 case 2:
1142 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1143 default:
1144 return new Unknown(machInst);
1145 }
1146 } else {
1147 switch (size) {
1148 case 1:
1149 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1150 case 2:
1151 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1152 default:
1153 return new Unknown(machInst);
1154 }
1155 }
1156 case 0x1:
1157 if (u)
1158 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1159 else
1160 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1161 case 0x4:
1162 if (u) {
1163 switch (size) {
1164 case 1:
1165 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1166 case 2:
1167 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1168 default:
1169 return new Unknown(machInst);
1170 }
1171 } else {
1172 switch (size) {
1173 case 1:
1174 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1175 case 2:
1176 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1177 default:
1178 return new Unknown(machInst);
1179 }
1180 }
1181 case 0x5:
1182 if (u)
1183 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1184 else
1185 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1186 case 0x2:
1187 if (u) {
1188 switch (size) {
1189 case 1:
1190 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1191 case 2:
1192 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1193 default:
1194 return new Unknown(machInst);
1195 }
1196 } else {
1197 switch (size) {
1198 case 1:
1199 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1200 case 2:
1201 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1202 default:
1203 return new Unknown(machInst);
1204 }
1205 }
1206 case 0x6:
1207 if (u) {
1208 switch (size) {
1209 case 1:
1210 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1211 case 2:
1212 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1213 default:
1214 return new Unknown(machInst);
1215 }
1216 } else {
1217 switch (size) {
1218 case 1:
1219 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1220 case 2:
1221 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1222 default:
1223 return new Unknown(machInst);
1224 }
1225 }
1226 case 0x3:
1227 if (u) {
1228 return new Unknown(machInst);
1229 } else {
1230 switch (size) {
1231 case 1:
1232 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1233 case 2:
1234 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1235 default:
1236 return new Unknown(machInst);
1237 }
1238 }
1239 case 0x7:
1240 if (u) {
1241 return new Unknown(machInst);
1242 } else {
1243 switch (size) {
1244 case 1:
1245 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1246 case 2:
1247 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1248 default:
1249 return new Unknown(machInst);
1250 }
1251 }
1252 case 0x8:
1253 if (u) {
1254 switch (size) {
1255 case 1:
1256 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1257 case 2:
1258 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1259 default:
1260 return new Unknown(machInst);
1261 }
1262 } else {
1263 switch (size) {
1264 case 1:
1265 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1266 case 2:
1267 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1268 default:
1269 return new Unknown(machInst);
1270 }
1271 }
1272 case 0x9:
1273 if (u)
1274 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1275 else
1276 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1277 case 0xa:
1278 if (u) {
1279 switch (size) {
1280 case 1:
1281 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1282 case 2:
1283 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1284 default:
1285 return new Unknown(machInst);
1286 }
1287 } else {
1288 switch (size) {
1289 case 1:
1290 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1291 case 2:
1292 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1293 default:
1294 return new Unknown(machInst);
1295 }
1296 }
1297 case 0xb:
1298 if (u) {
1299 return new Unknown(machInst);
1300 } else {
1301 if (u) {
1302 switch (size) {
1303 case 1:
1304 return new Vqdmulls<uint16_t>(
1305 machInst, vd, vn, vm, index);
1306 case 2:
1307 return new Vqdmulls<uint32_t>(
1308 machInst, vd, vn, vm, index);
1309 default:
1310 return new Unknown(machInst);
1311 }
1312 } else {
1313 switch (size) {
1314 case 1:
1315 return new Vqdmulls<int16_t>(
1316 machInst, vd, vn, vm, index);
1317 case 2:
1318 return new Vqdmulls<int32_t>(
1319 machInst, vd, vn, vm, index);
1320 default:
1321 return new Unknown(machInst);
1322 }
1323 }
1324 }
1325 case 0xc:
1326 if (u) {
1327 switch (size) {
1328 case 1:
1329 return new VqdmulhsQ<int16_t>(
1330 machInst, vd, vn, vm, index);
1331 case 2:
1332 return new VqdmulhsQ<int32_t>(
1333 machInst, vd, vn, vm, index);
1334 default:
1335 return new Unknown(machInst);
1336 }
1337 } else {
1338 switch (size) {
1339 case 1:
1340 return new VqdmulhsD<int16_t>(
1341 machInst, vd, vn, vm, index);
1342 case 2:
1343 return new VqdmulhsD<int32_t>(
1344 machInst, vd, vn, vm, index);
1345 default:
1346 return new Unknown(machInst);
1347 }
1348 }
1349 case 0xd:
1350 if (u) {
1351 switch (size) {
1352 case 1:
1353 return new VqrdmulhsQ<int16_t>(
1354 machInst, vd, vn, vm, index);
1355 case 2:
1356 return new VqrdmulhsQ<int32_t>(
1357 machInst, vd, vn, vm, index);
1358 default:
1359 return new Unknown(machInst);
1360 }
1361 } else {
1362 switch (size) {
1363 case 1:
1364 return new VqrdmulhsD<int16_t>(
1365 machInst, vd, vn, vm, index);
1366 case 2:
1367 return new VqrdmulhsD<int32_t>(
1368 machInst, vd, vn, vm, index);
1369 default:
1370 return new Unknown(machInst);
1371 }
1372 }
1373 }
1374 return new Unknown(machInst);
1375 }
1376
1377 static StaticInstPtr
1378 decodeNeonTwoRegMisc(ExtMachInst machInst)
1379 {
1380 const uint32_t a = bits(machInst, 17, 16);
1381 const uint32_t b = bits(machInst, 10, 6);
1382 const bool q = bits(machInst, 6);
1383 const IntRegIndex vd =
1384 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1385 (bits(machInst, 22) << 4)));
1386 const IntRegIndex vm =
1387 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1388 (bits(machInst, 5) << 4)));
1389 const unsigned size = bits(machInst, 19, 18);
1390 switch (a) {
1391 case 0x0:
1392 switch (bits(b, 4, 1)) {
1393 case 0x0:
1394 switch (size) {
1395 case 0:
1396 if (q) {
1397 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1398 } else {
1399 return new NVrev64D<uint8_t>(machInst, vd, vm);
1400 }
1401 case 1:
1402 if (q) {
1403 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1404 } else {
1405 return new NVrev64D<uint16_t>(machInst, vd, vm);
1406 }
1407 case 2:
1408 if (q) {
1409 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1410 } else {
1411 return new NVrev64D<uint32_t>(machInst, vd, vm);
1412 }
1413 default:
1414 return new Unknown(machInst);
1415 }
1416 case 0x1:
1417 switch (size) {
1418 case 0:
1419 if (q) {
1420 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1421 } else {
1422 return new NVrev32D<uint8_t>(machInst, vd, vm);
1423 }
1424 case 1:
1425 if (q) {
1426 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1427 } else {
1428 return new NVrev32D<uint16_t>(machInst, vd, vm);
1429 }
1430 default:
1431 return new Unknown(machInst);
1432 }
1433 case 0x2:
1434 if (size != 0) {
1435 return new Unknown(machInst);
1436 } else if (q) {
1437 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1438 } else {
1439 return new NVrev16D<uint8_t>(machInst, vd, vm);
1440 }
1441 case 0x4:
1442 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1443 q, size, machInst, vd, vm);
1444 case 0x5:
1445 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1446 q, size, machInst, vd, vm);
1447 case 0x8:
1448 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1449 q, size, machInst, vd, vm);
1450 case 0x9:
1451 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1452 q, size, machInst, vd, vm);
1453 case 0xa:
1454 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1455 q, size, machInst, vd, vm);
1456 case 0xb:
1457 if (q)
1458 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1459 else
1460 return new NVmvnD<uint64_t>(machInst, vd, vm);
1461 case 0xc:
1462 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1463 q, size, machInst, vd, vm);
1464 case 0xd:
1465 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1466 q, size, machInst, vd, vm);
1467 case 0xe:
1468 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1469 q, size, machInst, vd, vm);
1470 case 0xf:
1471 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1472 q, size, machInst, vd, vm);
1473 default:
1474 return new Unknown(machInst);
1475 }
1476 case 0x1:
1477 switch (bits(b, 3, 1)) {
1478 case 0x0:
1479 if (bits(b, 4)) {
1480 if (q) {
1481 return new NVcgtQFp<float>(machInst, vd, vm);
1482 } else {
1483 return new NVcgtDFp<float>(machInst, vd, vm);
1484 }
1485 } else {
1486 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1487 q, size, machInst, vd, vm);
1488 }
1489 case 0x1:
1490 if (bits(b, 4)) {
1491 if (q) {
1492 return new NVcgeQFp<float>(machInst, vd, vm);
1493 } else {
1494 return new NVcgeDFp<float>(machInst, vd, vm);
1495 }
1496 } else {
1497 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1498 q, size, machInst, vd, vm);
1499 }
1500 case 0x2:
1501 if (bits(b, 4)) {
1502 if (q) {
1503 return new NVceqQFp<float>(machInst, vd, vm);
1504 } else {
1505 return new NVceqDFp<float>(machInst, vd, vm);
1506 }
1507 } else {
1508 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1509 q, size, machInst, vd, vm);
1510 }
1511 case 0x3:
1512 if (bits(b, 4)) {
1513 if (q) {
1514 return new NVcleQFp<float>(machInst, vd, vm);
1515 } else {
1516 return new NVcleDFp<float>(machInst, vd, vm);
1517 }
1518 } else {
1519 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1520 q, size, machInst, vd, vm);
1521 }
1522 case 0x4:
1523 if (bits(b, 4)) {
1524 if (q) {
1525 return new NVcltQFp<float>(machInst, vd, vm);
1526 } else {
1527 return new NVcltDFp<float>(machInst, vd, vm);
1528 }
1529 } else {
1530 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1531 q, size, machInst, vd, vm);
1532 }
1533 case 0x6:
1534 if (bits(machInst, 10)) {
1535 if (q)
1536 return new NVabsQFp<float>(machInst, vd, vm);
1537 else
1538 return new NVabsDFp<float>(machInst, vd, vm);
1539 } else {
1540 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1541 q, size, machInst, vd, vm);
1542 }
1543 case 0x7:
1544 if (bits(machInst, 10)) {
1545 if (q)
1546 return new NVnegQFp<float>(machInst, vd, vm);
1547 else
1548 return new NVnegDFp<float>(machInst, vd, vm);
1549 } else {
1550 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1551 q, size, machInst, vd, vm);
1552 }
1553 }
1554 case 0x2:
1555 switch (bits(b, 4, 1)) {
1556 case 0x0:
1557 if (q)
1558 return new NVswpQ<uint64_t>(machInst, vd, vm);
1559 else
1560 return new NVswpD<uint64_t>(machInst, vd, vm);
1561 case 0x1:
1562 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1563 q, size, machInst, vd, vm);
1564 case 0x2:
1565 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1566 q, size, machInst, vd, vm);
1567 case 0x3:
1568 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1569 q, size, machInst, vd, vm);
1570 case 0x4:
1571 if (b == 0x8) {
1572 return decodeNeonUTwoMiscUSReg<NVmovn>(
1573 size, machInst, vd, vm);
1574 } else {
1575 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1576 size, machInst, vd, vm);
1577 }
1578 case 0x5:
1579 if (q) {
1580 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1581 size, machInst, vd, vm);
1582 } else {
1583 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1584 size, machInst, vd, vm);
1585 }
1586 case 0x6:
1587 if (b == 0xc) {
1588 return decodeNeonSTwoShiftUSReg<NVshll>(
1589 size, machInst, vd, vm, 8 << size);
1590 } else {
1591 return new Unknown(machInst);
1592 }
1593 case 0xc:
1594 case 0xe:
1595 if (b == 0x18) {
1596 if (size != 1 || (vm % 2))
1597 return new Unknown(machInst);
1598 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1599 } else if (b == 0x1c) {
1600 if (size != 1 || (vd % 2))
1601 return new Unknown(machInst);
1602 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1603 } else {
1604 return new Unknown(machInst);
1605 }
1606 default:
1607 return new Unknown(machInst);
1608 }
1609 case 0x3:
1610 if (bits(b, 4, 3) == 0x3) {
1611 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1612 return new Unknown(machInst);
1613 } else {
1614 if (bits(b, 2)) {
1615 if (bits(b, 1)) {
1616 if (q) {
1617 return new NVcvt2ufxQ<float>(
1618 machInst, vd, vm, 0);
1619 } else {
1620 return new NVcvt2ufxD<float>(
1621 machInst, vd, vm, 0);
1622 }
1623 } else {
1624 if (q) {
1625 return new NVcvt2sfxQ<float>(
1626 machInst, vd, vm, 0);
1627 } else {
1628 return new NVcvt2sfxD<float>(
1629 machInst, vd, vm, 0);
1630 }
1631 }
1632 } else {
1633 if (bits(b, 1)) {
1634 if (q) {
1635 return new NVcvtu2fpQ<float>(
1636 machInst, vd, vm, 0);
1637 } else {
1638 return new NVcvtu2fpD<float>(
1639 machInst, vd, vm, 0);
1640 }
1641 } else {
1642 if (q) {
1643 return new NVcvts2fpQ<float>(
1644 machInst, vd, vm, 0);
1645 } else {
1646 return new NVcvts2fpD<float>(
1647 machInst, vd, vm, 0);
1648 }
1649 }
1650 }
1651 }
1652 } else if ((b & 0x1a) == 0x10) {
1653 if (bits(b, 2)) {
1654 if (q) {
1655 return new NVrecpeQFp<float>(machInst, vd, vm);
1656 } else {
1657 return new NVrecpeDFp<float>(machInst, vd, vm);
1658 }
1659 } else {
1660 if (q) {
1661 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1662 } else {
1663 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1664 }
1665 }
1666 } else if ((b & 0x1a) == 0x12) {
1667 if (bits(b, 2)) {
1668 if (q) {
1669 return new NVrsqrteQFp<float>(machInst, vd, vm);
1670 } else {
1671 return new NVrsqrteDFp<float>(machInst, vd, vm);
1672 }
1673 } else {
1674 if (q) {
1675 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1676 } else {
1677 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1678 }
1679 }
1680 } else {
1681 return new Unknown(machInst);
1682 }
1683 }
1684 return new Unknown(machInst);
1685 }
1686
1687 StaticInstPtr
1688 decodeNeonData(ExtMachInst machInst)
1689 {
1690 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1691 const uint32_t a = bits(machInst, 23, 19);
1692 const uint32_t b = bits(machInst, 11, 8);
1693 const uint32_t c = bits(machInst, 7, 4);
1694 if (bits(a, 4) == 0) {
1695 return decodeNeonThreeRegistersSameLength(machInst);
1696 } else if ((c & 0x9) == 1) {
1697 if ((a & 0x7) == 0) {
1698 return decodeNeonOneRegModImm(machInst);
1699 } else {
1700 return decodeNeonTwoRegAndShift(machInst);
1701 }
1702 } else if ((c & 0x9) == 9) {
1703 return decodeNeonTwoRegAndShift(machInst);
1704 } else if (bits(a, 2, 1) != 0x3) {
1705 if ((c & 0x5) == 0) {
1706 return decodeNeonThreeRegDiffLengths(machInst);
1707 } else if ((c & 0x5) == 4) {
1708 return decodeNeonTwoRegScalar(machInst);
1709 }
1710 } else if ((a & 0x16) == 0x16) {
1711 const IntRegIndex vd =
1712 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1713 (bits(machInst, 22) << 4)));
1714 const IntRegIndex vn =
1715 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1716 (bits(machInst, 7) << 4)));
1717 const IntRegIndex vm =
1718 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1719 (bits(machInst, 5) << 4)));
1720 if (!u) {
1721 if (bits(c, 0) == 0) {
1722 unsigned imm4 = bits(machInst, 11, 8);
1723 bool q = bits(machInst, 6);
1724 if (imm4 >= 16 && !q)
1725 return new Unknown(machInst);
1726 if (q) {
1727 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1728 } else {
1729 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1730 }
1731 }
1732 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1733 return decodeNeonTwoRegMisc(machInst);
1734 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1735 unsigned length = bits(machInst, 9, 8) + 1;
1736 if ((uint32_t)vn / 2 + length > 32)
1737 return new Unknown(machInst);
1738 if (bits(machInst, 6) == 0) {
1739 switch (length) {
1740 case 1:
1741 return new NVtbl1(machInst, vd, vn, vm);
1742 case 2:
1743 return new NVtbl2(machInst, vd, vn, vm);
1744 case 3:
1745 return new NVtbl3(machInst, vd, vn, vm);
1746 case 4:
1747 return new NVtbl4(machInst, vd, vn, vm);
1748 }
1749 } else {
1750 switch (length) {
1751 case 1:
1752 return new NVtbx1(machInst, vd, vn, vm);
1753 case 2:
1754 return new NVtbx2(machInst, vd, vn, vm);
1755 case 3:
1756 return new NVtbx3(machInst, vd, vn, vm);
1757 case 4:
1758 return new NVtbx4(machInst, vd, vn, vm);
1759 }
1760 }
1761 } else if (b == 0xc && (c & 0x9) == 0) {
1762 unsigned imm4 = bits(machInst, 19, 16);
1763 if (bits(imm4, 2, 0) == 0)
1764 return new Unknown(machInst);
1765 unsigned size = 0;
1766 while ((imm4 & 0x1) == 0) {
1767 size++;
1768 imm4 >>= 1;
1769 }
1770 unsigned index = imm4 >> 1;
1771 const bool q = bits(machInst, 6);
1772 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1773 q, size, machInst, vd, vm, index);
1774 }
1775 }
1776 return new Unknown(machInst);
1777 }
1778 '''
1779}};
1780
1781def format ThumbNeonMem() {{
1782 decode_block = '''
1783 return decodeNeonMem(machInst);
1784 '''
1785}};
1786
1787def format ThumbNeonData() {{
1788 decode_block = '''
1789 return decodeNeonData(machInst);
1790 '''
1791}};
1792
1793let {{
1794 header_output = '''
1795 StaticInstPtr
1796 decodeExtensionRegLoadStore(ExtMachInst machInst);
1797 '''
1798 decoder_output = '''
1799 StaticInstPtr
1800 decodeExtensionRegLoadStore(ExtMachInst machInst)
1801 {
1802 const uint32_t opcode = bits(machInst, 24, 20);
1803 const uint32_t offset = bits(machInst, 7, 0);
1804 const bool single = (bits(machInst, 8) == 0);
1805 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1806 RegIndex vd;
1807 if (single) {
1808 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1809 bits(machInst, 22));
1810 } else {
1811 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1812 (bits(machInst, 22) << 5));
1813 }
1814 switch (bits(opcode, 4, 3)) {
1815 case 0x0:
1816 if (bits(opcode, 4, 1) == 0x2 &&
1817 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1818 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1819 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1820 break;
1821 }
1822 const IntRegIndex rt =
1823 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1824 const IntRegIndex rt2 =
1825 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1826 const bool op = bits(machInst, 20);
1827 uint32_t vm;
1828 if (single) {
1829 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1830 } else {
1831 vm = (bits(machInst, 3, 0) << 1) |
1832 (bits(machInst, 5) << 5);
1833 }
1834 if (op) {
1835 return new Vmov2Core2Reg(machInst, rt, rt2,
1836 (IntRegIndex)vm);
1837 } else {
1838 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1839 rt, rt2);
1840 }
1841 }
1842 break;
1843 case 0x1:
1844 {
1845 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1846 break;
1847 }
1848 switch (bits(opcode, 1, 0)) {
1849 case 0x0:
1850 return new VLdmStm(machInst, rn, vd, single,
1851 true, false, false, offset);
1852 case 0x1:
1853 return new VLdmStm(machInst, rn, vd, single,
1854 true, false, true, offset);
1855 case 0x2:
1856 return new VLdmStm(machInst, rn, vd, single,
1857 true, true, false, offset);
1858 case 0x3:
1859 // If rn == sp, then this is called vpop.
1860 return new VLdmStm(machInst, rn, vd, single,
1861 true, true, true, offset);
1862 }
1863 }
1864 case 0x2:
1865 if (bits(opcode, 1, 0) == 0x2) {
1866 // If rn == sp, then this is called vpush.
1867 return new VLdmStm(machInst, rn, vd, single,
1868 false, true, false, offset);
1869 } else if (bits(opcode, 1, 0) == 0x3) {
1870 return new VLdmStm(machInst, rn, vd, single,
1871 false, true, true, offset);
1872 }
1873 // Fall through on purpose
1874 case 0x3:
1875 const bool up = (bits(machInst, 23) == 1);
1876 const uint32_t imm = bits(machInst, 7, 0) << 2;
1877 if (single) {
1878 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1879 (bits(machInst, 22)));
1880 } else {
1881 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1882 (bits(machInst, 22) << 5));
1883 }
1884 if (bits(opcode, 1, 0) == 0x0) {
1885 if (single) {
1886 if (up) {
1887 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1888 } else {
1889 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1890 }
1891 } else {
1892 if (up) {
1893 return new %(vstr_ud)s(machInst, vd, vd + 1,
1894 rn, up, imm);
1895 } else {
1896 return new %(vstr_d)s(machInst, vd, vd + 1,
1897 rn, up, imm);
1898 }
1899 }
1900 } else if (bits(opcode, 1, 0) == 0x1) {
1901 if (single) {
1902 if (up) {
1903 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1904 } else {
1905 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1906 }
1907 } else {
1908 if (up) {
1909 return new %(vldr_ud)s(machInst, vd, vd + 1,
1910 rn, up, imm);
1911 } else {
1912 return new %(vldr_d)s(machInst, vd, vd + 1,
1913 rn, up, imm);
1914 }
1915 }
1916 }
1917 }
1918 return new Unknown(machInst);
1919 }
1920 ''' % {
1921 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1922 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1923 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1924 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1925 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1926 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1927 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1928 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1929 }
1930}};
1931
1932def format ExtensionRegLoadStore() {{
1933 decode_block = '''
1934 return decodeExtensionRegLoadStore(machInst);
1935 '''
1936}};
1937
1938let {{
1939 header_output = '''
1940 StaticInstPtr
1941 decodeShortFpTransfer(ExtMachInst machInst);
1942 '''
1943 decoder_output = '''
1944 StaticInstPtr
1945 decodeShortFpTransfer(ExtMachInst machInst)
1946 {
1947 const uint32_t l = bits(machInst, 20);
1948 const uint32_t c = bits(machInst, 8);
1949 const uint32_t a = bits(machInst, 23, 21);
1950 const uint32_t b = bits(machInst, 6, 5);
1951 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1952 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1953 return new Unknown(machInst);
1953 // Determine if this is backported aarch64 FP instruction
1954 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
1955 const bool b23 = bits(machInst, 23);
1956 const bool b21_b18 = bits(machInst, 21, 18) == 0xE;
1957 const bool b11_b9 = bits(machInst, 11, 9) == 0x5;
1958 const bool sz = bits(machInst, 8);
1959 const bool b7_b6 = bits(machInst, 7, 6) == 0x1;
1960 const bool b6 = bits(machInst, 6) == 0x0;
1961 const bool b4 = bits(machInst, 4) == 0x0;
1962 if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) {
1963 // VINT* Integer Rounding Instructon
1964 const uint32_t rm = bits(machInst, 17, 16);
1965
1966 if (sz) {
1967 const IntRegIndex vd =
1968 (IntRegIndex)((bits(machInst, 22) << 5) |
1969 (bits(machInst, 15, 12) << 1));
1970 const IntRegIndex vm =
1971 (IntRegIndex)((bits(machInst, 5) << 5) |
1972 (bits(machInst, 3, 0) << 1));
1973 switch(rm) {
1974 case 0x0:
1975 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
1976 true);
1977 case 0x1:
1978 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
1979 true);
1980 case 0x2:
1981 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
1982 true);
1983 case 0x3:
1984 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
1985 true);
1986 default: return new Unknown(machInst);
1987 }
1988 } else {
1989 const IntRegIndex vd =
1990 (IntRegIndex)(bits(machInst, 22) |
1991 (bits(machInst, 15, 12) << 1));
1992 const IntRegIndex vm =
1993 (IntRegIndex)(bits(machInst, 5) |
1994 (bits(machInst, 3, 0) << 1));
1995 switch(rm) {
1996 case 0x0:
1997 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
1998 false);
1999 case 0x1:
2000 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2001 false);
2002 case 0x2:
2003 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2004 false);
2005 case 0x3:
2006 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2007 false);
2008 default: return new Unknown(machInst);
2009 }
2010 }
2011 } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){
2012 // VSEL* floating point conditional select
2013
2014 ConditionCode cond;
2015 switch(bits(machInst, 21, 20)) {
2016 case 0x0: cond = COND_EQ; break;
2017 case 0x1: cond = COND_VS; break;
2018 case 0x2: cond = COND_GE; break;
2019 case 0x3: cond = COND_GT; break;
2020 }
2021
2022 if (sz) {
2023 const IntRegIndex vd =
2024 (IntRegIndex)((bits(machInst, 22) << 5) |
2025 (bits(machInst, 15, 12) << 1));
2026 const IntRegIndex vm =
2027 (IntRegIndex)((bits(machInst, 5) << 5) |
2028 (bits(machInst, 3, 0) << 1));
2029 const IntRegIndex vn =
2030 (IntRegIndex)((bits(machInst, 7) << 5) |
2031 (bits(machInst, 19, 16) << 1));
2032 return new VselD(machInst, vd, vn, vm, cond);
2033 } else {
2034 const IntRegIndex vd =
2035 (IntRegIndex)(bits(machInst, 22) |
2036 (bits(machInst, 15, 12) << 1));
2037 const IntRegIndex vm =
2038 (IntRegIndex)(bits(machInst, 5) |
2039 (bits(machInst, 3, 0) << 1));
2040 const IntRegIndex vn =
2041 (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2042 bits(machInst, 7));
2043 return new VselS(machInst, vd, vn, vm, cond);
2044 }
2045 } else {
2046 return new Unknown(machInst);
2047 }
1954 }
1955 if (l == 0 && c == 0) {
1956 if (a == 0) {
1957 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1958 bits(machInst, 7);
1959 const IntRegIndex rt =
1960 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1961 if (bits(machInst, 20) == 1) {
1962 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1963 } else {
1964 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1965 }
1966 } else if (a == 0x7) {
1967 const IntRegIndex rt =
1968 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1969 uint32_t reg = bits(machInst, 19, 16);
1970 uint32_t specReg;
1971 switch (reg) {
1972 case 0:
1973 specReg = MISCREG_FPSID;
1974 break;
1975 case 1:
1976 specReg = MISCREG_FPSCR;
1977 break;
1978 case 6:
1979 specReg = MISCREG_MVFR1;
1980 break;
1981 case 7:
1982 specReg = MISCREG_MVFR0;
1983 break;
1984 case 8:
1985 specReg = MISCREG_FPEXC;
1986 break;
1987 default:
1988 return new Unknown(machInst);
1989 }
1990 if (specReg == MISCREG_FPSCR) {
1991 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1992 } else {
1993 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
1994 reg, a, bits(machInst, 7, 5));
1995 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
1996 }
1997 }
1998 } else if (l == 0 && c == 1) {
1999 if (bits(a, 2) == 0) {
2000 uint32_t vd = (bits(machInst, 7) << 5) |
2001 (bits(machInst, 19, 16) << 1);
2002 // Handle accessing each single precision half of the vector.
2003 vd += bits(machInst, 21);
2004 const IntRegIndex rt =
2005 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2006 if (bits(machInst, 22) == 1) {
2007 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2008 rt, bits(machInst, 6, 5));
2009 } else if (bits(machInst, 5) == 1) {
2010 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2011 rt, bits(machInst, 6));
2012 } else if (bits(machInst, 6) == 0) {
2013 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2014 } else {
2015 return new Unknown(machInst);
2016 }
2017 } else if (bits(b, 1) == 0) {
2018 bool q = bits(machInst, 21);
2019 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2020 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2021 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2022 IntRegIndex rt = (IntRegIndex)(uint32_t)
2023 bits(machInst, 15, 12);
2024 if (q) {
2025 switch (be) {
2026 case 0:
2027 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2028 case 1:
2029 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2030 case 2:
2031 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2032 case 3:
2033 return new Unknown(machInst);
2034 }
2035 } else {
2036 switch (be) {
2037 case 0:
2038 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2039 case 1:
2040 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2041 case 2:
2042 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2043 case 3:
2044 return new Unknown(machInst);
2045 }
2046 }
2047 }
2048 } else if (l == 1 && c == 0) {
2049 if (a == 0) {
2050 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2051 bits(machInst, 7);
2052 const IntRegIndex rt =
2053 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2054 if (bits(machInst, 20) == 1) {
2055 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2056 } else {
2057 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2058 }
2059 } else if (a == 7) {
2060 const IntRegIndex rt =
2061 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2062 uint32_t reg = bits(machInst, 19, 16);
2063 uint32_t specReg;
2064 switch (reg) {
2065 case 0:
2066 specReg = MISCREG_FPSID;
2067 break;
2068 case 1:
2069 specReg = MISCREG_FPSCR;
2070 break;
2071 case 6:
2072 specReg = MISCREG_MVFR1;
2073 break;
2074 case 7:
2075 specReg = MISCREG_MVFR0;
2076 break;
2077 case 8:
2078 specReg = MISCREG_FPEXC;
2079 break;
2080 default:
2081 return new Unknown(machInst);
2082 }
2083 if (rt == 0xf) {
2084 if (specReg == MISCREG_FPSCR) {
2085 return new VmrsApsrFpscr(machInst);
2086 } else {
2087 return new Unknown(machInst);
2088 }
2089 } else if (specReg == MISCREG_FPSCR) {
2090 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2091 } else {
2092 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2093 reg, a, bits(machInst, 7, 5));
2094 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2095 }
2096 }
2097 } else {
2098 uint32_t vd = (bits(machInst, 7) << 5) |
2099 (bits(machInst, 19, 16) << 1);
2100 // Handle indexing into each single precision half of the vector.
2101 vd += bits(machInst, 21);
2102 uint32_t index;
2103 const IntRegIndex rt =
2104 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2105 const bool u = (bits(machInst, 23) == 1);
2106 if (bits(machInst, 22) == 1) {
2107 index = bits(machInst, 6, 5);
2108 if (u) {
2109 return new VmovRegCoreUB(machInst, rt,
2110 (IntRegIndex)vd, index);
2111 } else {
2112 return new VmovRegCoreSB(machInst, rt,
2113 (IntRegIndex)vd, index);
2114 }
2115 } else if (bits(machInst, 5) == 1) {
2116 index = bits(machInst, 6);
2117 if (u) {
2118 return new VmovRegCoreUH(machInst, rt,
2119 (IntRegIndex)vd, index);
2120 } else {
2121 return new VmovRegCoreSH(machInst, rt,
2122 (IntRegIndex)vd, index);
2123 }
2124 } else if (bits(machInst, 6) == 0 && !u) {
2125 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2126 } else {
2127 return new Unknown(machInst);
2128 }
2129 }
2130 return new Unknown(machInst);
2131 }
2132 '''
2133}};
2134
2135def format ShortFpTransfer() {{
2136 decode_block = '''
2137 return decodeShortFpTransfer(machInst);
2138 '''
2139}};
2140
2141let {{
2142 header_output = '''
2143 StaticInstPtr
2144 decodeVfpData(ExtMachInst machInst);
2145 '''
2146 decoder_output = '''
2147 StaticInstPtr
2148 decodeVfpData(ExtMachInst machInst)
2149 {
2150 const uint32_t opc1 = bits(machInst, 23, 20);
2151 const uint32_t opc2 = bits(machInst, 19, 16);
2152 const uint32_t opc3 = bits(machInst, 7, 6);
2153 //const uint32_t opc4 = bits(machInst, 3, 0);
2154 const bool single = (bits(machInst, 8) == 0);
2155 // Used to select between vcmp and vcmpe.
2156 const bool e = (bits(machInst, 7) == 1);
2157 IntRegIndex vd;
2158 IntRegIndex vm;
2159 IntRegIndex vn;
2160 if (single) {
2161 vd = (IntRegIndex)(bits(machInst, 22) |
2162 (bits(machInst, 15, 12) << 1));
2163 vm = (IntRegIndex)(bits(machInst, 5) |
2164 (bits(machInst, 3, 0) << 1));
2165 vn = (IntRegIndex)(bits(machInst, 7) |
2166 (bits(machInst, 19, 16) << 1));
2167 } else {
2168 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2169 (bits(machInst, 15, 12) << 1));
2170 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2171 (bits(machInst, 3, 0) << 1));
2172 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2173 (bits(machInst, 19, 16) << 1));
2174 }
2175 switch (opc1 & 0xb /* 1011 */) {
2176 case 0x0:
2177 if (bits(machInst, 6) == 0) {
2178 if (single) {
2179 return decodeVfpRegRegRegOp<VmlaS>(
2180 machInst, vd, vn, vm, false);
2181 } else {
2182 return decodeVfpRegRegRegOp<VmlaD>(
2183 machInst, vd, vn, vm, true);
2184 }
2185 } else {
2186 if (single) {
2187 return decodeVfpRegRegRegOp<VmlsS>(
2188 machInst, vd, vn, vm, false);
2189 } else {
2190 return decodeVfpRegRegRegOp<VmlsD>(
2191 machInst, vd, vn, vm, true);
2192 }
2193 }
2194 case 0x1:
2195 if (bits(machInst, 6) == 1) {
2196 if (single) {
2197 return decodeVfpRegRegRegOp<VnmlaS>(
2198 machInst, vd, vn, vm, false);
2199 } else {
2200 return decodeVfpRegRegRegOp<VnmlaD>(
2201 machInst, vd, vn, vm, true);
2202 }
2203 } else {
2204 if (single) {
2205 return decodeVfpRegRegRegOp<VnmlsS>(
2206 machInst, vd, vn, vm, false);
2207 } else {
2208 return decodeVfpRegRegRegOp<VnmlsD>(
2209 machInst, vd, vn, vm, true);
2210 }
2211 }
2212 case 0x2:
2213 if ((opc3 & 0x1) == 0) {
2214 if (single) {
2215 return decodeVfpRegRegRegOp<VmulS>(
2216 machInst, vd, vn, vm, false);
2217 } else {
2218 return decodeVfpRegRegRegOp<VmulD>(
2219 machInst, vd, vn, vm, true);
2220 }
2221 } else {
2222 if (single) {
2223 return decodeVfpRegRegRegOp<VnmulS>(
2224 machInst, vd, vn, vm, false);
2225 } else {
2226 return decodeVfpRegRegRegOp<VnmulD>(
2227 machInst, vd, vn, vm, true);
2228 }
2229 }
2230 case 0x3:
2231 if ((opc3 & 0x1) == 0) {
2232 if (single) {
2233 return decodeVfpRegRegRegOp<VaddS>(
2234 machInst, vd, vn, vm, false);
2235 } else {
2236 return decodeVfpRegRegRegOp<VaddD>(
2237 machInst, vd, vn, vm, true);
2238 }
2239 } else {
2240 if (single) {
2241 return decodeVfpRegRegRegOp<VsubS>(
2242 machInst, vd, vn, vm, false);
2243 } else {
2244 return decodeVfpRegRegRegOp<VsubD>(
2245 machInst, vd, vn, vm, true);
2246 }
2247 }
2248 case 0x8:
2249 if ((opc3 & 0x1) == 0) {
2250 if (single) {
2251 return decodeVfpRegRegRegOp<VdivS>(
2252 machInst, vd, vn, vm, false);
2253 } else {
2254 return decodeVfpRegRegRegOp<VdivD>(
2255 machInst, vd, vn, vm, true);
2256 }
2257 }
2258 break;
2259 case 0x9:
2260 if ((opc3 & 0x1) == 0) {
2261 if (single) {
2262 return decodeVfpRegRegRegOp<VfnmaS>(
2263 machInst, vd, vn, vm, false);
2264 } else {
2265 return decodeVfpRegRegRegOp<VfnmaD>(
2266 machInst, vd, vn, vm, true);
2267 }
2268 } else {
2269 if (single) {
2270 return decodeVfpRegRegRegOp<VfnmsS>(
2271 machInst, vd, vn, vm, false);
2272 } else {
2273 return decodeVfpRegRegRegOp<VfnmsD>(
2274 machInst, vd, vn, vm, true);
2275 }
2276 }
2277 break;
2278 case 0xa:
2279 if ((opc3 & 0x1) == 0) {
2280 if (single) {
2281 return decodeVfpRegRegRegOp<VfmaS>(
2282 machInst, vd, vn, vm, false);
2283 } else {
2284 return decodeVfpRegRegRegOp<VfmaD>(
2285 machInst, vd, vn, vm, true);
2286 }
2287 } else {
2288 if (single) {
2289 return decodeVfpRegRegRegOp<VfmsS>(
2290 machInst, vd, vn, vm, false);
2291 } else {
2292 return decodeVfpRegRegRegOp<VfmsD>(
2293 machInst, vd, vn, vm, true);
2294 }
2295 }
2296 break;
2297 case 0xb:
2298 if ((opc3 & 0x1) == 0) {
2299 const uint32_t baseImm =
2300 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2301 if (single) {
2302 uint32_t imm = vfp_modified_imm(baseImm, false);
2303 return decodeVfpRegImmOp<VmovImmS>(
2304 machInst, vd, imm, false);
2305 } else {
2306 uint64_t imm = vfp_modified_imm(baseImm, true);
2307 return decodeVfpRegImmOp<VmovImmD>(
2308 machInst, vd, imm, true);
2309 }
2310 }
2311 switch (opc2) {
2312 case 0x0:
2313 if (opc3 == 1) {
2314 if (single) {
2315 return decodeVfpRegRegOp<VmovRegS>(
2316 machInst, vd, vm, false);
2317 } else {
2318 return decodeVfpRegRegOp<VmovRegD>(
2319 machInst, vd, vm, true);
2320 }
2321 } else {
2322 if (single) {
2323 return decodeVfpRegRegOp<VabsS>(
2324 machInst, vd, vm, false);
2325 } else {
2326 return decodeVfpRegRegOp<VabsD>(
2327 machInst, vd, vm, true);
2328 }
2329 }
2330 case 0x1:
2331 if (opc3 == 1) {
2332 if (single) {
2333 return decodeVfpRegRegOp<VnegS>(
2334 machInst, vd, vm, false);
2335 } else {
2336 return decodeVfpRegRegOp<VnegD>(
2337 machInst, vd, vm, true);
2338 }
2339 } else {
2340 if (single) {
2341 return decodeVfpRegRegOp<VsqrtS>(
2342 machInst, vd, vm, false);
2343 } else {
2344 return decodeVfpRegRegOp<VsqrtD>(
2345 machInst, vd, vm, true);
2346 }
2347 }
2348 case 0x2:
2349 case 0x3:
2350 {
2351 const bool toHalf = bits(machInst, 16);
2352 const bool top = bits(machInst, 7);
2353 if (top) {
2354 if (toHalf) {
2355 return new VcvtFpSFpHT(machInst, vd, vm);
2356 } else {
2357 return new VcvtFpHTFpS(machInst, vd, vm);
2358 }
2359 } else {
2360 if (toHalf) {
2361 return new VcvtFpSFpHB(machInst, vd, vm);
2362 } else {
2363 return new VcvtFpHBFpS(machInst, vd, vm);
2364 }
2365 }
2366 }
2367 case 0x4:
2368 if (single) {
2369 if (e) {
2370 return new VcmpeS(machInst, vd, vm);
2371 } else {
2372 return new VcmpS(machInst, vd, vm);
2373 }
2374 } else {
2375 if (e) {
2376 return new VcmpeD(machInst, vd, vm);
2377 } else {
2378 return new VcmpD(machInst, vd, vm);
2379 }
2380 }
2381 case 0x5:
2382 if (single) {
2383 if (e) {
2384 return new VcmpeZeroS(machInst, vd, 0);
2385 } else {
2386 return new VcmpZeroS(machInst, vd, 0);
2387 }
2388 } else {
2389 if (e) {
2390 return new VcmpeZeroD(machInst, vd, 0);
2391 } else {
2392 return new VcmpZeroD(machInst, vd, 0);
2393 }
2394 }
2395 case 0x7:
2396 if (opc3 == 0x3) {
2397 if (single) {
2398 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2399 (bits(machInst, 15, 12) << 1));
2400 return new VcvtFpSFpD(machInst, vd, vm);
2401 } else {
2402 vd = (IntRegIndex)(bits(machInst, 22) |
2403 (bits(machInst, 15, 12) << 1));
2404 return new VcvtFpDFpS(machInst, vd, vm);
2405 }
2406 }
2407 break;
2408 case 0x8:
2409 if (bits(machInst, 7) == 0) {
2410 if (single) {
2411 return new VcvtUIntFpS(machInst, vd, vm);
2412 } else {
2413 vm = (IntRegIndex)(bits(machInst, 5) |
2414 (bits(machInst, 3, 0) << 1));
2415 return new VcvtUIntFpD(machInst, vd, vm);
2416 }
2417 } else {
2418 if (single) {
2419 return new VcvtSIntFpS(machInst, vd, vm);
2420 } else {
2421 vm = (IntRegIndex)(bits(machInst, 5) |
2422 (bits(machInst, 3, 0) << 1));
2423 return new VcvtSIntFpD(machInst, vd, vm);
2424 }
2425 }
2426 case 0xa:
2427 {
2428 const bool half = (bits(machInst, 7) == 0);
2429 const uint32_t imm = bits(machInst, 5) |
2430 (bits(machInst, 3, 0) << 1);
2431 const uint32_t size =
2432 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2433 if (single) {
2434 if (half) {
2435 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2436 } else {
2437 return new VcvtSFixedFpS(machInst, vd, vd, size);
2438 }
2439 } else {
2440 if (half) {
2441 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2442 } else {
2443 return new VcvtSFixedFpD(machInst, vd, vd, size);
2444 }
2445 }
2446 }
2447 case 0xb:
2448 {
2449 const bool half = (bits(machInst, 7) == 0);
2450 const uint32_t imm = bits(machInst, 5) |
2451 (bits(machInst, 3, 0) << 1);
2452 const uint32_t size =
2453 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2454 if (single) {
2455 if (half) {
2456 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2457 } else {
2458 return new VcvtUFixedFpS(machInst, vd, vd, size);
2459 }
2460 } else {
2461 if (half) {
2462 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2463 } else {
2464 return new VcvtUFixedFpD(machInst, vd, vd, size);
2465 }
2466 }
2467 }
2468 case 0xc:
2469 if (bits(machInst, 7) == 0) {
2470 if (single) {
2471 return new VcvtFpUIntSR(machInst, vd, vm);
2472 } else {
2473 vd = (IntRegIndex)(bits(machInst, 22) |
2474 (bits(machInst, 15, 12) << 1));
2475 return new VcvtFpUIntDR(machInst, vd, vm);
2476 }
2477 } else {
2478 if (single) {
2479 return new VcvtFpUIntS(machInst, vd, vm);
2480 } else {
2481 vd = (IntRegIndex)(bits(machInst, 22) |
2482 (bits(machInst, 15, 12) << 1));
2483 return new VcvtFpUIntD(machInst, vd, vm);
2484 }
2485 }
2486 case 0xd:
2487 if (bits(machInst, 7) == 0) {
2488 if (single) {
2489 return new VcvtFpSIntSR(machInst, vd, vm);
2490 } else {
2491 vd = (IntRegIndex)(bits(machInst, 22) |
2492 (bits(machInst, 15, 12) << 1));
2493 return new VcvtFpSIntDR(machInst, vd, vm);
2494 }
2495 } else {
2496 if (single) {
2497 return new VcvtFpSIntS(machInst, vd, vm);
2498 } else {
2499 vd = (IntRegIndex)(bits(machInst, 22) |
2500 (bits(machInst, 15, 12) << 1));
2501 return new VcvtFpSIntD(machInst, vd, vm);
2502 }
2503 }
2504 case 0xe:
2505 {
2506 const bool half = (bits(machInst, 7) == 0);
2507 const uint32_t imm = bits(machInst, 5) |
2508 (bits(machInst, 3, 0) << 1);
2509 const uint32_t size =
2510 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2511 if (single) {
2512 if (half) {
2513 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2514 } else {
2515 return new VcvtFpSFixedS(machInst, vd, vd, size);
2516 }
2517 } else {
2518 if (half) {
2519 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2520 } else {
2521 return new VcvtFpSFixedD(machInst, vd, vd, size);
2522 }
2523 }
2524 }
2525 case 0xf:
2526 {
2527 const bool half = (bits(machInst, 7) == 0);
2528 const uint32_t imm = bits(machInst, 5) |
2529 (bits(machInst, 3, 0) << 1);
2530 const uint32_t size =
2531 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2532 if (single) {
2533 if (half) {
2534 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2535 } else {
2536 return new VcvtFpUFixedS(machInst, vd, vd, size);
2537 }
2538 } else {
2539 if (half) {
2540 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2541 } else {
2542 return new VcvtFpUFixedD(machInst, vd, vd, size);
2543 }
2544 }
2545 }
2546 }
2547 break;
2548 }
2549 return new Unknown(machInst);
2550 }
2551 '''
2552}};
2553
2554def format VfpData() {{
2555 decode_block = '''
2556 return decodeVfpData(machInst);
2557 '''
2558}};
2048 }
2049 if (l == 0 && c == 0) {
2050 if (a == 0) {
2051 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2052 bits(machInst, 7);
2053 const IntRegIndex rt =
2054 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2055 if (bits(machInst, 20) == 1) {
2056 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2057 } else {
2058 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2059 }
2060 } else if (a == 0x7) {
2061 const IntRegIndex rt =
2062 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2063 uint32_t reg = bits(machInst, 19, 16);
2064 uint32_t specReg;
2065 switch (reg) {
2066 case 0:
2067 specReg = MISCREG_FPSID;
2068 break;
2069 case 1:
2070 specReg = MISCREG_FPSCR;
2071 break;
2072 case 6:
2073 specReg = MISCREG_MVFR1;
2074 break;
2075 case 7:
2076 specReg = MISCREG_MVFR0;
2077 break;
2078 case 8:
2079 specReg = MISCREG_FPEXC;
2080 break;
2081 default:
2082 return new Unknown(machInst);
2083 }
2084 if (specReg == MISCREG_FPSCR) {
2085 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2086 } else {
2087 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2088 reg, a, bits(machInst, 7, 5));
2089 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2090 }
2091 }
2092 } else if (l == 0 && c == 1) {
2093 if (bits(a, 2) == 0) {
2094 uint32_t vd = (bits(machInst, 7) << 5) |
2095 (bits(machInst, 19, 16) << 1);
2096 // Handle accessing each single precision half of the vector.
2097 vd += bits(machInst, 21);
2098 const IntRegIndex rt =
2099 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2100 if (bits(machInst, 22) == 1) {
2101 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2102 rt, bits(machInst, 6, 5));
2103 } else if (bits(machInst, 5) == 1) {
2104 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2105 rt, bits(machInst, 6));
2106 } else if (bits(machInst, 6) == 0) {
2107 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2108 } else {
2109 return new Unknown(machInst);
2110 }
2111 } else if (bits(b, 1) == 0) {
2112 bool q = bits(machInst, 21);
2113 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2114 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2115 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2116 IntRegIndex rt = (IntRegIndex)(uint32_t)
2117 bits(machInst, 15, 12);
2118 if (q) {
2119 switch (be) {
2120 case 0:
2121 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2122 case 1:
2123 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2124 case 2:
2125 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2126 case 3:
2127 return new Unknown(machInst);
2128 }
2129 } else {
2130 switch (be) {
2131 case 0:
2132 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2133 case 1:
2134 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2135 case 2:
2136 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2137 case 3:
2138 return new Unknown(machInst);
2139 }
2140 }
2141 }
2142 } else if (l == 1 && c == 0) {
2143 if (a == 0) {
2144 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2145 bits(machInst, 7);
2146 const IntRegIndex rt =
2147 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2148 if (bits(machInst, 20) == 1) {
2149 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2150 } else {
2151 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2152 }
2153 } else if (a == 7) {
2154 const IntRegIndex rt =
2155 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2156 uint32_t reg = bits(machInst, 19, 16);
2157 uint32_t specReg;
2158 switch (reg) {
2159 case 0:
2160 specReg = MISCREG_FPSID;
2161 break;
2162 case 1:
2163 specReg = MISCREG_FPSCR;
2164 break;
2165 case 6:
2166 specReg = MISCREG_MVFR1;
2167 break;
2168 case 7:
2169 specReg = MISCREG_MVFR0;
2170 break;
2171 case 8:
2172 specReg = MISCREG_FPEXC;
2173 break;
2174 default:
2175 return new Unknown(machInst);
2176 }
2177 if (rt == 0xf) {
2178 if (specReg == MISCREG_FPSCR) {
2179 return new VmrsApsrFpscr(machInst);
2180 } else {
2181 return new Unknown(machInst);
2182 }
2183 } else if (specReg == MISCREG_FPSCR) {
2184 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2185 } else {
2186 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2187 reg, a, bits(machInst, 7, 5));
2188 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2189 }
2190 }
2191 } else {
2192 uint32_t vd = (bits(machInst, 7) << 5) |
2193 (bits(machInst, 19, 16) << 1);
2194 // Handle indexing into each single precision half of the vector.
2195 vd += bits(machInst, 21);
2196 uint32_t index;
2197 const IntRegIndex rt =
2198 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2199 const bool u = (bits(machInst, 23) == 1);
2200 if (bits(machInst, 22) == 1) {
2201 index = bits(machInst, 6, 5);
2202 if (u) {
2203 return new VmovRegCoreUB(machInst, rt,
2204 (IntRegIndex)vd, index);
2205 } else {
2206 return new VmovRegCoreSB(machInst, rt,
2207 (IntRegIndex)vd, index);
2208 }
2209 } else if (bits(machInst, 5) == 1) {
2210 index = bits(machInst, 6);
2211 if (u) {
2212 return new VmovRegCoreUH(machInst, rt,
2213 (IntRegIndex)vd, index);
2214 } else {
2215 return new VmovRegCoreSH(machInst, rt,
2216 (IntRegIndex)vd, index);
2217 }
2218 } else if (bits(machInst, 6) == 0 && !u) {
2219 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2220 } else {
2221 return new Unknown(machInst);
2222 }
2223 }
2224 return new Unknown(machInst);
2225 }
2226 '''
2227}};
2228
2229def format ShortFpTransfer() {{
2230 decode_block = '''
2231 return decodeShortFpTransfer(machInst);
2232 '''
2233}};
2234
2235let {{
2236 header_output = '''
2237 StaticInstPtr
2238 decodeVfpData(ExtMachInst machInst);
2239 '''
2240 decoder_output = '''
2241 StaticInstPtr
2242 decodeVfpData(ExtMachInst machInst)
2243 {
2244 const uint32_t opc1 = bits(machInst, 23, 20);
2245 const uint32_t opc2 = bits(machInst, 19, 16);
2246 const uint32_t opc3 = bits(machInst, 7, 6);
2247 //const uint32_t opc4 = bits(machInst, 3, 0);
2248 const bool single = (bits(machInst, 8) == 0);
2249 // Used to select between vcmp and vcmpe.
2250 const bool e = (bits(machInst, 7) == 1);
2251 IntRegIndex vd;
2252 IntRegIndex vm;
2253 IntRegIndex vn;
2254 if (single) {
2255 vd = (IntRegIndex)(bits(machInst, 22) |
2256 (bits(machInst, 15, 12) << 1));
2257 vm = (IntRegIndex)(bits(machInst, 5) |
2258 (bits(machInst, 3, 0) << 1));
2259 vn = (IntRegIndex)(bits(machInst, 7) |
2260 (bits(machInst, 19, 16) << 1));
2261 } else {
2262 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2263 (bits(machInst, 15, 12) << 1));
2264 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2265 (bits(machInst, 3, 0) << 1));
2266 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2267 (bits(machInst, 19, 16) << 1));
2268 }
2269 switch (opc1 & 0xb /* 1011 */) {
2270 case 0x0:
2271 if (bits(machInst, 6) == 0) {
2272 if (single) {
2273 return decodeVfpRegRegRegOp<VmlaS>(
2274 machInst, vd, vn, vm, false);
2275 } else {
2276 return decodeVfpRegRegRegOp<VmlaD>(
2277 machInst, vd, vn, vm, true);
2278 }
2279 } else {
2280 if (single) {
2281 return decodeVfpRegRegRegOp<VmlsS>(
2282 machInst, vd, vn, vm, false);
2283 } else {
2284 return decodeVfpRegRegRegOp<VmlsD>(
2285 machInst, vd, vn, vm, true);
2286 }
2287 }
2288 case 0x1:
2289 if (bits(machInst, 6) == 1) {
2290 if (single) {
2291 return decodeVfpRegRegRegOp<VnmlaS>(
2292 machInst, vd, vn, vm, false);
2293 } else {
2294 return decodeVfpRegRegRegOp<VnmlaD>(
2295 machInst, vd, vn, vm, true);
2296 }
2297 } else {
2298 if (single) {
2299 return decodeVfpRegRegRegOp<VnmlsS>(
2300 machInst, vd, vn, vm, false);
2301 } else {
2302 return decodeVfpRegRegRegOp<VnmlsD>(
2303 machInst, vd, vn, vm, true);
2304 }
2305 }
2306 case 0x2:
2307 if ((opc3 & 0x1) == 0) {
2308 if (single) {
2309 return decodeVfpRegRegRegOp<VmulS>(
2310 machInst, vd, vn, vm, false);
2311 } else {
2312 return decodeVfpRegRegRegOp<VmulD>(
2313 machInst, vd, vn, vm, true);
2314 }
2315 } else {
2316 if (single) {
2317 return decodeVfpRegRegRegOp<VnmulS>(
2318 machInst, vd, vn, vm, false);
2319 } else {
2320 return decodeVfpRegRegRegOp<VnmulD>(
2321 machInst, vd, vn, vm, true);
2322 }
2323 }
2324 case 0x3:
2325 if ((opc3 & 0x1) == 0) {
2326 if (single) {
2327 return decodeVfpRegRegRegOp<VaddS>(
2328 machInst, vd, vn, vm, false);
2329 } else {
2330 return decodeVfpRegRegRegOp<VaddD>(
2331 machInst, vd, vn, vm, true);
2332 }
2333 } else {
2334 if (single) {
2335 return decodeVfpRegRegRegOp<VsubS>(
2336 machInst, vd, vn, vm, false);
2337 } else {
2338 return decodeVfpRegRegRegOp<VsubD>(
2339 machInst, vd, vn, vm, true);
2340 }
2341 }
2342 case 0x8:
2343 if ((opc3 & 0x1) == 0) {
2344 if (single) {
2345 return decodeVfpRegRegRegOp<VdivS>(
2346 machInst, vd, vn, vm, false);
2347 } else {
2348 return decodeVfpRegRegRegOp<VdivD>(
2349 machInst, vd, vn, vm, true);
2350 }
2351 }
2352 break;
2353 case 0x9:
2354 if ((opc3 & 0x1) == 0) {
2355 if (single) {
2356 return decodeVfpRegRegRegOp<VfnmaS>(
2357 machInst, vd, vn, vm, false);
2358 } else {
2359 return decodeVfpRegRegRegOp<VfnmaD>(
2360 machInst, vd, vn, vm, true);
2361 }
2362 } else {
2363 if (single) {
2364 return decodeVfpRegRegRegOp<VfnmsS>(
2365 machInst, vd, vn, vm, false);
2366 } else {
2367 return decodeVfpRegRegRegOp<VfnmsD>(
2368 machInst, vd, vn, vm, true);
2369 }
2370 }
2371 break;
2372 case 0xa:
2373 if ((opc3 & 0x1) == 0) {
2374 if (single) {
2375 return decodeVfpRegRegRegOp<VfmaS>(
2376 machInst, vd, vn, vm, false);
2377 } else {
2378 return decodeVfpRegRegRegOp<VfmaD>(
2379 machInst, vd, vn, vm, true);
2380 }
2381 } else {
2382 if (single) {
2383 return decodeVfpRegRegRegOp<VfmsS>(
2384 machInst, vd, vn, vm, false);
2385 } else {
2386 return decodeVfpRegRegRegOp<VfmsD>(
2387 machInst, vd, vn, vm, true);
2388 }
2389 }
2390 break;
2391 case 0xb:
2392 if ((opc3 & 0x1) == 0) {
2393 const uint32_t baseImm =
2394 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2395 if (single) {
2396 uint32_t imm = vfp_modified_imm(baseImm, false);
2397 return decodeVfpRegImmOp<VmovImmS>(
2398 machInst, vd, imm, false);
2399 } else {
2400 uint64_t imm = vfp_modified_imm(baseImm, true);
2401 return decodeVfpRegImmOp<VmovImmD>(
2402 machInst, vd, imm, true);
2403 }
2404 }
2405 switch (opc2) {
2406 case 0x0:
2407 if (opc3 == 1) {
2408 if (single) {
2409 return decodeVfpRegRegOp<VmovRegS>(
2410 machInst, vd, vm, false);
2411 } else {
2412 return decodeVfpRegRegOp<VmovRegD>(
2413 machInst, vd, vm, true);
2414 }
2415 } else {
2416 if (single) {
2417 return decodeVfpRegRegOp<VabsS>(
2418 machInst, vd, vm, false);
2419 } else {
2420 return decodeVfpRegRegOp<VabsD>(
2421 machInst, vd, vm, true);
2422 }
2423 }
2424 case 0x1:
2425 if (opc3 == 1) {
2426 if (single) {
2427 return decodeVfpRegRegOp<VnegS>(
2428 machInst, vd, vm, false);
2429 } else {
2430 return decodeVfpRegRegOp<VnegD>(
2431 machInst, vd, vm, true);
2432 }
2433 } else {
2434 if (single) {
2435 return decodeVfpRegRegOp<VsqrtS>(
2436 machInst, vd, vm, false);
2437 } else {
2438 return decodeVfpRegRegOp<VsqrtD>(
2439 machInst, vd, vm, true);
2440 }
2441 }
2442 case 0x2:
2443 case 0x3:
2444 {
2445 const bool toHalf = bits(machInst, 16);
2446 const bool top = bits(machInst, 7);
2447 if (top) {
2448 if (toHalf) {
2449 return new VcvtFpSFpHT(machInst, vd, vm);
2450 } else {
2451 return new VcvtFpHTFpS(machInst, vd, vm);
2452 }
2453 } else {
2454 if (toHalf) {
2455 return new VcvtFpSFpHB(machInst, vd, vm);
2456 } else {
2457 return new VcvtFpHBFpS(machInst, vd, vm);
2458 }
2459 }
2460 }
2461 case 0x4:
2462 if (single) {
2463 if (e) {
2464 return new VcmpeS(machInst, vd, vm);
2465 } else {
2466 return new VcmpS(machInst, vd, vm);
2467 }
2468 } else {
2469 if (e) {
2470 return new VcmpeD(machInst, vd, vm);
2471 } else {
2472 return new VcmpD(machInst, vd, vm);
2473 }
2474 }
2475 case 0x5:
2476 if (single) {
2477 if (e) {
2478 return new VcmpeZeroS(machInst, vd, 0);
2479 } else {
2480 return new VcmpZeroS(machInst, vd, 0);
2481 }
2482 } else {
2483 if (e) {
2484 return new VcmpeZeroD(machInst, vd, 0);
2485 } else {
2486 return new VcmpZeroD(machInst, vd, 0);
2487 }
2488 }
2489 case 0x7:
2490 if (opc3 == 0x3) {
2491 if (single) {
2492 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2493 (bits(machInst, 15, 12) << 1));
2494 return new VcvtFpSFpD(machInst, vd, vm);
2495 } else {
2496 vd = (IntRegIndex)(bits(machInst, 22) |
2497 (bits(machInst, 15, 12) << 1));
2498 return new VcvtFpDFpS(machInst, vd, vm);
2499 }
2500 }
2501 break;
2502 case 0x8:
2503 if (bits(machInst, 7) == 0) {
2504 if (single) {
2505 return new VcvtUIntFpS(machInst, vd, vm);
2506 } else {
2507 vm = (IntRegIndex)(bits(machInst, 5) |
2508 (bits(machInst, 3, 0) << 1));
2509 return new VcvtUIntFpD(machInst, vd, vm);
2510 }
2511 } else {
2512 if (single) {
2513 return new VcvtSIntFpS(machInst, vd, vm);
2514 } else {
2515 vm = (IntRegIndex)(bits(machInst, 5) |
2516 (bits(machInst, 3, 0) << 1));
2517 return new VcvtSIntFpD(machInst, vd, vm);
2518 }
2519 }
2520 case 0xa:
2521 {
2522 const bool half = (bits(machInst, 7) == 0);
2523 const uint32_t imm = bits(machInst, 5) |
2524 (bits(machInst, 3, 0) << 1);
2525 const uint32_t size =
2526 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2527 if (single) {
2528 if (half) {
2529 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2530 } else {
2531 return new VcvtSFixedFpS(machInst, vd, vd, size);
2532 }
2533 } else {
2534 if (half) {
2535 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2536 } else {
2537 return new VcvtSFixedFpD(machInst, vd, vd, size);
2538 }
2539 }
2540 }
2541 case 0xb:
2542 {
2543 const bool half = (bits(machInst, 7) == 0);
2544 const uint32_t imm = bits(machInst, 5) |
2545 (bits(machInst, 3, 0) << 1);
2546 const uint32_t size =
2547 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2548 if (single) {
2549 if (half) {
2550 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2551 } else {
2552 return new VcvtUFixedFpS(machInst, vd, vd, size);
2553 }
2554 } else {
2555 if (half) {
2556 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2557 } else {
2558 return new VcvtUFixedFpD(machInst, vd, vd, size);
2559 }
2560 }
2561 }
2562 case 0xc:
2563 if (bits(machInst, 7) == 0) {
2564 if (single) {
2565 return new VcvtFpUIntSR(machInst, vd, vm);
2566 } else {
2567 vd = (IntRegIndex)(bits(machInst, 22) |
2568 (bits(machInst, 15, 12) << 1));
2569 return new VcvtFpUIntDR(machInst, vd, vm);
2570 }
2571 } else {
2572 if (single) {
2573 return new VcvtFpUIntS(machInst, vd, vm);
2574 } else {
2575 vd = (IntRegIndex)(bits(machInst, 22) |
2576 (bits(machInst, 15, 12) << 1));
2577 return new VcvtFpUIntD(machInst, vd, vm);
2578 }
2579 }
2580 case 0xd:
2581 if (bits(machInst, 7) == 0) {
2582 if (single) {
2583 return new VcvtFpSIntSR(machInst, vd, vm);
2584 } else {
2585 vd = (IntRegIndex)(bits(machInst, 22) |
2586 (bits(machInst, 15, 12) << 1));
2587 return new VcvtFpSIntDR(machInst, vd, vm);
2588 }
2589 } else {
2590 if (single) {
2591 return new VcvtFpSIntS(machInst, vd, vm);
2592 } else {
2593 vd = (IntRegIndex)(bits(machInst, 22) |
2594 (bits(machInst, 15, 12) << 1));
2595 return new VcvtFpSIntD(machInst, vd, vm);
2596 }
2597 }
2598 case 0xe:
2599 {
2600 const bool half = (bits(machInst, 7) == 0);
2601 const uint32_t imm = bits(machInst, 5) |
2602 (bits(machInst, 3, 0) << 1);
2603 const uint32_t size =
2604 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2605 if (single) {
2606 if (half) {
2607 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2608 } else {
2609 return new VcvtFpSFixedS(machInst, vd, vd, size);
2610 }
2611 } else {
2612 if (half) {
2613 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2614 } else {
2615 return new VcvtFpSFixedD(machInst, vd, vd, size);
2616 }
2617 }
2618 }
2619 case 0xf:
2620 {
2621 const bool half = (bits(machInst, 7) == 0);
2622 const uint32_t imm = bits(machInst, 5) |
2623 (bits(machInst, 3, 0) << 1);
2624 const uint32_t size =
2625 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2626 if (single) {
2627 if (half) {
2628 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2629 } else {
2630 return new VcvtFpUFixedS(machInst, vd, vd, size);
2631 }
2632 } else {
2633 if (half) {
2634 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2635 } else {
2636 return new VcvtFpUFixedD(machInst, vd, vd, size);
2637 }
2638 }
2639 }
2640 }
2641 break;
2642 }
2643 return new Unknown(machInst);
2644 }
2645 '''
2646}};
2647
2648def format VfpData() {{
2649 decode_block = '''
2650 return decodeVfpData(machInst);
2651 '''
2652}};