fp.isa (13979:1e0c4607ac12) fp.isa (14043:2cbe8d275b08)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011, 2016-2019 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 M5_FALLTHROUGH;
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 opc = bits(machInst, 11, 8);
345 const bool o1 = bits(machInst, 4);
346 const uint32_t size = 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 bool q = bits(machInst, 6);
357 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
358 return new Unknown(machInst);
359 switch (opc) {
360 case 0x0:
361 if (o1) {
362 if (u) {
363 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
364 q, size, machInst, vd, vn, vm);
365 } else {
366 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
367 q, size, machInst, vd, vn, vm);
368 }
369 } else {
370 if (size == 3)
371 return new Unknown(machInst);
372 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
373 q, u, size, machInst, vd, vn, vm);
374 }
375 case 0x1:
376 if (!o1) {
377 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
378 q, u, size, machInst, vd, vn, vm);
379 } else {
380 if (u) {
381 switch (size) {
382 case 0:
383 if (q) {
384 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
385 } else {
386 return new VeorD<uint64_t>(machInst, vd, vn, vm);
387 }
388 case 1:
389 if (q) {
390 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
391 } else {
392 return new VbslD<uint64_t>(machInst, vd, vn, vm);
393 }
394 case 2:
395 if (q) {
396 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
397 } else {
398 return new VbitD<uint64_t>(machInst, vd, vn, vm);
399 }
400 case 3:
401 if (q) {
402 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
403 } else {
404 return new VbifD<uint64_t>(machInst, vd, vn, vm);
405 }
406 default:
407 M5_UNREACHABLE;
408 }
409 } else {
410 switch (size) {
411 case 0:
412 if (q) {
413 return new VandQ<uint64_t>(machInst, vd, vn, vm);
414 } else {
415 return new VandD<uint64_t>(machInst, vd, vn, vm);
416 }
417 case 1:
418 if (q) {
419 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
420 } else {
421 return new VbicD<uint64_t>(machInst, vd, vn, vm);
422 }
423 case 2:
424 if (vn == vm) {
425 if (q) {
426 return new VmovQ<uint64_t>(
427 machInst, vd, vn, vm);
428 } else {
429 return new VmovD<uint64_t>(
430 machInst, vd, vn, vm);
431 }
432 } else {
433 if (q) {
434 return new VorrQ<uint64_t>(
435 machInst, vd, vn, vm);
436 } else {
437 return new VorrD<uint64_t>(
438 machInst, vd, vn, vm);
439 }
440 }
441 case 3:
442 if (q) {
443 return new VornQ<uint64_t>(
444 machInst, vd, vn, vm);
445 } else {
446 return new VornD<uint64_t>(
447 machInst, vd, vn, vm);
448 }
449 default:
450 M5_UNREACHABLE;
451 }
452 }
453 }
454 case 0x2:
455 if (o1) {
456 if (u) {
457 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
458 q, size, machInst, vd, vn, vm);
459 } else {
460 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
461 q, size, machInst, vd, vn, vm);
462 }
463 } else {
464 if (size == 3)
465 return new Unknown(machInst);
466 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
467 q, u, size, machInst, vd, vn, vm);
468 }
469 case 0x3:
470 if (o1) {
471 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
472 q, u, size, machInst, vd, vn, vm);
473 } else {
474 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
475 q, u, size, machInst, vd, vn, vm);
476 }
477 case 0x4:
478 if (o1) {
479 if (u) {
480 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
481 q, size, machInst, vd, vm, vn);
482 } else {
483 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
484 q, size, machInst, vd, vm, vn);
485 }
486 } else {
487 return decodeNeonUSThreeReg<VshlD, VshlQ>(
488 q, u, size, machInst, vd, vm, vn);
489 }
490 case 0x5:
491 if (o1) {
492 if (u) {
493 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
494 q, size, machInst, vd, vm, vn);
495 } else {
496 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
497 q, size, machInst, vd, vm, vn);
498 }
499 } else {
500 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
501 q, u, size, machInst, vd, vm, vn);
502 }
503 case 0x6:
504 if (o1) {
505 return decodeNeonUSThreeReg<VminD, VminQ>(
506 q, u, size, machInst, vd, vn, vm);
507 } else {
508 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
509 q, u, size, machInst, vd, vn, vm);
510 }
511 case 0x7:
512 if (o1) {
513 return decodeNeonUSThreeReg<VabaD, VabaQ>(
514 q, u, size, machInst, vd, vn, vm);
515 } else {
516 if (bits(machInst, 23) == 1) {
517 if (q) {
518 return new Unknown(machInst);
519 } else {
520 return decodeNeonUSThreeUSReg<Vabdl>(
521 u, size, machInst, vd, vn, vm);
522 }
523 } else {
524 return decodeNeonUSThreeReg<VabdD, VabdQ>(
525 q, u, size, machInst, vd, vn, vm);
526 }
527 }
528 case 0x8:
529 if (o1) {
530 if (u) {
531 return decodeNeonUThreeReg<VceqD, VceqQ>(
532 q, size, machInst, vd, vn, vm);
533 } else {
534 return decodeNeonUThreeReg<VtstD, VtstQ>(
535 q, size, machInst, vd, vn, vm);
536 }
537 } else {
538 if (u) {
539 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
540 q, size, machInst, vd, vn, vm);
541 } else {
542 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
543 q, size, machInst, vd, vn, vm);
544 }
545 }
546 case 0x9:
547 if (o1) {
548 if (u) {
549 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
550 q, size, machInst, vd, vn, vm);
551 } else {
552 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
553 q, size, machInst, vd, vn, vm);
554 }
555 } else {
556 if (u) {
557 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
558 q, u, size, machInst, vd, vn, vm);
559 } else {
560 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
561 q, u, size, machInst, vd, vn, vm);
562 }
563 }
564 case 0xa:
565 if (q)
566 return new Unknown(machInst);
567 if (o1) {
568 return decodeNeonUSThreeUSReg<VpminD>(
569 u, size, machInst, vd, vn, vm);
570 } else {
571 return decodeNeonUSThreeUSReg<VpmaxD>(
572 u, size, machInst, vd, vn, vm);
573 }
574 case 0xb:
575 if (o1) {
576 if (u || q) {
577 return new Unknown(machInst);
578 } else {
579 return decodeNeonUThreeUSReg<NVpaddD>(
580 size, machInst, vd, vn, vm);
581 }
582 } else {
583 if (u) {
584 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
585 q, size, machInst, vd, vn, vm);
586 } else {
587 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
588 q, size, machInst, vd, vn, vm);
589 }
590 }
591 case 0xc:
592 if (o1) {
593 if (!u) {
594 if (bits(size, 1) == 0) {
595 if (q) {
596 return new NVfmaQFp<float>(machInst, vd, vn, vm);
597 } else {
598 return new NVfmaDFp<float>(machInst, vd, vn, vm);
599 }
600 } else {
601 if (q) {
602 return new NVfmsQFp<float>(machInst, vd, vn, vm);
603 } else {
604 return new NVfmsDFp<float>(machInst, vd, vn, vm);
605 }
606 }
607 }
608 } else {
609 if (u) {
610 switch (size) {
611 case 0x0:
612 return new SHA256H(machInst, vd, vn, vm);
613 case 0x1:
614 return new SHA256H2(machInst, vd, vn, vm);
615 case 0x2:
616 return new SHA256SU1(machInst, vd, vn, vm);
617 case 0x3:
618 return new Unknown(machInst);
619 default:
620 M5_UNREACHABLE;
621 }
622 } else {
623 switch (size) {
624 case 0x0:
625 return new SHA1C(machInst, vd, vn, vm);
626 case 0x1:
627 return new SHA1P(machInst, vd, vn, vm);
628 case 0x2:
629 return new SHA1M(machInst, vd, vn, vm);
630 case 0x3:
631 return new SHA1SU0(machInst, vd, vn, vm);
632 default:
633 M5_UNREACHABLE;
634 }
635 }
636 }
637 return new Unknown(machInst);
638 case 0xd:
639 if (o1) {
640 if (u) {
641 if (bits(size, 1) == 0) {
642 if (q) {
643 return new NVmulQFp<float>(machInst, vd, vn, vm);
644 } else {
645 return new NVmulDFp<float>(machInst, vd, vn, vm);
646 }
647 } else {
648 return new Unknown(machInst);
649 }
650 } else {
651 if (bits(size, 1) == 0) {
652 if (q) {
653 return new NVmlaQFp<float>(machInst, vd, vn, vm);
654 } else {
655 return new NVmlaDFp<float>(machInst, vd, vn, vm);
656 }
657 } else {
658 if (q) {
659 return new NVmlsQFp<float>(machInst, vd, vn, vm);
660 } else {
661 return new NVmlsDFp<float>(machInst, vd, vn, vm);
662 }
663 }
664 }
665 } else {
666 if (u) {
667 if (bits(size, 1) == 0) {
668 if (q) {
669 return new VpaddQFp<float>(machInst, vd, vn, vm);
670 } else {
671 return new VpaddDFp<float>(machInst, vd, vn, vm);
672 }
673 } else {
674 if (q) {
675 return new VabdQFp<float>(machInst, vd, vn, vm);
676 } else {
677 return new VabdDFp<float>(machInst, vd, vn, vm);
678 }
679 }
680 } else {
681 if (bits(size, 1) == 0) {
682 if (q) {
683 return new VaddQFp<float>(machInst, vd, vn, vm);
684 } else {
685 return new VaddDFp<float>(machInst, vd, vn, vm);
686 }
687 } else {
688 if (q) {
689 return new VsubQFp<float>(machInst, vd, vn, vm);
690 } else {
691 return new VsubDFp<float>(machInst, vd, vn, vm);
692 }
693 }
694 }
695 }
696 case 0xe:
697 if (o1) {
698 if (u) {
699 if (bits(size, 1) == 0) {
700 if (q) {
701 return new VacgeQFp<float>(machInst, vd, vn, vm);
702 } else {
703 return new VacgeDFp<float>(machInst, vd, vn, vm);
704 }
705 } else {
706 if (q) {
707 return new VacgtQFp<float>(machInst, vd, vn, vm);
708 } else {
709 return new VacgtDFp<float>(machInst, vd, vn, vm);
710 }
711 }
712 } else {
713 return new Unknown(machInst);
714 }
715 } else {
716 if (u) {
717 if (bits(size, 1) == 0) {
718 if (q) {
719 return new VcgeQFp<float>(machInst, vd, vn, vm);
720 } else {
721 return new VcgeDFp<float>(machInst, vd, vn, vm);
722 }
723 } else {
724 if (q) {
725 return new VcgtQFp<float>(machInst, vd, vn, vm);
726 } else {
727 return new VcgtDFp<float>(machInst, vd, vn, vm);
728 }
729 }
730 } else {
731 if (bits(size, 1) == 0) {
732 if (q) {
733 return new VceqQFp<float>(machInst, vd, vn, vm);
734 } else {
735 return new VceqDFp<float>(machInst, vd, vn, vm);
736 }
737 } else {
738 return new Unknown(machInst);
739 }
740 }
741 }
742 case 0xf:
743 if (o1) {
744 if (u) {
745 if (bits(size, 1) == 0) {
746 if (q) {
747 return new VmaxnmQFp<uint32_t>(
748 machInst, vd, vn, vm);
749 } else {
750 return new VmaxnmDFp<uint32_t>(
751 machInst, vd, vn, vm);
752 }
753 } else {
754 if (q) {
755 return new VminnmQFp<uint32_t>(
756 machInst, vd, vn, vm);
757 } else {
758 return new VminnmDFp<uint32_t>(
759 machInst, vd, vn, vm);
760 }
761 }
762 } else {
763 if (bits(size, 1) == 0) {
764 if (q) {
765 return new VrecpsQFp<float>(machInst, vd, vn, vm);
766 } else {
767 return new VrecpsDFp<float>(machInst, vd, vn, vm);
768 }
769 } else {
770 if (q) {
771 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
772 } else {
773 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
774 }
775 }
776 }
777 } else {
778 if (u) {
779 if (bits(size, 1) == 0) {
780 if (q) {
781 return new VpmaxQFp<uint32_t>(
782 machInst, vd, vn, vm);
783 } else {
784 return new VpmaxDFp<uint32_t>(
785 machInst, vd, vn, vm);
786 }
787 } else {
788 if (q) {
789 return new VpminQFp<uint32_t>(
790 machInst, vd, vn, vm);
791 } else {
792 return new VpminDFp<uint32_t>(
793 machInst, vd, vn, vm);
794 }
795 }
796 } else {
797 if (bits(size, 1) == 0) {
798 if (q) {
799 return new VmaxQFp<uint32_t>(
800 machInst, vd, vn, vm);
801 } else {
802 return new VmaxDFp<uint32_t>(
803 machInst, vd, vn, vm);
804 }
805 } else {
806 if (q) {
807 return new VminQFp<uint32_t>(
808 machInst, vd, vn, vm);
809 } else {
810 return new VminDFp<uint32_t>(
811 machInst, vd, vn, vm);
812 }
813 }
814 }
815 }
816 }
817 return new Unknown(machInst);
818 }
819
820 static StaticInstPtr
821 decodeNeonOneRegModImm(ExtMachInst machInst)
822 {
823 const IntRegIndex vd =
824 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
825 (bits(machInst, 22) << 4)));
826 const bool q = bits(machInst, 6);
827 const bool op = bits(machInst, 5);
828 const uint8_t cmode = bits(machInst, 11, 8);
829 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
830 bits(machInst, 24)) << 7) |
831 (bits(machInst, 18, 16) << 4) |
832 (bits(machInst, 3, 0) << 0);
833
834 // Check for invalid immediate encodings and return an unknown op
835 // if it happens
836 bool immValid = true;
837 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
838 if (!immValid) {
839 return new Unknown(machInst);
840 }
841
842 if (op) {
843 if (bits(cmode, 3) == 0) {
844 if (bits(cmode, 0) == 0) {
845 if (q)
846 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
847 else
848 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
849 } else {
850 if (q)
851 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
852 else
853 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
854 }
855 } else {
856 if (bits(cmode, 2) == 1) {
857 switch (bits(cmode, 1, 0)) {
858 case 0:
859 case 1:
860 if (q)
861 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
862 else
863 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
864 case 2:
865 if (q)
866 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
867 else
868 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
869 case 3:
870 if (q)
871 return new Unknown(machInst);
872 else
873 return new Unknown(machInst);
874 }
875 } else {
876 if (bits(cmode, 0) == 0) {
877 if (q)
878 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
879 else
880 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
881 } else {
882 if (q)
883 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
884 else
885 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
886 }
887 }
888 }
889 } else {
890 if (bits(cmode, 3) == 0) {
891 if (bits(cmode, 0) == 0) {
892 if (q)
893 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
894 else
895 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
896 } else {
897 if (q)
898 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
899 else
900 return new NVorriD<uint64_t>(machInst, vd, bigImm);
901 }
902 } else {
903 if (bits(cmode, 2) == 1) {
904 if (q)
905 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
906 else
907 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
908 } else {
909 if (bits(cmode, 0) == 0) {
910 if (q)
911 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
912 else
913 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
914 } else {
915 if (q)
916 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
917 else
918 return new NVorriD<uint64_t>(machInst, vd, bigImm);
919 }
920 }
921 }
922 }
923 return new Unknown(machInst);
924 }
925
926 static StaticInstPtr
927 decodeNeonTwoRegAndShift(ExtMachInst machInst)
928 {
929 const uint32_t opc = bits(machInst, 11, 8);
930 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
931 const bool q = bits(machInst, 6);
932 const bool l = bits(machInst, 7);
933 const IntRegIndex vd =
934 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
935 (bits(machInst, 22) << 4)));
936 const IntRegIndex vm =
937 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
938 (bits(machInst, 5) << 4)));
939 unsigned imm6 = bits(machInst, 21, 16);
940 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
941 unsigned size = 3;
942 unsigned lShiftAmt = 0;
943 unsigned bitSel;
944 for (bitSel = 1 << 6; true; bitSel >>= 1) {
945 if (bitSel & imm)
946 break;
947 else if (!size)
948 return new Unknown(machInst);
949 size--;
950 }
951 lShiftAmt = imm6 & ~bitSel;
952 unsigned rShiftAmt = 0;
953 if (opc != 0xe && opc != 0xf) {
954 if (size > 2)
955 rShiftAmt = 64 - imm6;
956 else
957 rShiftAmt = 2 * (8 << size) - imm6;
958 }
959
960 switch (opc) {
961 case 0x0:
962 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
963 q, u, size, machInst, vd, vm, rShiftAmt);
964 case 0x1:
965 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
966 q, u, size, machInst, vd, vm, rShiftAmt);
967 case 0x2:
968 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
969 q, u, size, machInst, vd, vm, rShiftAmt);
970 case 0x3:
971 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
972 q, u, size, machInst, vd, vm, rShiftAmt);
973 case 0x4:
974 if (u) {
975 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
976 q, size, machInst, vd, vm, rShiftAmt);
977 } else {
978 return new Unknown(machInst);
979 }
980 case 0x5:
981 if (u) {
982 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
983 q, size, machInst, vd, vm, lShiftAmt);
984 } else {
985 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
986 q, size, machInst, vd, vm, lShiftAmt);
987 }
988 case 0x6:
989 case 0x7:
990 if (u) {
991 if (opc == 0x6) {
992 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
993 q, size, machInst, vd, vm, lShiftAmt);
994 } else {
995 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
996 q, size, machInst, vd, vm, lShiftAmt);
997 }
998 } else {
999 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
1000 q, size, machInst, vd, vm, lShiftAmt);
1001 }
1002 case 0x8:
1003 if (l) {
1004 return new Unknown(machInst);
1005 } else if (u) {
1006 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
1007 q, size, machInst, vd, vm, rShiftAmt);
1008 } else {
1009 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
1010 q, size, machInst, vd, vm, rShiftAmt);
1011 }
1012 case 0x9:
1013 if (l) {
1014 return new Unknown(machInst);
1015 } else if (u) {
1016 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
1017 q, size, machInst, vd, vm, rShiftAmt);
1018 } else {
1019 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
1020 q, size, machInst, vd, vm, rShiftAmt);
1021 }
1022 case 0xa:
1023 if (l || q) {
1024 return new Unknown(machInst);
1025 } else {
1026 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
1027 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
1028 }
1029 case 0xe:
1030 if (l) {
1031 return new Unknown(machInst);
1032 } else {
1033 if (bits(imm6, 5) == 0)
1034 return new Unknown(machInst);
1035 if (u) {
1036 if (q) {
1037 return new NVcvtu2fpQ<float>(
1038 machInst, vd, vm, 64 - imm6);
1039 } else {
1040 return new NVcvtu2fpD<float>(
1041 machInst, vd, vm, 64 - imm6);
1042 }
1043 } else {
1044 if (q) {
1045 return new NVcvts2fpQ<float>(
1046 machInst, vd, vm, 64 - imm6);
1047 } else {
1048 return new NVcvts2fpD<float>(
1049 machInst, vd, vm, 64 - imm6);
1050 }
1051 }
1052 }
1053 case 0xf:
1054 if (l) {
1055 return new Unknown(machInst);
1056 } else {
1057 if (bits(imm6, 5) == 0)
1058 return new Unknown(machInst);
1059 if (u) {
1060 if (q) {
1061 return new NVcvt2ufxQ<float>(
1062 machInst, vd, vm, 64 - imm6);
1063 } else {
1064 return new NVcvt2ufxD<float>(
1065 machInst, vd, vm, 64 - imm6);
1066 }
1067 } else {
1068 if (q) {
1069 return new NVcvt2sfxQ<float>(
1070 machInst, vd, vm, 64 - imm6);
1071 } else {
1072 return new NVcvt2sfxD<float>(
1073 machInst, vd, vm, 64 - imm6);
1074 }
1075 }
1076 }
1077 }
1078 return new Unknown(machInst);
1079 }
1080
1081 static StaticInstPtr
1082 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1083 {
1084 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1085 const uint32_t opc = bits(machInst, 11, 8);
1086 const IntRegIndex vd =
1087 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1088 (bits(machInst, 22) << 4)));
1089 const IntRegIndex vn =
1090 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1091 (bits(machInst, 7) << 4)));
1092 const IntRegIndex vm =
1093 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1094 (bits(machInst, 5) << 4)));
1095 const unsigned size = bits(machInst, 21, 20);
1096 switch (opc) {
1097 case 0x0:
1098 return decodeNeonUSThreeUSReg<Vaddl>(
1099 u, size, machInst, vd, vn, vm);
1100 case 0x1:
1101 return decodeNeonUSThreeUSReg<Vaddw>(
1102 u, size, machInst, vd, vn, vm);
1103 case 0x2:
1104 return decodeNeonUSThreeUSReg<Vsubl>(
1105 u, size, machInst, vd, vn, vm);
1106 case 0x3:
1107 return decodeNeonUSThreeUSReg<Vsubw>(
1108 u, size, machInst, vd, vn, vm);
1109 case 0x4:
1110 if (u) {
1111 return decodeNeonUThreeUSReg<Vraddhn>(
1112 size, machInst, vd, vn, vm);
1113 } else {
1114 return decodeNeonUThreeUSReg<Vaddhn>(
1115 size, machInst, vd, vn, vm);
1116 }
1117 case 0x5:
1118 return decodeNeonUSThreeUSReg<Vabal>(
1119 u, size, machInst, vd, vn, vm);
1120 case 0x6:
1121 if (u) {
1122 return decodeNeonUThreeUSReg<Vrsubhn>(
1123 size, machInst, vd, vn, vm);
1124 } else {
1125 return decodeNeonUThreeUSReg<Vsubhn>(
1126 size, machInst, vd, vn, vm);
1127 }
1128 case 0x7:
1129 if (bits(machInst, 23)) {
1130 return decodeNeonUSThreeUSReg<Vabdl>(
1131 u, size, machInst, vd, vn, vm);
1132 } else {
1133 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1134 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1135 }
1136 case 0x8:
1137 return decodeNeonUSThreeUSReg<Vmlal>(
1138 u, size, machInst, vd, vn, vm);
1139 case 0xa:
1140 return decodeNeonUSThreeUSReg<Vmlsl>(
1141 u, size, machInst, vd, vn, vm);
1142 case 0x9:
1143 if (u) {
1144 return new Unknown(machInst);
1145 } else {
1146 return decodeNeonSThreeUSReg<Vqdmlal>(
1147 size, machInst, vd, vn, vm);
1148 }
1149 case 0xb:
1150 if (u) {
1151 return new Unknown(machInst);
1152 } else {
1153 return decodeNeonSThreeUSReg<Vqdmlsl>(
1154 size, machInst, vd, vn, vm);
1155 }
1156 case 0xc:
1157 return decodeNeonUSThreeUSReg<Vmull>(
1158 u, size, machInst, vd, vn, vm);
1159 case 0xd:
1160 if (u) {
1161 return new Unknown(machInst);
1162 } else {
1163 return decodeNeonSThreeUSReg<Vqdmull>(
1164 size, machInst, vd, vn, vm);
1165 }
1166 case 0xe:
1167 return decodeNeonUThreeUSReg<Vmullp>(
1168 size, machInst, vd, vn, vm);
1169 }
1170 return new Unknown(machInst);
1171 }
1172
1173 static StaticInstPtr
1174 decodeNeonTwoRegScalar(ExtMachInst machInst)
1175 {
1176 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1177 const uint32_t opc = bits(machInst, 11, 8);
1178 const unsigned size = bits(machInst, 21, 20);
1179 const IntRegIndex vd =
1180 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1181 (bits(machInst, 22) << 4)));
1182 const IntRegIndex vn =
1183 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1184 (bits(machInst, 7) << 4)));
1185 const IntRegIndex vm = (size == 2) ?
1186 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1187 (IntRegIndex)(2 * bits(machInst, 2, 0));
1188 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1189 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1190 switch (opc) {
1191 case 0x0:
1192 if (u) {
1193 switch (size) {
1194 case 1:
1195 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1196 case 2:
1197 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1198 default:
1199 return new Unknown(machInst);
1200 }
1201 } else {
1202 switch (size) {
1203 case 1:
1204 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1205 case 2:
1206 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1207 default:
1208 return new Unknown(machInst);
1209 }
1210 }
1211 case 0x1:
1212 if (u)
1213 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1214 else
1215 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1216 case 0x4:
1217 if (u) {
1218 switch (size) {
1219 case 1:
1220 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1221 case 2:
1222 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1223 default:
1224 return new Unknown(machInst);
1225 }
1226 } else {
1227 switch (size) {
1228 case 1:
1229 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1230 case 2:
1231 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1232 default:
1233 return new Unknown(machInst);
1234 }
1235 }
1236 case 0x5:
1237 if (u)
1238 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1239 else
1240 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1241 case 0x2:
1242 if (u) {
1243 switch (size) {
1244 case 1:
1245 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1246 case 2:
1247 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1248 default:
1249 return new Unknown(machInst);
1250 }
1251 } else {
1252 switch (size) {
1253 case 1:
1254 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1255 case 2:
1256 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1257 default:
1258 return new Unknown(machInst);
1259 }
1260 }
1261 case 0x6:
1262 if (u) {
1263 switch (size) {
1264 case 1:
1265 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1266 case 2:
1267 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1268 default:
1269 return new Unknown(machInst);
1270 }
1271 } else {
1272 switch (size) {
1273 case 1:
1274 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1275 case 2:
1276 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1277 default:
1278 return new Unknown(machInst);
1279 }
1280 }
1281 case 0x3:
1282 if (u) {
1283 return new Unknown(machInst);
1284 } else {
1285 switch (size) {
1286 case 1:
1287 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1288 case 2:
1289 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1290 default:
1291 return new Unknown(machInst);
1292 }
1293 }
1294 case 0x7:
1295 if (u) {
1296 return new Unknown(machInst);
1297 } else {
1298 switch (size) {
1299 case 1:
1300 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1301 case 2:
1302 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1303 default:
1304 return new Unknown(machInst);
1305 }
1306 }
1307 case 0x8:
1308 if (u) {
1309 switch (size) {
1310 case 1:
1311 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1312 case 2:
1313 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1314 default:
1315 return new Unknown(machInst);
1316 }
1317 } else {
1318 switch (size) {
1319 case 1:
1320 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1321 case 2:
1322 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1323 default:
1324 return new Unknown(machInst);
1325 }
1326 }
1327 case 0x9:
1328 if (u)
1329 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1330 else
1331 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1332 case 0xa:
1333 if (u) {
1334 switch (size) {
1335 case 1:
1336 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1337 case 2:
1338 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1339 default:
1340 return new Unknown(machInst);
1341 }
1342 } else {
1343 switch (size) {
1344 case 1:
1345 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1346 case 2:
1347 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1348 default:
1349 return new Unknown(machInst);
1350 }
1351 }
1352 case 0xb:
1353 if (u) {
1354 return new Unknown(machInst);
1355 } else {
1356 if (u) {
1357 switch (size) {
1358 case 1:
1359 return new Vqdmulls<uint16_t>(
1360 machInst, vd, vn, vm, index);
1361 case 2:
1362 return new Vqdmulls<uint32_t>(
1363 machInst, vd, vn, vm, index);
1364 default:
1365 return new Unknown(machInst);
1366 }
1367 } else {
1368 switch (size) {
1369 case 1:
1370 return new Vqdmulls<int16_t>(
1371 machInst, vd, vn, vm, index);
1372 case 2:
1373 return new Vqdmulls<int32_t>(
1374 machInst, vd, vn, vm, index);
1375 default:
1376 return new Unknown(machInst);
1377 }
1378 }
1379 }
1380 case 0xc:
1381 if (u) {
1382 switch (size) {
1383 case 1:
1384 return new VqdmulhsQ<int16_t>(
1385 machInst, vd, vn, vm, index);
1386 case 2:
1387 return new VqdmulhsQ<int32_t>(
1388 machInst, vd, vn, vm, index);
1389 default:
1390 return new Unknown(machInst);
1391 }
1392 } else {
1393 switch (size) {
1394 case 1:
1395 return new VqdmulhsD<int16_t>(
1396 machInst, vd, vn, vm, index);
1397 case 2:
1398 return new VqdmulhsD<int32_t>(
1399 machInst, vd, vn, vm, index);
1400 default:
1401 return new Unknown(machInst);
1402 }
1403 }
1404 case 0xd:
1405 if (u) {
1406 switch (size) {
1407 case 1:
1408 return new VqrdmulhsQ<int16_t>(
1409 machInst, vd, vn, vm, index);
1410 case 2:
1411 return new VqrdmulhsQ<int32_t>(
1412 machInst, vd, vn, vm, index);
1413 default:
1414 return new Unknown(machInst);
1415 }
1416 } else {
1417 switch (size) {
1418 case 1:
1419 return new VqrdmulhsD<int16_t>(
1420 machInst, vd, vn, vm, index);
1421 case 2:
1422 return new VqrdmulhsD<int32_t>(
1423 machInst, vd, vn, vm, index);
1424 default:
1425 return new Unknown(machInst);
1426 }
1427 }
1428 }
1429 return new Unknown(machInst);
1430 }
1431
1432 static StaticInstPtr
1433 decodeNeonTwoRegMisc(ExtMachInst machInst)
1434 {
1435 const uint32_t opc1 = bits(machInst, 17, 16);
1436 const uint32_t b = bits(machInst, 10, 6);
1437 const bool q = bits(machInst, 6);
1438 const IntRegIndex vd =
1439 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1440 (bits(machInst, 22) << 4)));
1441 const IntRegIndex vm =
1442 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1443 (bits(machInst, 5) << 4)));
1444 const unsigned size = bits(machInst, 19, 18);
1445 switch (opc1) {
1446 case 0x0:
1447 switch (bits(b, 4, 1)) {
1448 case 0x0:
1449 switch (size) {
1450 case 0:
1451 if (q) {
1452 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1453 } else {
1454 return new NVrev64D<uint8_t>(machInst, vd, vm);
1455 }
1456 case 1:
1457 if (q) {
1458 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1459 } else {
1460 return new NVrev64D<uint16_t>(machInst, vd, vm);
1461 }
1462 case 2:
1463 if (q) {
1464 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1465 } else {
1466 return new NVrev64D<uint32_t>(machInst, vd, vm);
1467 }
1468 default:
1469 return new Unknown(machInst);
1470 }
1471 case 0x1:
1472 switch (size) {
1473 case 0:
1474 if (q) {
1475 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1476 } else {
1477 return new NVrev32D<uint8_t>(machInst, vd, vm);
1478 }
1479 case 1:
1480 if (q) {
1481 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1482 } else {
1483 return new NVrev32D<uint16_t>(machInst, vd, vm);
1484 }
1485 default:
1486 return new Unknown(machInst);
1487 }
1488 case 0x2:
1489 if (size != 0) {
1490 return new Unknown(machInst);
1491 } else if (q) {
1492 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1493 } else {
1494 return new NVrev16D<uint8_t>(machInst, vd, vm);
1495 }
1496 case 0x4:
1497 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1498 q, size, machInst, vd, vm);
1499 case 0x5:
1500 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1501 q, size, machInst, vd, vm);
1502 case 0x6:
1503 if (q == 0) {
1504 return new AESE(machInst, vd, vd, vm);
1505 } else {
1506 return new AESD(machInst, vd, vd, vm);
1507 }
1508 case 0x7:
1509 if (q == 0) {
1510 return new AESMC(machInst, vd, vm);
1511 } else {
1512 return new AESIMC(machInst, vd, vm);
1513 }
1514 case 0x8:
1515 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1516 q, size, machInst, vd, vm);
1517 case 0x9:
1518 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1519 q, size, machInst, vd, vm);
1520 case 0xa:
1521 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1522 q, size, machInst, vd, vm);
1523 case 0xb:
1524 if (q)
1525 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1526 else
1527 return new NVmvnD<uint64_t>(machInst, vd, vm);
1528 case 0xc:
1529 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1530 q, size, machInst, vd, vm);
1531 case 0xd:
1532 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1533 q, size, machInst, vd, vm);
1534 case 0xe:
1535 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1536 q, size, machInst, vd, vm);
1537 case 0xf:
1538 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1539 q, size, machInst, vd, vm);
1540 default:
1541 return new Unknown(machInst);
1542 }
1543 case 0x1:
1544 switch (bits(b, 3, 1)) {
1545 case 0x0:
1546 if (bits(b, 4)) {
1547 if (q) {
1548 return new NVcgtQFp<float>(machInst, vd, vm);
1549 } else {
1550 return new NVcgtDFp<float>(machInst, vd, vm);
1551 }
1552 } else {
1553 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1554 q, size, machInst, vd, vm);
1555 }
1556 case 0x1:
1557 if (bits(b, 4)) {
1558 if (q) {
1559 return new NVcgeQFp<float>(machInst, vd, vm);
1560 } else {
1561 return new NVcgeDFp<float>(machInst, vd, vm);
1562 }
1563 } else {
1564 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1565 q, size, machInst, vd, vm);
1566 }
1567 case 0x2:
1568 if (bits(b, 4)) {
1569 if (q) {
1570 return new NVceqQFp<float>(machInst, vd, vm);
1571 } else {
1572 return new NVceqDFp<float>(machInst, vd, vm);
1573 }
1574 } else {
1575 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1576 q, size, machInst, vd, vm);
1577 }
1578 case 0x3:
1579 if (bits(b, 4)) {
1580 if (q) {
1581 return new NVcleQFp<float>(machInst, vd, vm);
1582 } else {
1583 return new NVcleDFp<float>(machInst, vd, vm);
1584 }
1585 } else {
1586 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1587 q, size, machInst, vd, vm);
1588 }
1589 case 0x4:
1590 if (bits(b, 4)) {
1591 if (q) {
1592 return new NVcltQFp<float>(machInst, vd, vm);
1593 } else {
1594 return new NVcltDFp<float>(machInst, vd, vm);
1595 }
1596 } else {
1597 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1598 q, size, machInst, vd, vm);
1599 }
1600 case 0x5:
1601 if (q) {
1602 return new SHA1H(machInst, vd, vm);
1603 } else {
1604 return new Unknown(machInst);
1605 }
1606 case 0x6:
1607 if (bits(machInst, 10)) {
1608 if (q)
1609 return new NVabsQFp<float>(machInst, vd, vm);
1610 else
1611 return new NVabsDFp<float>(machInst, vd, vm);
1612 } else {
1613 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1614 q, size, machInst, vd, vm);
1615 }
1616 case 0x7:
1617 if (bits(machInst, 10)) {
1618 if (q)
1619 return new NVnegQFp<float>(machInst, vd, vm);
1620 else
1621 return new NVnegDFp<float>(machInst, vd, vm);
1622 } else {
1623 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1624 q, size, machInst, vd, vm);
1625 }
1626 default:
1627 return new Unknown64(machInst);
1628 }
1629 case 0x2:
1630 switch (bits(b, 4, 1)) {
1631 case 0x0:
1632 if (q)
1633 return new NVswpQ<uint64_t>(machInst, vd, vm);
1634 else
1635 return new NVswpD<uint64_t>(machInst, vd, vm);
1636 case 0x1:
1637 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1638 q, size, machInst, vd, vm);
1639 case 0x2:
1640 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1641 q, size, machInst, vd, vm);
1642 case 0x3:
1643 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1644 q, size, machInst, vd, vm);
1645 case 0x4:
1646 if (b == 0x8) {
1647 return decodeNeonUTwoMiscUSReg<NVmovn>(
1648 size, machInst, vd, vm);
1649 } else {
1650 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1651 size, machInst, vd, vm);
1652 }
1653 case 0x5:
1654 if (q) {
1655 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1656 size, machInst, vd, vm);
1657 } else {
1658 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1659 size, machInst, vd, vm);
1660 }
1661 case 0x6:
1662 if (b == 0xc) {
1663 return decodeNeonSTwoShiftUSReg<NVshll>(
1664 size, machInst, vd, vm, 8 << size);
1665 } else {
1666 return new Unknown(machInst);
1667 }
1668 case 0x7:
1669 if (q) {
1670 return new SHA256SU0(machInst, vd, vm);
1671 } else {
1672 return new SHA1SU1(machInst, vd, vm);
1673 }
1674 case 0xc:
1675 case 0xe:
1676 if (b == 0x18) {
1677 if (size != 1 || (vm % 2))
1678 return new Unknown(machInst);
1679 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1680 } else if (b == 0x1c) {
1681 if (size != 1 || (vd % 2))
1682 return new Unknown(machInst);
1683 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1684 } else {
1685 return new Unknown(machInst);
1686 }
1687 default:
1688 return new Unknown(machInst);
1689 }
1690 case 0x3:
1691 if (bits(b, 4, 3) == 0x3) {
1692 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1693 return new Unknown(machInst);
1694 } else {
1695 if (bits(b, 2)) {
1696 if (bits(b, 1)) {
1697 if (q) {
1698 return new NVcvt2ufxQ<float>(
1699 machInst, vd, vm, 0);
1700 } else {
1701 return new NVcvt2ufxD<float>(
1702 machInst, vd, vm, 0);
1703 }
1704 } else {
1705 if (q) {
1706 return new NVcvt2sfxQ<float>(
1707 machInst, vd, vm, 0);
1708 } else {
1709 return new NVcvt2sfxD<float>(
1710 machInst, vd, vm, 0);
1711 }
1712 }
1713 } else {
1714 if (bits(b, 1)) {
1715 if (q) {
1716 return new NVcvtu2fpQ<float>(
1717 machInst, vd, vm, 0);
1718 } else {
1719 return new NVcvtu2fpD<float>(
1720 machInst, vd, vm, 0);
1721 }
1722 } else {
1723 if (q) {
1724 return new NVcvts2fpQ<float>(
1725 machInst, vd, vm, 0);
1726 } else {
1727 return new NVcvts2fpD<float>(
1728 machInst, vd, vm, 0);
1729 }
1730 }
1731 }
1732 }
1733 } else if ((b & 0x1a) == 0x10) {
1734 if (bits(b, 2)) {
1735 if (q) {
1736 return new NVrecpeQFp<float>(machInst, vd, vm);
1737 } else {
1738 return new NVrecpeDFp<float>(machInst, vd, vm);
1739 }
1740 } else {
1741 if (q) {
1742 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1743 } else {
1744 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1745 }
1746 }
1747 } else if ((b & 0x1a) == 0x12) {
1748 if (bits(b, 2)) {
1749 if (q) {
1750 return new NVrsqrteQFp<float>(machInst, vd, vm);
1751 } else {
1752 return new NVrsqrteDFp<float>(machInst, vd, vm);
1753 }
1754 } else {
1755 if (q) {
1756 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1757 } else {
1758 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1759 }
1760 }
1761 } else {
1762 return new Unknown(machInst);
1763 }
1764 }
1765 return new Unknown(machInst);
1766 }
1767
1768 StaticInstPtr
1769 decodeNeonData(ExtMachInst machInst)
1770 {
1771 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1772 const uint32_t a = bits(machInst, 23, 19);
1773 const uint32_t q = bits(machInst, 11, 8);
1774 const uint32_t c = bits(machInst, 7, 4);
1775 if (bits(a, 4) == 0) {
1776 return decodeNeonThreeRegistersSameLength(machInst);
1777 } else if ((c & 0x9) == 1) {
1778 if ((a & 0x7) == 0) {
1779 return decodeNeonOneRegModImm(machInst);
1780 } else {
1781 return decodeNeonTwoRegAndShift(machInst);
1782 }
1783 } else if ((c & 0x9) == 9) {
1784 return decodeNeonTwoRegAndShift(machInst);
1785 } else if (bits(a, 2, 1) != 0x3) {
1786 if ((c & 0x5) == 0) {
1787 return decodeNeonThreeRegDiffLengths(machInst);
1788 } else if ((c & 0x5) == 4) {
1789 return decodeNeonTwoRegScalar(machInst);
1790 }
1791 } else if ((a & 0x16) == 0x16) {
1792 const IntRegIndex vd =
1793 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1794 (bits(machInst, 22) << 4)));
1795 const IntRegIndex vn =
1796 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1797 (bits(machInst, 7) << 4)));
1798 const IntRegIndex vm =
1799 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1800 (bits(machInst, 5) << 4)));
1801 if (!u) {
1802 if (bits(c, 0) == 0) {
1803 unsigned imm4 = bits(machInst, 11, 8);
1804 bool q = bits(machInst, 6);
1805 if (imm4 >= 16 && !q)
1806 return new Unknown(machInst);
1807 if (q) {
1808 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1809 } else {
1810 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1811 }
1812 }
1813 } else if (bits(q, 3) == 0 && bits(c, 0) == 0) {
1814 return decodeNeonTwoRegMisc(machInst);
1815 } else if (bits(q, 3, 2) == 0x2 && bits(c, 0) == 0) {
1816 unsigned length = bits(machInst, 9, 8) + 1;
1817 if ((uint32_t)vn / 2 + length > 32)
1818 return new Unknown(machInst);
1819 if (bits(machInst, 6) == 0) {
1820 switch (length) {
1821 case 1:
1822 return new NVtbl1(machInst, vd, vn, vm);
1823 case 2:
1824 return new NVtbl2(machInst, vd, vn, vm);
1825 case 3:
1826 return new NVtbl3(machInst, vd, vn, vm);
1827 case 4:
1828 return new NVtbl4(machInst, vd, vn, vm);
1829 }
1830 } else {
1831 switch (length) {
1832 case 1:
1833 return new NVtbx1(machInst, vd, vn, vm);
1834 case 2:
1835 return new NVtbx2(machInst, vd, vn, vm);
1836 case 3:
1837 return new NVtbx3(machInst, vd, vn, vm);
1838 case 4:
1839 return new NVtbx4(machInst, vd, vn, vm);
1840 }
1841 }
1842 } else if (q == 0xc && (c & 0x9) == 0) {
1843 unsigned imm4 = bits(machInst, 19, 16);
1844 if (bits(imm4, 2, 0) == 0)
1845 return new Unknown(machInst);
1846 unsigned size = 0;
1847 while ((imm4 & 0x1) == 0) {
1848 size++;
1849 imm4 >>= 1;
1850 }
1851 unsigned index = imm4 >> 1;
1852 const bool q = bits(machInst, 6);
1853 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1854 q, size, machInst, vd, vm, index);
1855 }
1856 }
1857 return new Unknown(machInst);
1858 }
1859 '''
1860}};
1861
1862def format ThumbNeonMem() {{
1863 decode_block = '''
1864 return decodeNeonMem(machInst);
1865 '''
1866}};
1867
1868def format ThumbNeonData() {{
1869 decode_block = '''
1870 return decodeNeonData(machInst);
1871 '''
1872}};
1873
1874let {{
1875 header_output = '''
1876 StaticInstPtr
1877 decodeExtensionRegLoadStore(ExtMachInst machInst);
1878 '''
1879 decoder_output = '''
1880 StaticInstPtr
1881 decodeExtensionRegLoadStore(ExtMachInst machInst)
1882 {
1883 const uint32_t opcode = bits(machInst, 24, 20);
1884 const uint32_t offset = bits(machInst, 7, 0);
1885 const bool single = (bits(machInst, 8) == 0);
1886 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1887 RegIndex vd;
1888 if (single) {
1889 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1890 bits(machInst, 22));
1891 } else {
1892 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1893 (bits(machInst, 22) << 5));
1894 }
1895 switch (bits(opcode, 4, 3)) {
1896 case 0x0:
1897 if (bits(opcode, 4, 1) == 0x2 &&
1898 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1899 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1900 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1901 break;
1902 }
1903 const IntRegIndex rt =
1904 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1905 const IntRegIndex rt2 =
1906 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1907 const bool op = bits(machInst, 20);
1908 uint32_t vm;
1909 if (single) {
1910 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1911 } else {
1912 vm = (bits(machInst, 3, 0) << 1) |
1913 (bits(machInst, 5) << 5);
1914 }
1915 if (op) {
1916 return new Vmov2Core2Reg(machInst, rt, rt2,
1917 (IntRegIndex)vm);
1918 } else {
1919 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1920 rt, rt2);
1921 }
1922 }
1923 break;
1924 case 0x1:
1925 {
1926 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1927 break;
1928 }
1929 switch (bits(opcode, 1, 0)) {
1930 case 0x0:
1931 return new VLdmStm(machInst, rn, vd, single,
1932 true, false, false, offset);
1933 case 0x1:
1934 return new VLdmStm(machInst, rn, vd, single,
1935 true, false, true, offset);
1936 case 0x2:
1937 return new VLdmStm(machInst, rn, vd, single,
1938 true, true, false, offset);
1939 case 0x3:
1940 // If rn == sp, then this is called vpop.
1941 return new VLdmStm(machInst, rn, vd, single,
1942 true, true, true, offset);
1943 default:
1944 M5_UNREACHABLE;
1945 }
1946 }
1947 case 0x2:
1948 if (bits(opcode, 1, 0) == 0x2) {
1949 // If rn == sp, then this is called vpush.
1950 return new VLdmStm(machInst, rn, vd, single,
1951 false, true, false, offset);
1952 } else if (bits(opcode, 1, 0) == 0x3) {
1953 return new VLdmStm(machInst, rn, vd, single,
1954 false, true, true, offset);
1955 }
1956 M5_FALLTHROUGH;
1957 case 0x3:
1958 const bool up = (bits(machInst, 23) == 1);
1959 const uint32_t imm = bits(machInst, 7, 0) << 2;
1960 if (single) {
1961 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1962 (bits(machInst, 22)));
1963 } else {
1964 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1965 (bits(machInst, 22) << 5));
1966 }
1967 if (bits(opcode, 1, 0) == 0x0) {
1968 if (single) {
1969 if (up) {
1970 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1971 } else {
1972 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1973 }
1974 } else {
1975 if (up) {
1976 return new %(vstr_ud)s(machInst, vd, vd + 1,
1977 rn, up, imm);
1978 } else {
1979 return new %(vstr_d)s(machInst, vd, vd + 1,
1980 rn, up, imm);
1981 }
1982 }
1983 } else if (bits(opcode, 1, 0) == 0x1) {
1984 if (single) {
1985 if (up) {
1986 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1987 } else {
1988 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1989 }
1990 } else {
1991 if (up) {
1992 return new %(vldr_ud)s(machInst, vd, vd + 1,
1993 rn, up, imm);
1994 } else {
1995 return new %(vldr_d)s(machInst, vd, vd + 1,
1996 rn, up, imm);
1997 }
1998 }
1999 }
2000 }
2001 return new Unknown(machInst);
2002 }
2003 ''' % {
2004 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
2005 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
2006 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
2007 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
2008 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
2009 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
2010 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
2011 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
2012 }
2013}};
2014
2015def format ExtensionRegLoadStore() {{
2016 decode_block = '''
2017 return decodeExtensionRegLoadStore(machInst);
2018 '''
2019}};
2020
2021let {{
2022 header_output = '''
2023 StaticInstPtr
2024 decodeShortFpTransfer(ExtMachInst machInst);
2025 '''
2026 decoder_output = '''
2027 IntRegIndex decodeFpVd(ExtMachInst machInst, uint32_t size, bool isInt)
2028 {
2029 if (!isInt and size == 3) {
2030 return (IntRegIndex)((bits(machInst, 22) << 5) |
2031 (bits(machInst, 15, 12) << 1));
2032 } else {
2033 return (IntRegIndex)(bits(machInst, 22) |
2034 (bits(machInst, 15, 12) << 1));
2035 }
2036 }
2037
2038 IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2039 {
2040 if (!isInt and size == 3) {
2041 return (IntRegIndex)((bits(machInst, 5) << 5) |
2042 (bits(machInst, 3, 0) << 1));
2043 } else {
2044 return (IntRegIndex)(bits(machInst, 5) |
2045 (bits(machInst, 3, 0) << 1));
2046 }
2047 }
2048
2049 IntRegIndex decodeFpVn(ExtMachInst machInst, uint32_t size)
2050 {
2051 if (size == 3) {
2052 return (IntRegIndex)((bits(machInst, 7) << 5) |
2053 (bits(machInst, 19, 16) << 1));
2054 } else {
2055 return (IntRegIndex)(bits(machInst, 7) |
2056 (bits(machInst, 19, 16) << 1));
2057 }
2058 }
2059
2060 StaticInstPtr
2061 decodeFloatingPointDataProcessing(ExtMachInst machInst) {
2062 const uint32_t op0 = bits(machInst, 23, 20);
2063 const uint32_t op1 = bits(machInst, 19, 16);
2064 const uint32_t op2 = bits(machInst, 9, 8);
2065 const uint32_t op3 = bits(machInst, 6);
2066 const uint32_t rm = bits(machInst, 17, 16);
2067 const uint32_t size = bits(machInst, 9, 8);
2068 IntRegIndex vd = decodeFpVd(machInst, size, false);
2069 IntRegIndex vm = decodeFpVm(machInst, size, false);
2070 IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2071 IntRegIndex vn = decodeFpVn(machInst, size);
2072 if (bits(machInst, 31, 24) == 0xFE && !bits(machInst, 4)) {
2073 if (bits(op0, 3) == 0 && op2 != 0 && !op3){
2074 ConditionCode cond;
2075 switch(bits(machInst, 21, 20)) {
2076 case 0x0: cond = COND_EQ; break;
2077 case 0x1: cond = COND_VS; break;
2078 case 0x2: cond = COND_GE; break;
2079 case 0x3: cond = COND_GT; break;
2080 }
2081 if (size == 3) {
2082 return new VselD(machInst, vd, vn, vm, cond);
2083 } else {
2084 return new VselS(machInst, vd, vn, vm, cond);
2085 }
2086 } else if (bits(op0, 3) == 1 && bits(op0, 1, 0) == 0 && op2 != 0) {
2087 const bool op = bits(machInst, 6);
2088 if (op) {
2089 if (size == 1) {
2090 return new FailUnimplemented("vminnm.f16", machInst);
2091 }
2092 return decodeNeonSizeSingleDouble<VminnmS, VminnmD>(
2093 size, machInst, vd, vn, vm);
2094 } else {
2095 if (size == 1) {
2096 return new FailUnimplemented("vmaxnm.f16", machInst);
2097 }
2098 return decodeNeonSizeSingleDouble<VmaxnmS, VmaxnmD>(
2099 size, machInst, vd, vn, vm);
2100 }
2101 } else if (bits(op0, 3) && bits(op0, 1, 0) == 3 &&
2102 bits(op1, 3) && op2 != 0 && op3)
2103 {
2104 const uint32_t o1 = bits(machInst, 18);
2105 if (o1 == 0) {
2106 if (size == 3) {
2107 switch(rm) {
2108 case 0x0:
2109 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2110 true);
2111 case 0x1:
2112 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2113 true);
2114 case 0x2:
2115 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
2116 true);
2117 case 0x3:
2118 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
2119 true);
2120 default: return new Unknown(machInst);
2121 }
2122 } else {
2123 switch(rm) {
2124 case 0x0:
2125 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
2126 false);
2127 case 0x1:
2128 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2129 false);
2130 case 0x2:
2131 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2132 false);
2133 case 0x3:
2134 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2135 false);
2136 default: return new Unknown(machInst);
2137 }
2138 }
2139 } else {
2140 const bool op = bits(machInst, 7);
2141 switch(rm) {
2142 case 0x0:
2143 switch(size) {
2144 case 0x0:
2145 return new Unknown(machInst);
2146 case 0x1:
2147 return new FailUnimplemented(
2148 "vcvta.u32.f16", machInst);
2149 case 0x2:
2150 if (op) {
2151 return new VcvtaFpSIntS(machInst, vdInt, vm);
2152 } else {
2153 return new VcvtaFpUIntS(machInst, vdInt, vm);
2154 }
2155 case 0x3:
2156 if (op) {
2157 return new VcvtaFpSIntD(machInst, vdInt, vm);
2158 } else {
2159 return new VcvtaFpUIntD(machInst, vdInt, vm);
2160 }
2161 default: return new Unknown(machInst);
2162 }
2163 case 0x1:
2164 switch(size) {
2165 case 0x0:
2166 return new Unknown(machInst);
2167 case 0x1:
2168 return new FailUnimplemented(
2169 "vcvtn.u32.f16", machInst);
2170 case 0x2:
2171 if (op) {
2172 return new VcvtnFpSIntS(machInst, vdInt, vm);
2173 } else {
2174 return new VcvtnFpUIntS(machInst, vdInt, vm);
2175 }
2176 case 0x3:
2177 if (op) {
2178 return new VcvtnFpSIntD(machInst, vdInt, vm);
2179 } else {
2180 return new VcvtnFpUIntD(machInst, vdInt, vm);
2181 }
2182 default: return new Unknown(machInst);
2183 }
2184 case 0x2:
2185 switch(size) {
2186 case 0x0:
2187 return new Unknown(machInst);
2188 case 0x1:
2189 return new FailUnimplemented(
2190 "vcvtp.u32.f16", machInst);
2191 case 0x2:
2192 if (op) {
2193 return new VcvtpFpSIntS(machInst, vdInt, vm);
2194 } else {
2195 return new VcvtpFpUIntS(machInst, vdInt, vm);
2196 }
2197 case 0x3:
2198 if (op) {
2199 return new VcvtpFpSIntD(machInst, vdInt, vm);
2200 } else {
2201 return new VcvtpFpUIntD(machInst, vdInt, vm);
2202 }
2203 default: return new Unknown(machInst);
2204 }
2205 case 0x3:
2206 switch(size) {
2207 case 0x0:
2208 return new Unknown(machInst);
2209 case 0x1:
2210 return new FailUnimplemented(
2211 "vcvtm.u32.f16", machInst);
2212 case 0x2:
2213 if (op) {
2214 return new VcvtmFpSIntS(machInst, vdInt, vm);
2215 } else {
2216 return new VcvtmFpUIntS(machInst, vdInt, vm);
2217 }
2218 case 0x3:
2219 if (op) {
2220 return new VcvtmFpSIntD(machInst, vdInt, vm);
2221 } else {
2222 return new VcvtmFpUIntD(machInst, vdInt, vm);
2223 }
2224 default: return new Unknown(machInst);
2225 }
2226 default: return new Unknown(machInst);
2227 }
2228 }
2229 } else {
2230 return new Unknown(machInst);
2231 }
2232 } else {
2233 return new Unknown(machInst);
2234 }
2235 }
2236
2237 StaticInstPtr
2238 decodeShortFpTransfer(ExtMachInst machInst)
2239 {
2240 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2241 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2242 return decodeFloatingPointDataProcessing(machInst);
2243 }
2244 const uint32_t l = bits(machInst, 20);
2245 const uint32_t c = bits(machInst, 8);
2246 const uint32_t a = bits(machInst, 23, 21);
2247 const uint32_t q = bits(machInst, 6, 5);
2248 if (l == 0 && c == 0) {
2249 if (a == 0) {
2250 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2251 bits(machInst, 7);
2252 const IntRegIndex rt =
2253 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2254 if (bits(machInst, 20) == 1) {
2255 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2256 } else {
2257 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2258 }
2259 } else if (a == 0x7) {
2260 const IntRegIndex rt =
2261 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2262 uint32_t reg = bits(machInst, 19, 16);
2263 uint32_t specReg;
2264 switch (reg) {
2265 case 0:
2266 specReg = MISCREG_FPSID;
2267 break;
2268 case 1:
2269 specReg = MISCREG_FPSCR;
2270 break;
2271 case 6:
2272 specReg = MISCREG_MVFR1;
2273 break;
2274 case 7:
2275 specReg = MISCREG_MVFR0;
2276 break;
2277 case 8:
2278 specReg = MISCREG_FPEXC;
2279 break;
2280 default:
2281 return new Unknown(machInst);
2282 }
2283 if (specReg == MISCREG_FPSCR) {
2284 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2285 } else {
2286 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2287 reg, a, bits(machInst, 7, 5));
2288 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2289 }
2290 }
2291 } else if (l == 0 && c == 1) {
2292 if (bits(a, 2) == 0) {
2293 uint32_t vd = (bits(machInst, 7) << 5) |
2294 (bits(machInst, 19, 16) << 1);
2295 // Handle accessing each single precision half of the vector.
2296 vd += bits(machInst, 21);
2297 const IntRegIndex rt =
2298 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2299 if (bits(machInst, 22) == 1) {
2300 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2301 rt, bits(machInst, 6, 5));
2302 } else if (bits(machInst, 5) == 1) {
2303 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2304 rt, bits(machInst, 6));
2305 } else if (bits(machInst, 6) == 0) {
2306 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2307 } else {
2308 return new Unknown(machInst);
2309 }
2310 } else if (bits(q, 1) == 0) {
2311 bool q = bits(machInst, 21);
2312 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2313 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2314 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2315 IntRegIndex rt = (IntRegIndex)(uint32_t)
2316 bits(machInst, 15, 12);
2317 if (q) {
2318 switch (be) {
2319 case 0:
2320 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2321 case 1:
2322 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2323 case 2:
2324 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2325 case 3:
2326 return new Unknown(machInst);
2327 }
2328 } else {
2329 switch (be) {
2330 case 0:
2331 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2332 case 1:
2333 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2334 case 2:
2335 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2336 case 3:
2337 return new Unknown(machInst);
2338 }
2339 }
2340 }
2341 } else if (l == 1 && c == 0) {
2342 if (a == 0) {
2343 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2344 bits(machInst, 7);
2345 const IntRegIndex rt =
2346 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2347 if (bits(machInst, 20) == 1) {
2348 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2349 } else {
2350 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2351 }
2352 } else if (a == 7) {
2353 const IntRegIndex rt =
2354 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2355 uint32_t reg = bits(machInst, 19, 16);
2356 uint32_t specReg;
2357 switch (reg) {
2358 case 0:
2359 specReg = MISCREG_FPSID;
2360 break;
2361 case 1:
2362 specReg = MISCREG_FPSCR;
2363 break;
2364 case 6:
2365 specReg = MISCREG_MVFR1;
2366 break;
2367 case 7:
2368 specReg = MISCREG_MVFR0;
2369 break;
2370 case 8:
2371 specReg = MISCREG_FPEXC;
2372 break;
2373 default:
2374 return new Unknown(machInst);
2375 }
2376 if (rt == 0xf) {
2377 if (specReg == MISCREG_FPSCR) {
2378 return new VmrsApsrFpscr(machInst);
2379 } else {
2380 return new Unknown(machInst);
2381 }
2382 } else if (specReg == MISCREG_FPSCR) {
2383 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2384 } else {
2385 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2386 reg, a, bits(machInst, 7, 5));
2387 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2388 }
2389 }
2390 } else {
2391 uint32_t vd = (bits(machInst, 7) << 5) |
2392 (bits(machInst, 19, 16) << 1);
2393 // Handle indexing into each single precision half of the vector.
2394 vd += bits(machInst, 21);
2395 uint32_t index;
2396 const IntRegIndex rt =
2397 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2398 const bool u = (bits(machInst, 23) == 1);
2399 if (bits(machInst, 22) == 1) {
2400 index = bits(machInst, 6, 5);
2401 if (u) {
2402 return new VmovRegCoreUB(machInst, rt,
2403 (IntRegIndex)vd, index);
2404 } else {
2405 return new VmovRegCoreSB(machInst, rt,
2406 (IntRegIndex)vd, index);
2407 }
2408 } else if (bits(machInst, 5) == 1) {
2409 index = bits(machInst, 6);
2410 if (u) {
2411 return new VmovRegCoreUH(machInst, rt,
2412 (IntRegIndex)vd, index);
2413 } else {
2414 return new VmovRegCoreSH(machInst, rt,
2415 (IntRegIndex)vd, index);
2416 }
2417 } else if (bits(machInst, 6) == 0 && !u) {
2418 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2419 } else {
2420 return new Unknown(machInst);
2421 }
2422 }
2423 return new Unknown(machInst);
2424 }
2425 '''
2426}};
2427
2428def format ShortFpTransfer() {{
2429 decode_block = '''
2430 return decodeShortFpTransfer(machInst);
2431 '''
2432}};
2433
2434let {{
2435 header_output = '''
2436 StaticInstPtr
2437 decodeVfpData(ExtMachInst machInst);
2438 '''
2439 decoder_output = '''
2440 StaticInstPtr
2441 decodeVfpData(ExtMachInst machInst)
2442 {
2443 const uint32_t opc1 = bits(machInst, 23, 20);
2444 const uint32_t opc2 = bits(machInst, 19, 16);
2445 const uint32_t opc3 = bits(machInst, 7, 6);
2446 //const uint32_t opc4 = bits(machInst, 3, 0);
2447 const bool single = (bits(machInst, 8) == 0);
2448 // Used to select between vcmp and vcmpe.
2449 const bool e = (bits(machInst, 7) == 1);
2450 IntRegIndex vd;
2451 IntRegIndex vm;
2452 IntRegIndex vn;
2453 if (single) {
2454 vd = (IntRegIndex)(bits(machInst, 22) |
2455 (bits(machInst, 15, 12) << 1));
2456 vm = (IntRegIndex)(bits(machInst, 5) |
2457 (bits(machInst, 3, 0) << 1));
2458 vn = (IntRegIndex)(bits(machInst, 7) |
2459 (bits(machInst, 19, 16) << 1));
2460 } else {
2461 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2462 (bits(machInst, 15, 12) << 1));
2463 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2464 (bits(machInst, 3, 0) << 1));
2465 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2466 (bits(machInst, 19, 16) << 1));
2467 }
2468 switch (opc1 & 0xb /* 1011 */) {
2469 case 0x0:
2470 if (bits(machInst, 6) == 0) {
2471 if (single) {
2472 return decodeVfpRegRegRegOp<VmlaS>(
2473 machInst, vd, vn, vm, false);
2474 } else {
2475 return decodeVfpRegRegRegOp<VmlaD>(
2476 machInst, vd, vn, vm, true);
2477 }
2478 } else {
2479 if (single) {
2480 return decodeVfpRegRegRegOp<VmlsS>(
2481 machInst, vd, vn, vm, false);
2482 } else {
2483 return decodeVfpRegRegRegOp<VmlsD>(
2484 machInst, vd, vn, vm, true);
2485 }
2486 }
2487 case 0x1:
2488 if (bits(machInst, 6) == 1) {
2489 if (single) {
2490 return decodeVfpRegRegRegOp<VnmlaS>(
2491 machInst, vd, vn, vm, false);
2492 } else {
2493 return decodeVfpRegRegRegOp<VnmlaD>(
2494 machInst, vd, vn, vm, true);
2495 }
2496 } else {
2497 if (single) {
2498 return decodeVfpRegRegRegOp<VnmlsS>(
2499 machInst, vd, vn, vm, false);
2500 } else {
2501 return decodeVfpRegRegRegOp<VnmlsD>(
2502 machInst, vd, vn, vm, true);
2503 }
2504 }
2505 case 0x2:
2506 if ((opc3 & 0x1) == 0) {
2507 if (single) {
2508 return decodeVfpRegRegRegOp<VmulS>(
2509 machInst, vd, vn, vm, false);
2510 } else {
2511 return decodeVfpRegRegRegOp<VmulD>(
2512 machInst, vd, vn, vm, true);
2513 }
2514 } else {
2515 if (single) {
2516 return decodeVfpRegRegRegOp<VnmulS>(
2517 machInst, vd, vn, vm, false);
2518 } else {
2519 return decodeVfpRegRegRegOp<VnmulD>(
2520 machInst, vd, vn, vm, true);
2521 }
2522 }
2523 case 0x3:
2524 if ((opc3 & 0x1) == 0) {
2525 if (single) {
2526 return decodeVfpRegRegRegOp<VaddS>(
2527 machInst, vd, vn, vm, false);
2528 } else {
2529 return decodeVfpRegRegRegOp<VaddD>(
2530 machInst, vd, vn, vm, true);
2531 }
2532 } else {
2533 if (single) {
2534 return decodeVfpRegRegRegOp<VsubS>(
2535 machInst, vd, vn, vm, false);
2536 } else {
2537 return decodeVfpRegRegRegOp<VsubD>(
2538 machInst, vd, vn, vm, true);
2539 }
2540 }
2541 case 0x8:
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011, 2016-2019 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 M5_FALLTHROUGH;
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 opc = bits(machInst, 11, 8);
345 const bool o1 = bits(machInst, 4);
346 const uint32_t size = 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 bool q = bits(machInst, 6);
357 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
358 return new Unknown(machInst);
359 switch (opc) {
360 case 0x0:
361 if (o1) {
362 if (u) {
363 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
364 q, size, machInst, vd, vn, vm);
365 } else {
366 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
367 q, size, machInst, vd, vn, vm);
368 }
369 } else {
370 if (size == 3)
371 return new Unknown(machInst);
372 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
373 q, u, size, machInst, vd, vn, vm);
374 }
375 case 0x1:
376 if (!o1) {
377 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
378 q, u, size, machInst, vd, vn, vm);
379 } else {
380 if (u) {
381 switch (size) {
382 case 0:
383 if (q) {
384 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
385 } else {
386 return new VeorD<uint64_t>(machInst, vd, vn, vm);
387 }
388 case 1:
389 if (q) {
390 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
391 } else {
392 return new VbslD<uint64_t>(machInst, vd, vn, vm);
393 }
394 case 2:
395 if (q) {
396 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
397 } else {
398 return new VbitD<uint64_t>(machInst, vd, vn, vm);
399 }
400 case 3:
401 if (q) {
402 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
403 } else {
404 return new VbifD<uint64_t>(machInst, vd, vn, vm);
405 }
406 default:
407 M5_UNREACHABLE;
408 }
409 } else {
410 switch (size) {
411 case 0:
412 if (q) {
413 return new VandQ<uint64_t>(machInst, vd, vn, vm);
414 } else {
415 return new VandD<uint64_t>(machInst, vd, vn, vm);
416 }
417 case 1:
418 if (q) {
419 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
420 } else {
421 return new VbicD<uint64_t>(machInst, vd, vn, vm);
422 }
423 case 2:
424 if (vn == vm) {
425 if (q) {
426 return new VmovQ<uint64_t>(
427 machInst, vd, vn, vm);
428 } else {
429 return new VmovD<uint64_t>(
430 machInst, vd, vn, vm);
431 }
432 } else {
433 if (q) {
434 return new VorrQ<uint64_t>(
435 machInst, vd, vn, vm);
436 } else {
437 return new VorrD<uint64_t>(
438 machInst, vd, vn, vm);
439 }
440 }
441 case 3:
442 if (q) {
443 return new VornQ<uint64_t>(
444 machInst, vd, vn, vm);
445 } else {
446 return new VornD<uint64_t>(
447 machInst, vd, vn, vm);
448 }
449 default:
450 M5_UNREACHABLE;
451 }
452 }
453 }
454 case 0x2:
455 if (o1) {
456 if (u) {
457 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
458 q, size, machInst, vd, vn, vm);
459 } else {
460 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
461 q, size, machInst, vd, vn, vm);
462 }
463 } else {
464 if (size == 3)
465 return new Unknown(machInst);
466 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
467 q, u, size, machInst, vd, vn, vm);
468 }
469 case 0x3:
470 if (o1) {
471 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
472 q, u, size, machInst, vd, vn, vm);
473 } else {
474 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
475 q, u, size, machInst, vd, vn, vm);
476 }
477 case 0x4:
478 if (o1) {
479 if (u) {
480 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
481 q, size, machInst, vd, vm, vn);
482 } else {
483 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
484 q, size, machInst, vd, vm, vn);
485 }
486 } else {
487 return decodeNeonUSThreeReg<VshlD, VshlQ>(
488 q, u, size, machInst, vd, vm, vn);
489 }
490 case 0x5:
491 if (o1) {
492 if (u) {
493 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
494 q, size, machInst, vd, vm, vn);
495 } else {
496 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
497 q, size, machInst, vd, vm, vn);
498 }
499 } else {
500 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
501 q, u, size, machInst, vd, vm, vn);
502 }
503 case 0x6:
504 if (o1) {
505 return decodeNeonUSThreeReg<VminD, VminQ>(
506 q, u, size, machInst, vd, vn, vm);
507 } else {
508 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
509 q, u, size, machInst, vd, vn, vm);
510 }
511 case 0x7:
512 if (o1) {
513 return decodeNeonUSThreeReg<VabaD, VabaQ>(
514 q, u, size, machInst, vd, vn, vm);
515 } else {
516 if (bits(machInst, 23) == 1) {
517 if (q) {
518 return new Unknown(machInst);
519 } else {
520 return decodeNeonUSThreeUSReg<Vabdl>(
521 u, size, machInst, vd, vn, vm);
522 }
523 } else {
524 return decodeNeonUSThreeReg<VabdD, VabdQ>(
525 q, u, size, machInst, vd, vn, vm);
526 }
527 }
528 case 0x8:
529 if (o1) {
530 if (u) {
531 return decodeNeonUThreeReg<VceqD, VceqQ>(
532 q, size, machInst, vd, vn, vm);
533 } else {
534 return decodeNeonUThreeReg<VtstD, VtstQ>(
535 q, size, machInst, vd, vn, vm);
536 }
537 } else {
538 if (u) {
539 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
540 q, size, machInst, vd, vn, vm);
541 } else {
542 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
543 q, size, machInst, vd, vn, vm);
544 }
545 }
546 case 0x9:
547 if (o1) {
548 if (u) {
549 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
550 q, size, machInst, vd, vn, vm);
551 } else {
552 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
553 q, size, machInst, vd, vn, vm);
554 }
555 } else {
556 if (u) {
557 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
558 q, u, size, machInst, vd, vn, vm);
559 } else {
560 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
561 q, u, size, machInst, vd, vn, vm);
562 }
563 }
564 case 0xa:
565 if (q)
566 return new Unknown(machInst);
567 if (o1) {
568 return decodeNeonUSThreeUSReg<VpminD>(
569 u, size, machInst, vd, vn, vm);
570 } else {
571 return decodeNeonUSThreeUSReg<VpmaxD>(
572 u, size, machInst, vd, vn, vm);
573 }
574 case 0xb:
575 if (o1) {
576 if (u || q) {
577 return new Unknown(machInst);
578 } else {
579 return decodeNeonUThreeUSReg<NVpaddD>(
580 size, machInst, vd, vn, vm);
581 }
582 } else {
583 if (u) {
584 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
585 q, size, machInst, vd, vn, vm);
586 } else {
587 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
588 q, size, machInst, vd, vn, vm);
589 }
590 }
591 case 0xc:
592 if (o1) {
593 if (!u) {
594 if (bits(size, 1) == 0) {
595 if (q) {
596 return new NVfmaQFp<float>(machInst, vd, vn, vm);
597 } else {
598 return new NVfmaDFp<float>(machInst, vd, vn, vm);
599 }
600 } else {
601 if (q) {
602 return new NVfmsQFp<float>(machInst, vd, vn, vm);
603 } else {
604 return new NVfmsDFp<float>(machInst, vd, vn, vm);
605 }
606 }
607 }
608 } else {
609 if (u) {
610 switch (size) {
611 case 0x0:
612 return new SHA256H(machInst, vd, vn, vm);
613 case 0x1:
614 return new SHA256H2(machInst, vd, vn, vm);
615 case 0x2:
616 return new SHA256SU1(machInst, vd, vn, vm);
617 case 0x3:
618 return new Unknown(machInst);
619 default:
620 M5_UNREACHABLE;
621 }
622 } else {
623 switch (size) {
624 case 0x0:
625 return new SHA1C(machInst, vd, vn, vm);
626 case 0x1:
627 return new SHA1P(machInst, vd, vn, vm);
628 case 0x2:
629 return new SHA1M(machInst, vd, vn, vm);
630 case 0x3:
631 return new SHA1SU0(machInst, vd, vn, vm);
632 default:
633 M5_UNREACHABLE;
634 }
635 }
636 }
637 return new Unknown(machInst);
638 case 0xd:
639 if (o1) {
640 if (u) {
641 if (bits(size, 1) == 0) {
642 if (q) {
643 return new NVmulQFp<float>(machInst, vd, vn, vm);
644 } else {
645 return new NVmulDFp<float>(machInst, vd, vn, vm);
646 }
647 } else {
648 return new Unknown(machInst);
649 }
650 } else {
651 if (bits(size, 1) == 0) {
652 if (q) {
653 return new NVmlaQFp<float>(machInst, vd, vn, vm);
654 } else {
655 return new NVmlaDFp<float>(machInst, vd, vn, vm);
656 }
657 } else {
658 if (q) {
659 return new NVmlsQFp<float>(machInst, vd, vn, vm);
660 } else {
661 return new NVmlsDFp<float>(machInst, vd, vn, vm);
662 }
663 }
664 }
665 } else {
666 if (u) {
667 if (bits(size, 1) == 0) {
668 if (q) {
669 return new VpaddQFp<float>(machInst, vd, vn, vm);
670 } else {
671 return new VpaddDFp<float>(machInst, vd, vn, vm);
672 }
673 } else {
674 if (q) {
675 return new VabdQFp<float>(machInst, vd, vn, vm);
676 } else {
677 return new VabdDFp<float>(machInst, vd, vn, vm);
678 }
679 }
680 } else {
681 if (bits(size, 1) == 0) {
682 if (q) {
683 return new VaddQFp<float>(machInst, vd, vn, vm);
684 } else {
685 return new VaddDFp<float>(machInst, vd, vn, vm);
686 }
687 } else {
688 if (q) {
689 return new VsubQFp<float>(machInst, vd, vn, vm);
690 } else {
691 return new VsubDFp<float>(machInst, vd, vn, vm);
692 }
693 }
694 }
695 }
696 case 0xe:
697 if (o1) {
698 if (u) {
699 if (bits(size, 1) == 0) {
700 if (q) {
701 return new VacgeQFp<float>(machInst, vd, vn, vm);
702 } else {
703 return new VacgeDFp<float>(machInst, vd, vn, vm);
704 }
705 } else {
706 if (q) {
707 return new VacgtQFp<float>(machInst, vd, vn, vm);
708 } else {
709 return new VacgtDFp<float>(machInst, vd, vn, vm);
710 }
711 }
712 } else {
713 return new Unknown(machInst);
714 }
715 } else {
716 if (u) {
717 if (bits(size, 1) == 0) {
718 if (q) {
719 return new VcgeQFp<float>(machInst, vd, vn, vm);
720 } else {
721 return new VcgeDFp<float>(machInst, vd, vn, vm);
722 }
723 } else {
724 if (q) {
725 return new VcgtQFp<float>(machInst, vd, vn, vm);
726 } else {
727 return new VcgtDFp<float>(machInst, vd, vn, vm);
728 }
729 }
730 } else {
731 if (bits(size, 1) == 0) {
732 if (q) {
733 return new VceqQFp<float>(machInst, vd, vn, vm);
734 } else {
735 return new VceqDFp<float>(machInst, vd, vn, vm);
736 }
737 } else {
738 return new Unknown(machInst);
739 }
740 }
741 }
742 case 0xf:
743 if (o1) {
744 if (u) {
745 if (bits(size, 1) == 0) {
746 if (q) {
747 return new VmaxnmQFp<uint32_t>(
748 machInst, vd, vn, vm);
749 } else {
750 return new VmaxnmDFp<uint32_t>(
751 machInst, vd, vn, vm);
752 }
753 } else {
754 if (q) {
755 return new VminnmQFp<uint32_t>(
756 machInst, vd, vn, vm);
757 } else {
758 return new VminnmDFp<uint32_t>(
759 machInst, vd, vn, vm);
760 }
761 }
762 } else {
763 if (bits(size, 1) == 0) {
764 if (q) {
765 return new VrecpsQFp<float>(machInst, vd, vn, vm);
766 } else {
767 return new VrecpsDFp<float>(machInst, vd, vn, vm);
768 }
769 } else {
770 if (q) {
771 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
772 } else {
773 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
774 }
775 }
776 }
777 } else {
778 if (u) {
779 if (bits(size, 1) == 0) {
780 if (q) {
781 return new VpmaxQFp<uint32_t>(
782 machInst, vd, vn, vm);
783 } else {
784 return new VpmaxDFp<uint32_t>(
785 machInst, vd, vn, vm);
786 }
787 } else {
788 if (q) {
789 return new VpminQFp<uint32_t>(
790 machInst, vd, vn, vm);
791 } else {
792 return new VpminDFp<uint32_t>(
793 machInst, vd, vn, vm);
794 }
795 }
796 } else {
797 if (bits(size, 1) == 0) {
798 if (q) {
799 return new VmaxQFp<uint32_t>(
800 machInst, vd, vn, vm);
801 } else {
802 return new VmaxDFp<uint32_t>(
803 machInst, vd, vn, vm);
804 }
805 } else {
806 if (q) {
807 return new VminQFp<uint32_t>(
808 machInst, vd, vn, vm);
809 } else {
810 return new VminDFp<uint32_t>(
811 machInst, vd, vn, vm);
812 }
813 }
814 }
815 }
816 }
817 return new Unknown(machInst);
818 }
819
820 static StaticInstPtr
821 decodeNeonOneRegModImm(ExtMachInst machInst)
822 {
823 const IntRegIndex vd =
824 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
825 (bits(machInst, 22) << 4)));
826 const bool q = bits(machInst, 6);
827 const bool op = bits(machInst, 5);
828 const uint8_t cmode = bits(machInst, 11, 8);
829 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
830 bits(machInst, 24)) << 7) |
831 (bits(machInst, 18, 16) << 4) |
832 (bits(machInst, 3, 0) << 0);
833
834 // Check for invalid immediate encodings and return an unknown op
835 // if it happens
836 bool immValid = true;
837 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
838 if (!immValid) {
839 return new Unknown(machInst);
840 }
841
842 if (op) {
843 if (bits(cmode, 3) == 0) {
844 if (bits(cmode, 0) == 0) {
845 if (q)
846 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
847 else
848 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
849 } else {
850 if (q)
851 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
852 else
853 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
854 }
855 } else {
856 if (bits(cmode, 2) == 1) {
857 switch (bits(cmode, 1, 0)) {
858 case 0:
859 case 1:
860 if (q)
861 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
862 else
863 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
864 case 2:
865 if (q)
866 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
867 else
868 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
869 case 3:
870 if (q)
871 return new Unknown(machInst);
872 else
873 return new Unknown(machInst);
874 }
875 } else {
876 if (bits(cmode, 0) == 0) {
877 if (q)
878 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
879 else
880 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
881 } else {
882 if (q)
883 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
884 else
885 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
886 }
887 }
888 }
889 } else {
890 if (bits(cmode, 3) == 0) {
891 if (bits(cmode, 0) == 0) {
892 if (q)
893 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
894 else
895 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
896 } else {
897 if (q)
898 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
899 else
900 return new NVorriD<uint64_t>(machInst, vd, bigImm);
901 }
902 } else {
903 if (bits(cmode, 2) == 1) {
904 if (q)
905 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
906 else
907 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
908 } else {
909 if (bits(cmode, 0) == 0) {
910 if (q)
911 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
912 else
913 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
914 } else {
915 if (q)
916 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
917 else
918 return new NVorriD<uint64_t>(machInst, vd, bigImm);
919 }
920 }
921 }
922 }
923 return new Unknown(machInst);
924 }
925
926 static StaticInstPtr
927 decodeNeonTwoRegAndShift(ExtMachInst machInst)
928 {
929 const uint32_t opc = bits(machInst, 11, 8);
930 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
931 const bool q = bits(machInst, 6);
932 const bool l = bits(machInst, 7);
933 const IntRegIndex vd =
934 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
935 (bits(machInst, 22) << 4)));
936 const IntRegIndex vm =
937 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
938 (bits(machInst, 5) << 4)));
939 unsigned imm6 = bits(machInst, 21, 16);
940 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
941 unsigned size = 3;
942 unsigned lShiftAmt = 0;
943 unsigned bitSel;
944 for (bitSel = 1 << 6; true; bitSel >>= 1) {
945 if (bitSel & imm)
946 break;
947 else if (!size)
948 return new Unknown(machInst);
949 size--;
950 }
951 lShiftAmt = imm6 & ~bitSel;
952 unsigned rShiftAmt = 0;
953 if (opc != 0xe && opc != 0xf) {
954 if (size > 2)
955 rShiftAmt = 64 - imm6;
956 else
957 rShiftAmt = 2 * (8 << size) - imm6;
958 }
959
960 switch (opc) {
961 case 0x0:
962 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
963 q, u, size, machInst, vd, vm, rShiftAmt);
964 case 0x1:
965 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
966 q, u, size, machInst, vd, vm, rShiftAmt);
967 case 0x2:
968 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
969 q, u, size, machInst, vd, vm, rShiftAmt);
970 case 0x3:
971 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
972 q, u, size, machInst, vd, vm, rShiftAmt);
973 case 0x4:
974 if (u) {
975 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
976 q, size, machInst, vd, vm, rShiftAmt);
977 } else {
978 return new Unknown(machInst);
979 }
980 case 0x5:
981 if (u) {
982 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
983 q, size, machInst, vd, vm, lShiftAmt);
984 } else {
985 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
986 q, size, machInst, vd, vm, lShiftAmt);
987 }
988 case 0x6:
989 case 0x7:
990 if (u) {
991 if (opc == 0x6) {
992 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
993 q, size, machInst, vd, vm, lShiftAmt);
994 } else {
995 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
996 q, size, machInst, vd, vm, lShiftAmt);
997 }
998 } else {
999 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
1000 q, size, machInst, vd, vm, lShiftAmt);
1001 }
1002 case 0x8:
1003 if (l) {
1004 return new Unknown(machInst);
1005 } else if (u) {
1006 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
1007 q, size, machInst, vd, vm, rShiftAmt);
1008 } else {
1009 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
1010 q, size, machInst, vd, vm, rShiftAmt);
1011 }
1012 case 0x9:
1013 if (l) {
1014 return new Unknown(machInst);
1015 } else if (u) {
1016 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
1017 q, size, machInst, vd, vm, rShiftAmt);
1018 } else {
1019 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
1020 q, size, machInst, vd, vm, rShiftAmt);
1021 }
1022 case 0xa:
1023 if (l || q) {
1024 return new Unknown(machInst);
1025 } else {
1026 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
1027 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
1028 }
1029 case 0xe:
1030 if (l) {
1031 return new Unknown(machInst);
1032 } else {
1033 if (bits(imm6, 5) == 0)
1034 return new Unknown(machInst);
1035 if (u) {
1036 if (q) {
1037 return new NVcvtu2fpQ<float>(
1038 machInst, vd, vm, 64 - imm6);
1039 } else {
1040 return new NVcvtu2fpD<float>(
1041 machInst, vd, vm, 64 - imm6);
1042 }
1043 } else {
1044 if (q) {
1045 return new NVcvts2fpQ<float>(
1046 machInst, vd, vm, 64 - imm6);
1047 } else {
1048 return new NVcvts2fpD<float>(
1049 machInst, vd, vm, 64 - imm6);
1050 }
1051 }
1052 }
1053 case 0xf:
1054 if (l) {
1055 return new Unknown(machInst);
1056 } else {
1057 if (bits(imm6, 5) == 0)
1058 return new Unknown(machInst);
1059 if (u) {
1060 if (q) {
1061 return new NVcvt2ufxQ<float>(
1062 machInst, vd, vm, 64 - imm6);
1063 } else {
1064 return new NVcvt2ufxD<float>(
1065 machInst, vd, vm, 64 - imm6);
1066 }
1067 } else {
1068 if (q) {
1069 return new NVcvt2sfxQ<float>(
1070 machInst, vd, vm, 64 - imm6);
1071 } else {
1072 return new NVcvt2sfxD<float>(
1073 machInst, vd, vm, 64 - imm6);
1074 }
1075 }
1076 }
1077 }
1078 return new Unknown(machInst);
1079 }
1080
1081 static StaticInstPtr
1082 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1083 {
1084 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1085 const uint32_t opc = bits(machInst, 11, 8);
1086 const IntRegIndex vd =
1087 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1088 (bits(machInst, 22) << 4)));
1089 const IntRegIndex vn =
1090 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1091 (bits(machInst, 7) << 4)));
1092 const IntRegIndex vm =
1093 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1094 (bits(machInst, 5) << 4)));
1095 const unsigned size = bits(machInst, 21, 20);
1096 switch (opc) {
1097 case 0x0:
1098 return decodeNeonUSThreeUSReg<Vaddl>(
1099 u, size, machInst, vd, vn, vm);
1100 case 0x1:
1101 return decodeNeonUSThreeUSReg<Vaddw>(
1102 u, size, machInst, vd, vn, vm);
1103 case 0x2:
1104 return decodeNeonUSThreeUSReg<Vsubl>(
1105 u, size, machInst, vd, vn, vm);
1106 case 0x3:
1107 return decodeNeonUSThreeUSReg<Vsubw>(
1108 u, size, machInst, vd, vn, vm);
1109 case 0x4:
1110 if (u) {
1111 return decodeNeonUThreeUSReg<Vraddhn>(
1112 size, machInst, vd, vn, vm);
1113 } else {
1114 return decodeNeonUThreeUSReg<Vaddhn>(
1115 size, machInst, vd, vn, vm);
1116 }
1117 case 0x5:
1118 return decodeNeonUSThreeUSReg<Vabal>(
1119 u, size, machInst, vd, vn, vm);
1120 case 0x6:
1121 if (u) {
1122 return decodeNeonUThreeUSReg<Vrsubhn>(
1123 size, machInst, vd, vn, vm);
1124 } else {
1125 return decodeNeonUThreeUSReg<Vsubhn>(
1126 size, machInst, vd, vn, vm);
1127 }
1128 case 0x7:
1129 if (bits(machInst, 23)) {
1130 return decodeNeonUSThreeUSReg<Vabdl>(
1131 u, size, machInst, vd, vn, vm);
1132 } else {
1133 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1134 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1135 }
1136 case 0x8:
1137 return decodeNeonUSThreeUSReg<Vmlal>(
1138 u, size, machInst, vd, vn, vm);
1139 case 0xa:
1140 return decodeNeonUSThreeUSReg<Vmlsl>(
1141 u, size, machInst, vd, vn, vm);
1142 case 0x9:
1143 if (u) {
1144 return new Unknown(machInst);
1145 } else {
1146 return decodeNeonSThreeUSReg<Vqdmlal>(
1147 size, machInst, vd, vn, vm);
1148 }
1149 case 0xb:
1150 if (u) {
1151 return new Unknown(machInst);
1152 } else {
1153 return decodeNeonSThreeUSReg<Vqdmlsl>(
1154 size, machInst, vd, vn, vm);
1155 }
1156 case 0xc:
1157 return decodeNeonUSThreeUSReg<Vmull>(
1158 u, size, machInst, vd, vn, vm);
1159 case 0xd:
1160 if (u) {
1161 return new Unknown(machInst);
1162 } else {
1163 return decodeNeonSThreeUSReg<Vqdmull>(
1164 size, machInst, vd, vn, vm);
1165 }
1166 case 0xe:
1167 return decodeNeonUThreeUSReg<Vmullp>(
1168 size, machInst, vd, vn, vm);
1169 }
1170 return new Unknown(machInst);
1171 }
1172
1173 static StaticInstPtr
1174 decodeNeonTwoRegScalar(ExtMachInst machInst)
1175 {
1176 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1177 const uint32_t opc = bits(machInst, 11, 8);
1178 const unsigned size = bits(machInst, 21, 20);
1179 const IntRegIndex vd =
1180 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1181 (bits(machInst, 22) << 4)));
1182 const IntRegIndex vn =
1183 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1184 (bits(machInst, 7) << 4)));
1185 const IntRegIndex vm = (size == 2) ?
1186 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1187 (IntRegIndex)(2 * bits(machInst, 2, 0));
1188 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1189 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1190 switch (opc) {
1191 case 0x0:
1192 if (u) {
1193 switch (size) {
1194 case 1:
1195 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1196 case 2:
1197 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1198 default:
1199 return new Unknown(machInst);
1200 }
1201 } else {
1202 switch (size) {
1203 case 1:
1204 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1205 case 2:
1206 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1207 default:
1208 return new Unknown(machInst);
1209 }
1210 }
1211 case 0x1:
1212 if (u)
1213 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1214 else
1215 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1216 case 0x4:
1217 if (u) {
1218 switch (size) {
1219 case 1:
1220 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1221 case 2:
1222 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1223 default:
1224 return new Unknown(machInst);
1225 }
1226 } else {
1227 switch (size) {
1228 case 1:
1229 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1230 case 2:
1231 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1232 default:
1233 return new Unknown(machInst);
1234 }
1235 }
1236 case 0x5:
1237 if (u)
1238 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1239 else
1240 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1241 case 0x2:
1242 if (u) {
1243 switch (size) {
1244 case 1:
1245 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1246 case 2:
1247 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1248 default:
1249 return new Unknown(machInst);
1250 }
1251 } else {
1252 switch (size) {
1253 case 1:
1254 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1255 case 2:
1256 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1257 default:
1258 return new Unknown(machInst);
1259 }
1260 }
1261 case 0x6:
1262 if (u) {
1263 switch (size) {
1264 case 1:
1265 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1266 case 2:
1267 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1268 default:
1269 return new Unknown(machInst);
1270 }
1271 } else {
1272 switch (size) {
1273 case 1:
1274 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1275 case 2:
1276 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1277 default:
1278 return new Unknown(machInst);
1279 }
1280 }
1281 case 0x3:
1282 if (u) {
1283 return new Unknown(machInst);
1284 } else {
1285 switch (size) {
1286 case 1:
1287 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1288 case 2:
1289 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1290 default:
1291 return new Unknown(machInst);
1292 }
1293 }
1294 case 0x7:
1295 if (u) {
1296 return new Unknown(machInst);
1297 } else {
1298 switch (size) {
1299 case 1:
1300 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1301 case 2:
1302 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1303 default:
1304 return new Unknown(machInst);
1305 }
1306 }
1307 case 0x8:
1308 if (u) {
1309 switch (size) {
1310 case 1:
1311 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1312 case 2:
1313 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1314 default:
1315 return new Unknown(machInst);
1316 }
1317 } else {
1318 switch (size) {
1319 case 1:
1320 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1321 case 2:
1322 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1323 default:
1324 return new Unknown(machInst);
1325 }
1326 }
1327 case 0x9:
1328 if (u)
1329 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1330 else
1331 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1332 case 0xa:
1333 if (u) {
1334 switch (size) {
1335 case 1:
1336 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1337 case 2:
1338 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1339 default:
1340 return new Unknown(machInst);
1341 }
1342 } else {
1343 switch (size) {
1344 case 1:
1345 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1346 case 2:
1347 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1348 default:
1349 return new Unknown(machInst);
1350 }
1351 }
1352 case 0xb:
1353 if (u) {
1354 return new Unknown(machInst);
1355 } else {
1356 if (u) {
1357 switch (size) {
1358 case 1:
1359 return new Vqdmulls<uint16_t>(
1360 machInst, vd, vn, vm, index);
1361 case 2:
1362 return new Vqdmulls<uint32_t>(
1363 machInst, vd, vn, vm, index);
1364 default:
1365 return new Unknown(machInst);
1366 }
1367 } else {
1368 switch (size) {
1369 case 1:
1370 return new Vqdmulls<int16_t>(
1371 machInst, vd, vn, vm, index);
1372 case 2:
1373 return new Vqdmulls<int32_t>(
1374 machInst, vd, vn, vm, index);
1375 default:
1376 return new Unknown(machInst);
1377 }
1378 }
1379 }
1380 case 0xc:
1381 if (u) {
1382 switch (size) {
1383 case 1:
1384 return new VqdmulhsQ<int16_t>(
1385 machInst, vd, vn, vm, index);
1386 case 2:
1387 return new VqdmulhsQ<int32_t>(
1388 machInst, vd, vn, vm, index);
1389 default:
1390 return new Unknown(machInst);
1391 }
1392 } else {
1393 switch (size) {
1394 case 1:
1395 return new VqdmulhsD<int16_t>(
1396 machInst, vd, vn, vm, index);
1397 case 2:
1398 return new VqdmulhsD<int32_t>(
1399 machInst, vd, vn, vm, index);
1400 default:
1401 return new Unknown(machInst);
1402 }
1403 }
1404 case 0xd:
1405 if (u) {
1406 switch (size) {
1407 case 1:
1408 return new VqrdmulhsQ<int16_t>(
1409 machInst, vd, vn, vm, index);
1410 case 2:
1411 return new VqrdmulhsQ<int32_t>(
1412 machInst, vd, vn, vm, index);
1413 default:
1414 return new Unknown(machInst);
1415 }
1416 } else {
1417 switch (size) {
1418 case 1:
1419 return new VqrdmulhsD<int16_t>(
1420 machInst, vd, vn, vm, index);
1421 case 2:
1422 return new VqrdmulhsD<int32_t>(
1423 machInst, vd, vn, vm, index);
1424 default:
1425 return new Unknown(machInst);
1426 }
1427 }
1428 }
1429 return new Unknown(machInst);
1430 }
1431
1432 static StaticInstPtr
1433 decodeNeonTwoRegMisc(ExtMachInst machInst)
1434 {
1435 const uint32_t opc1 = bits(machInst, 17, 16);
1436 const uint32_t b = bits(machInst, 10, 6);
1437 const bool q = bits(machInst, 6);
1438 const IntRegIndex vd =
1439 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1440 (bits(machInst, 22) << 4)));
1441 const IntRegIndex vm =
1442 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1443 (bits(machInst, 5) << 4)));
1444 const unsigned size = bits(machInst, 19, 18);
1445 switch (opc1) {
1446 case 0x0:
1447 switch (bits(b, 4, 1)) {
1448 case 0x0:
1449 switch (size) {
1450 case 0:
1451 if (q) {
1452 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1453 } else {
1454 return new NVrev64D<uint8_t>(machInst, vd, vm);
1455 }
1456 case 1:
1457 if (q) {
1458 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1459 } else {
1460 return new NVrev64D<uint16_t>(machInst, vd, vm);
1461 }
1462 case 2:
1463 if (q) {
1464 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1465 } else {
1466 return new NVrev64D<uint32_t>(machInst, vd, vm);
1467 }
1468 default:
1469 return new Unknown(machInst);
1470 }
1471 case 0x1:
1472 switch (size) {
1473 case 0:
1474 if (q) {
1475 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1476 } else {
1477 return new NVrev32D<uint8_t>(machInst, vd, vm);
1478 }
1479 case 1:
1480 if (q) {
1481 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1482 } else {
1483 return new NVrev32D<uint16_t>(machInst, vd, vm);
1484 }
1485 default:
1486 return new Unknown(machInst);
1487 }
1488 case 0x2:
1489 if (size != 0) {
1490 return new Unknown(machInst);
1491 } else if (q) {
1492 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1493 } else {
1494 return new NVrev16D<uint8_t>(machInst, vd, vm);
1495 }
1496 case 0x4:
1497 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1498 q, size, machInst, vd, vm);
1499 case 0x5:
1500 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1501 q, size, machInst, vd, vm);
1502 case 0x6:
1503 if (q == 0) {
1504 return new AESE(machInst, vd, vd, vm);
1505 } else {
1506 return new AESD(machInst, vd, vd, vm);
1507 }
1508 case 0x7:
1509 if (q == 0) {
1510 return new AESMC(machInst, vd, vm);
1511 } else {
1512 return new AESIMC(machInst, vd, vm);
1513 }
1514 case 0x8:
1515 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1516 q, size, machInst, vd, vm);
1517 case 0x9:
1518 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1519 q, size, machInst, vd, vm);
1520 case 0xa:
1521 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1522 q, size, machInst, vd, vm);
1523 case 0xb:
1524 if (q)
1525 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1526 else
1527 return new NVmvnD<uint64_t>(machInst, vd, vm);
1528 case 0xc:
1529 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1530 q, size, machInst, vd, vm);
1531 case 0xd:
1532 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1533 q, size, machInst, vd, vm);
1534 case 0xe:
1535 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1536 q, size, machInst, vd, vm);
1537 case 0xf:
1538 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1539 q, size, machInst, vd, vm);
1540 default:
1541 return new Unknown(machInst);
1542 }
1543 case 0x1:
1544 switch (bits(b, 3, 1)) {
1545 case 0x0:
1546 if (bits(b, 4)) {
1547 if (q) {
1548 return new NVcgtQFp<float>(machInst, vd, vm);
1549 } else {
1550 return new NVcgtDFp<float>(machInst, vd, vm);
1551 }
1552 } else {
1553 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1554 q, size, machInst, vd, vm);
1555 }
1556 case 0x1:
1557 if (bits(b, 4)) {
1558 if (q) {
1559 return new NVcgeQFp<float>(machInst, vd, vm);
1560 } else {
1561 return new NVcgeDFp<float>(machInst, vd, vm);
1562 }
1563 } else {
1564 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1565 q, size, machInst, vd, vm);
1566 }
1567 case 0x2:
1568 if (bits(b, 4)) {
1569 if (q) {
1570 return new NVceqQFp<float>(machInst, vd, vm);
1571 } else {
1572 return new NVceqDFp<float>(machInst, vd, vm);
1573 }
1574 } else {
1575 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1576 q, size, machInst, vd, vm);
1577 }
1578 case 0x3:
1579 if (bits(b, 4)) {
1580 if (q) {
1581 return new NVcleQFp<float>(machInst, vd, vm);
1582 } else {
1583 return new NVcleDFp<float>(machInst, vd, vm);
1584 }
1585 } else {
1586 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1587 q, size, machInst, vd, vm);
1588 }
1589 case 0x4:
1590 if (bits(b, 4)) {
1591 if (q) {
1592 return new NVcltQFp<float>(machInst, vd, vm);
1593 } else {
1594 return new NVcltDFp<float>(machInst, vd, vm);
1595 }
1596 } else {
1597 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1598 q, size, machInst, vd, vm);
1599 }
1600 case 0x5:
1601 if (q) {
1602 return new SHA1H(machInst, vd, vm);
1603 } else {
1604 return new Unknown(machInst);
1605 }
1606 case 0x6:
1607 if (bits(machInst, 10)) {
1608 if (q)
1609 return new NVabsQFp<float>(machInst, vd, vm);
1610 else
1611 return new NVabsDFp<float>(machInst, vd, vm);
1612 } else {
1613 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1614 q, size, machInst, vd, vm);
1615 }
1616 case 0x7:
1617 if (bits(machInst, 10)) {
1618 if (q)
1619 return new NVnegQFp<float>(machInst, vd, vm);
1620 else
1621 return new NVnegDFp<float>(machInst, vd, vm);
1622 } else {
1623 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1624 q, size, machInst, vd, vm);
1625 }
1626 default:
1627 return new Unknown64(machInst);
1628 }
1629 case 0x2:
1630 switch (bits(b, 4, 1)) {
1631 case 0x0:
1632 if (q)
1633 return new NVswpQ<uint64_t>(machInst, vd, vm);
1634 else
1635 return new NVswpD<uint64_t>(machInst, vd, vm);
1636 case 0x1:
1637 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1638 q, size, machInst, vd, vm);
1639 case 0x2:
1640 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1641 q, size, machInst, vd, vm);
1642 case 0x3:
1643 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1644 q, size, machInst, vd, vm);
1645 case 0x4:
1646 if (b == 0x8) {
1647 return decodeNeonUTwoMiscUSReg<NVmovn>(
1648 size, machInst, vd, vm);
1649 } else {
1650 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1651 size, machInst, vd, vm);
1652 }
1653 case 0x5:
1654 if (q) {
1655 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1656 size, machInst, vd, vm);
1657 } else {
1658 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1659 size, machInst, vd, vm);
1660 }
1661 case 0x6:
1662 if (b == 0xc) {
1663 return decodeNeonSTwoShiftUSReg<NVshll>(
1664 size, machInst, vd, vm, 8 << size);
1665 } else {
1666 return new Unknown(machInst);
1667 }
1668 case 0x7:
1669 if (q) {
1670 return new SHA256SU0(machInst, vd, vm);
1671 } else {
1672 return new SHA1SU1(machInst, vd, vm);
1673 }
1674 case 0xc:
1675 case 0xe:
1676 if (b == 0x18) {
1677 if (size != 1 || (vm % 2))
1678 return new Unknown(machInst);
1679 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1680 } else if (b == 0x1c) {
1681 if (size != 1 || (vd % 2))
1682 return new Unknown(machInst);
1683 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1684 } else {
1685 return new Unknown(machInst);
1686 }
1687 default:
1688 return new Unknown(machInst);
1689 }
1690 case 0x3:
1691 if (bits(b, 4, 3) == 0x3) {
1692 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1693 return new Unknown(machInst);
1694 } else {
1695 if (bits(b, 2)) {
1696 if (bits(b, 1)) {
1697 if (q) {
1698 return new NVcvt2ufxQ<float>(
1699 machInst, vd, vm, 0);
1700 } else {
1701 return new NVcvt2ufxD<float>(
1702 machInst, vd, vm, 0);
1703 }
1704 } else {
1705 if (q) {
1706 return new NVcvt2sfxQ<float>(
1707 machInst, vd, vm, 0);
1708 } else {
1709 return new NVcvt2sfxD<float>(
1710 machInst, vd, vm, 0);
1711 }
1712 }
1713 } else {
1714 if (bits(b, 1)) {
1715 if (q) {
1716 return new NVcvtu2fpQ<float>(
1717 machInst, vd, vm, 0);
1718 } else {
1719 return new NVcvtu2fpD<float>(
1720 machInst, vd, vm, 0);
1721 }
1722 } else {
1723 if (q) {
1724 return new NVcvts2fpQ<float>(
1725 machInst, vd, vm, 0);
1726 } else {
1727 return new NVcvts2fpD<float>(
1728 machInst, vd, vm, 0);
1729 }
1730 }
1731 }
1732 }
1733 } else if ((b & 0x1a) == 0x10) {
1734 if (bits(b, 2)) {
1735 if (q) {
1736 return new NVrecpeQFp<float>(machInst, vd, vm);
1737 } else {
1738 return new NVrecpeDFp<float>(machInst, vd, vm);
1739 }
1740 } else {
1741 if (q) {
1742 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1743 } else {
1744 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1745 }
1746 }
1747 } else if ((b & 0x1a) == 0x12) {
1748 if (bits(b, 2)) {
1749 if (q) {
1750 return new NVrsqrteQFp<float>(machInst, vd, vm);
1751 } else {
1752 return new NVrsqrteDFp<float>(machInst, vd, vm);
1753 }
1754 } else {
1755 if (q) {
1756 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1757 } else {
1758 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1759 }
1760 }
1761 } else {
1762 return new Unknown(machInst);
1763 }
1764 }
1765 return new Unknown(machInst);
1766 }
1767
1768 StaticInstPtr
1769 decodeNeonData(ExtMachInst machInst)
1770 {
1771 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1772 const uint32_t a = bits(machInst, 23, 19);
1773 const uint32_t q = bits(machInst, 11, 8);
1774 const uint32_t c = bits(machInst, 7, 4);
1775 if (bits(a, 4) == 0) {
1776 return decodeNeonThreeRegistersSameLength(machInst);
1777 } else if ((c & 0x9) == 1) {
1778 if ((a & 0x7) == 0) {
1779 return decodeNeonOneRegModImm(machInst);
1780 } else {
1781 return decodeNeonTwoRegAndShift(machInst);
1782 }
1783 } else if ((c & 0x9) == 9) {
1784 return decodeNeonTwoRegAndShift(machInst);
1785 } else if (bits(a, 2, 1) != 0x3) {
1786 if ((c & 0x5) == 0) {
1787 return decodeNeonThreeRegDiffLengths(machInst);
1788 } else if ((c & 0x5) == 4) {
1789 return decodeNeonTwoRegScalar(machInst);
1790 }
1791 } else if ((a & 0x16) == 0x16) {
1792 const IntRegIndex vd =
1793 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1794 (bits(machInst, 22) << 4)));
1795 const IntRegIndex vn =
1796 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1797 (bits(machInst, 7) << 4)));
1798 const IntRegIndex vm =
1799 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1800 (bits(machInst, 5) << 4)));
1801 if (!u) {
1802 if (bits(c, 0) == 0) {
1803 unsigned imm4 = bits(machInst, 11, 8);
1804 bool q = bits(machInst, 6);
1805 if (imm4 >= 16 && !q)
1806 return new Unknown(machInst);
1807 if (q) {
1808 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1809 } else {
1810 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1811 }
1812 }
1813 } else if (bits(q, 3) == 0 && bits(c, 0) == 0) {
1814 return decodeNeonTwoRegMisc(machInst);
1815 } else if (bits(q, 3, 2) == 0x2 && bits(c, 0) == 0) {
1816 unsigned length = bits(machInst, 9, 8) + 1;
1817 if ((uint32_t)vn / 2 + length > 32)
1818 return new Unknown(machInst);
1819 if (bits(machInst, 6) == 0) {
1820 switch (length) {
1821 case 1:
1822 return new NVtbl1(machInst, vd, vn, vm);
1823 case 2:
1824 return new NVtbl2(machInst, vd, vn, vm);
1825 case 3:
1826 return new NVtbl3(machInst, vd, vn, vm);
1827 case 4:
1828 return new NVtbl4(machInst, vd, vn, vm);
1829 }
1830 } else {
1831 switch (length) {
1832 case 1:
1833 return new NVtbx1(machInst, vd, vn, vm);
1834 case 2:
1835 return new NVtbx2(machInst, vd, vn, vm);
1836 case 3:
1837 return new NVtbx3(machInst, vd, vn, vm);
1838 case 4:
1839 return new NVtbx4(machInst, vd, vn, vm);
1840 }
1841 }
1842 } else if (q == 0xc && (c & 0x9) == 0) {
1843 unsigned imm4 = bits(machInst, 19, 16);
1844 if (bits(imm4, 2, 0) == 0)
1845 return new Unknown(machInst);
1846 unsigned size = 0;
1847 while ((imm4 & 0x1) == 0) {
1848 size++;
1849 imm4 >>= 1;
1850 }
1851 unsigned index = imm4 >> 1;
1852 const bool q = bits(machInst, 6);
1853 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1854 q, size, machInst, vd, vm, index);
1855 }
1856 }
1857 return new Unknown(machInst);
1858 }
1859 '''
1860}};
1861
1862def format ThumbNeonMem() {{
1863 decode_block = '''
1864 return decodeNeonMem(machInst);
1865 '''
1866}};
1867
1868def format ThumbNeonData() {{
1869 decode_block = '''
1870 return decodeNeonData(machInst);
1871 '''
1872}};
1873
1874let {{
1875 header_output = '''
1876 StaticInstPtr
1877 decodeExtensionRegLoadStore(ExtMachInst machInst);
1878 '''
1879 decoder_output = '''
1880 StaticInstPtr
1881 decodeExtensionRegLoadStore(ExtMachInst machInst)
1882 {
1883 const uint32_t opcode = bits(machInst, 24, 20);
1884 const uint32_t offset = bits(machInst, 7, 0);
1885 const bool single = (bits(machInst, 8) == 0);
1886 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1887 RegIndex vd;
1888 if (single) {
1889 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1890 bits(machInst, 22));
1891 } else {
1892 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1893 (bits(machInst, 22) << 5));
1894 }
1895 switch (bits(opcode, 4, 3)) {
1896 case 0x0:
1897 if (bits(opcode, 4, 1) == 0x2 &&
1898 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1899 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1900 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1901 break;
1902 }
1903 const IntRegIndex rt =
1904 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1905 const IntRegIndex rt2 =
1906 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1907 const bool op = bits(machInst, 20);
1908 uint32_t vm;
1909 if (single) {
1910 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1911 } else {
1912 vm = (bits(machInst, 3, 0) << 1) |
1913 (bits(machInst, 5) << 5);
1914 }
1915 if (op) {
1916 return new Vmov2Core2Reg(machInst, rt, rt2,
1917 (IntRegIndex)vm);
1918 } else {
1919 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1920 rt, rt2);
1921 }
1922 }
1923 break;
1924 case 0x1:
1925 {
1926 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1927 break;
1928 }
1929 switch (bits(opcode, 1, 0)) {
1930 case 0x0:
1931 return new VLdmStm(machInst, rn, vd, single,
1932 true, false, false, offset);
1933 case 0x1:
1934 return new VLdmStm(machInst, rn, vd, single,
1935 true, false, true, offset);
1936 case 0x2:
1937 return new VLdmStm(machInst, rn, vd, single,
1938 true, true, false, offset);
1939 case 0x3:
1940 // If rn == sp, then this is called vpop.
1941 return new VLdmStm(machInst, rn, vd, single,
1942 true, true, true, offset);
1943 default:
1944 M5_UNREACHABLE;
1945 }
1946 }
1947 case 0x2:
1948 if (bits(opcode, 1, 0) == 0x2) {
1949 // If rn == sp, then this is called vpush.
1950 return new VLdmStm(machInst, rn, vd, single,
1951 false, true, false, offset);
1952 } else if (bits(opcode, 1, 0) == 0x3) {
1953 return new VLdmStm(machInst, rn, vd, single,
1954 false, true, true, offset);
1955 }
1956 M5_FALLTHROUGH;
1957 case 0x3:
1958 const bool up = (bits(machInst, 23) == 1);
1959 const uint32_t imm = bits(machInst, 7, 0) << 2;
1960 if (single) {
1961 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1962 (bits(machInst, 22)));
1963 } else {
1964 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1965 (bits(machInst, 22) << 5));
1966 }
1967 if (bits(opcode, 1, 0) == 0x0) {
1968 if (single) {
1969 if (up) {
1970 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1971 } else {
1972 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1973 }
1974 } else {
1975 if (up) {
1976 return new %(vstr_ud)s(machInst, vd, vd + 1,
1977 rn, up, imm);
1978 } else {
1979 return new %(vstr_d)s(machInst, vd, vd + 1,
1980 rn, up, imm);
1981 }
1982 }
1983 } else if (bits(opcode, 1, 0) == 0x1) {
1984 if (single) {
1985 if (up) {
1986 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1987 } else {
1988 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1989 }
1990 } else {
1991 if (up) {
1992 return new %(vldr_ud)s(machInst, vd, vd + 1,
1993 rn, up, imm);
1994 } else {
1995 return new %(vldr_d)s(machInst, vd, vd + 1,
1996 rn, up, imm);
1997 }
1998 }
1999 }
2000 }
2001 return new Unknown(machInst);
2002 }
2003 ''' % {
2004 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
2005 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
2006 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
2007 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
2008 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
2009 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
2010 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
2011 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
2012 }
2013}};
2014
2015def format ExtensionRegLoadStore() {{
2016 decode_block = '''
2017 return decodeExtensionRegLoadStore(machInst);
2018 '''
2019}};
2020
2021let {{
2022 header_output = '''
2023 StaticInstPtr
2024 decodeShortFpTransfer(ExtMachInst machInst);
2025 '''
2026 decoder_output = '''
2027 IntRegIndex decodeFpVd(ExtMachInst machInst, uint32_t size, bool isInt)
2028 {
2029 if (!isInt and size == 3) {
2030 return (IntRegIndex)((bits(machInst, 22) << 5) |
2031 (bits(machInst, 15, 12) << 1));
2032 } else {
2033 return (IntRegIndex)(bits(machInst, 22) |
2034 (bits(machInst, 15, 12) << 1));
2035 }
2036 }
2037
2038 IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2039 {
2040 if (!isInt and size == 3) {
2041 return (IntRegIndex)((bits(machInst, 5) << 5) |
2042 (bits(machInst, 3, 0) << 1));
2043 } else {
2044 return (IntRegIndex)(bits(machInst, 5) |
2045 (bits(machInst, 3, 0) << 1));
2046 }
2047 }
2048
2049 IntRegIndex decodeFpVn(ExtMachInst machInst, uint32_t size)
2050 {
2051 if (size == 3) {
2052 return (IntRegIndex)((bits(machInst, 7) << 5) |
2053 (bits(machInst, 19, 16) << 1));
2054 } else {
2055 return (IntRegIndex)(bits(machInst, 7) |
2056 (bits(machInst, 19, 16) << 1));
2057 }
2058 }
2059
2060 StaticInstPtr
2061 decodeFloatingPointDataProcessing(ExtMachInst machInst) {
2062 const uint32_t op0 = bits(machInst, 23, 20);
2063 const uint32_t op1 = bits(machInst, 19, 16);
2064 const uint32_t op2 = bits(machInst, 9, 8);
2065 const uint32_t op3 = bits(machInst, 6);
2066 const uint32_t rm = bits(machInst, 17, 16);
2067 const uint32_t size = bits(machInst, 9, 8);
2068 IntRegIndex vd = decodeFpVd(machInst, size, false);
2069 IntRegIndex vm = decodeFpVm(machInst, size, false);
2070 IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2071 IntRegIndex vn = decodeFpVn(machInst, size);
2072 if (bits(machInst, 31, 24) == 0xFE && !bits(machInst, 4)) {
2073 if (bits(op0, 3) == 0 && op2 != 0 && !op3){
2074 ConditionCode cond;
2075 switch(bits(machInst, 21, 20)) {
2076 case 0x0: cond = COND_EQ; break;
2077 case 0x1: cond = COND_VS; break;
2078 case 0x2: cond = COND_GE; break;
2079 case 0x3: cond = COND_GT; break;
2080 }
2081 if (size == 3) {
2082 return new VselD(machInst, vd, vn, vm, cond);
2083 } else {
2084 return new VselS(machInst, vd, vn, vm, cond);
2085 }
2086 } else if (bits(op0, 3) == 1 && bits(op0, 1, 0) == 0 && op2 != 0) {
2087 const bool op = bits(machInst, 6);
2088 if (op) {
2089 if (size == 1) {
2090 return new FailUnimplemented("vminnm.f16", machInst);
2091 }
2092 return decodeNeonSizeSingleDouble<VminnmS, VminnmD>(
2093 size, machInst, vd, vn, vm);
2094 } else {
2095 if (size == 1) {
2096 return new FailUnimplemented("vmaxnm.f16", machInst);
2097 }
2098 return decodeNeonSizeSingleDouble<VmaxnmS, VmaxnmD>(
2099 size, machInst, vd, vn, vm);
2100 }
2101 } else if (bits(op0, 3) && bits(op0, 1, 0) == 3 &&
2102 bits(op1, 3) && op2 != 0 && op3)
2103 {
2104 const uint32_t o1 = bits(machInst, 18);
2105 if (o1 == 0) {
2106 if (size == 3) {
2107 switch(rm) {
2108 case 0x0:
2109 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2110 true);
2111 case 0x1:
2112 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2113 true);
2114 case 0x2:
2115 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
2116 true);
2117 case 0x3:
2118 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
2119 true);
2120 default: return new Unknown(machInst);
2121 }
2122 } else {
2123 switch(rm) {
2124 case 0x0:
2125 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
2126 false);
2127 case 0x1:
2128 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2129 false);
2130 case 0x2:
2131 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2132 false);
2133 case 0x3:
2134 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2135 false);
2136 default: return new Unknown(machInst);
2137 }
2138 }
2139 } else {
2140 const bool op = bits(machInst, 7);
2141 switch(rm) {
2142 case 0x0:
2143 switch(size) {
2144 case 0x0:
2145 return new Unknown(machInst);
2146 case 0x1:
2147 return new FailUnimplemented(
2148 "vcvta.u32.f16", machInst);
2149 case 0x2:
2150 if (op) {
2151 return new VcvtaFpSIntS(machInst, vdInt, vm);
2152 } else {
2153 return new VcvtaFpUIntS(machInst, vdInt, vm);
2154 }
2155 case 0x3:
2156 if (op) {
2157 return new VcvtaFpSIntD(machInst, vdInt, vm);
2158 } else {
2159 return new VcvtaFpUIntD(machInst, vdInt, vm);
2160 }
2161 default: return new Unknown(machInst);
2162 }
2163 case 0x1:
2164 switch(size) {
2165 case 0x0:
2166 return new Unknown(machInst);
2167 case 0x1:
2168 return new FailUnimplemented(
2169 "vcvtn.u32.f16", machInst);
2170 case 0x2:
2171 if (op) {
2172 return new VcvtnFpSIntS(machInst, vdInt, vm);
2173 } else {
2174 return new VcvtnFpUIntS(machInst, vdInt, vm);
2175 }
2176 case 0x3:
2177 if (op) {
2178 return new VcvtnFpSIntD(machInst, vdInt, vm);
2179 } else {
2180 return new VcvtnFpUIntD(machInst, vdInt, vm);
2181 }
2182 default: return new Unknown(machInst);
2183 }
2184 case 0x2:
2185 switch(size) {
2186 case 0x0:
2187 return new Unknown(machInst);
2188 case 0x1:
2189 return new FailUnimplemented(
2190 "vcvtp.u32.f16", machInst);
2191 case 0x2:
2192 if (op) {
2193 return new VcvtpFpSIntS(machInst, vdInt, vm);
2194 } else {
2195 return new VcvtpFpUIntS(machInst, vdInt, vm);
2196 }
2197 case 0x3:
2198 if (op) {
2199 return new VcvtpFpSIntD(machInst, vdInt, vm);
2200 } else {
2201 return new VcvtpFpUIntD(machInst, vdInt, vm);
2202 }
2203 default: return new Unknown(machInst);
2204 }
2205 case 0x3:
2206 switch(size) {
2207 case 0x0:
2208 return new Unknown(machInst);
2209 case 0x1:
2210 return new FailUnimplemented(
2211 "vcvtm.u32.f16", machInst);
2212 case 0x2:
2213 if (op) {
2214 return new VcvtmFpSIntS(machInst, vdInt, vm);
2215 } else {
2216 return new VcvtmFpUIntS(machInst, vdInt, vm);
2217 }
2218 case 0x3:
2219 if (op) {
2220 return new VcvtmFpSIntD(machInst, vdInt, vm);
2221 } else {
2222 return new VcvtmFpUIntD(machInst, vdInt, vm);
2223 }
2224 default: return new Unknown(machInst);
2225 }
2226 default: return new Unknown(machInst);
2227 }
2228 }
2229 } else {
2230 return new Unknown(machInst);
2231 }
2232 } else {
2233 return new Unknown(machInst);
2234 }
2235 }
2236
2237 StaticInstPtr
2238 decodeShortFpTransfer(ExtMachInst machInst)
2239 {
2240 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2241 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2242 return decodeFloatingPointDataProcessing(machInst);
2243 }
2244 const uint32_t l = bits(machInst, 20);
2245 const uint32_t c = bits(machInst, 8);
2246 const uint32_t a = bits(machInst, 23, 21);
2247 const uint32_t q = bits(machInst, 6, 5);
2248 if (l == 0 && c == 0) {
2249 if (a == 0) {
2250 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2251 bits(machInst, 7);
2252 const IntRegIndex rt =
2253 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2254 if (bits(machInst, 20) == 1) {
2255 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2256 } else {
2257 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2258 }
2259 } else if (a == 0x7) {
2260 const IntRegIndex rt =
2261 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2262 uint32_t reg = bits(machInst, 19, 16);
2263 uint32_t specReg;
2264 switch (reg) {
2265 case 0:
2266 specReg = MISCREG_FPSID;
2267 break;
2268 case 1:
2269 specReg = MISCREG_FPSCR;
2270 break;
2271 case 6:
2272 specReg = MISCREG_MVFR1;
2273 break;
2274 case 7:
2275 specReg = MISCREG_MVFR0;
2276 break;
2277 case 8:
2278 specReg = MISCREG_FPEXC;
2279 break;
2280 default:
2281 return new Unknown(machInst);
2282 }
2283 if (specReg == MISCREG_FPSCR) {
2284 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2285 } else {
2286 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2287 reg, a, bits(machInst, 7, 5));
2288 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2289 }
2290 }
2291 } else if (l == 0 && c == 1) {
2292 if (bits(a, 2) == 0) {
2293 uint32_t vd = (bits(machInst, 7) << 5) |
2294 (bits(machInst, 19, 16) << 1);
2295 // Handle accessing each single precision half of the vector.
2296 vd += bits(machInst, 21);
2297 const IntRegIndex rt =
2298 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2299 if (bits(machInst, 22) == 1) {
2300 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2301 rt, bits(machInst, 6, 5));
2302 } else if (bits(machInst, 5) == 1) {
2303 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2304 rt, bits(machInst, 6));
2305 } else if (bits(machInst, 6) == 0) {
2306 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2307 } else {
2308 return new Unknown(machInst);
2309 }
2310 } else if (bits(q, 1) == 0) {
2311 bool q = bits(machInst, 21);
2312 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2313 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2314 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2315 IntRegIndex rt = (IntRegIndex)(uint32_t)
2316 bits(machInst, 15, 12);
2317 if (q) {
2318 switch (be) {
2319 case 0:
2320 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2321 case 1:
2322 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2323 case 2:
2324 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2325 case 3:
2326 return new Unknown(machInst);
2327 }
2328 } else {
2329 switch (be) {
2330 case 0:
2331 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2332 case 1:
2333 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2334 case 2:
2335 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2336 case 3:
2337 return new Unknown(machInst);
2338 }
2339 }
2340 }
2341 } else if (l == 1 && c == 0) {
2342 if (a == 0) {
2343 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2344 bits(machInst, 7);
2345 const IntRegIndex rt =
2346 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2347 if (bits(machInst, 20) == 1) {
2348 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2349 } else {
2350 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2351 }
2352 } else if (a == 7) {
2353 const IntRegIndex rt =
2354 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2355 uint32_t reg = bits(machInst, 19, 16);
2356 uint32_t specReg;
2357 switch (reg) {
2358 case 0:
2359 specReg = MISCREG_FPSID;
2360 break;
2361 case 1:
2362 specReg = MISCREG_FPSCR;
2363 break;
2364 case 6:
2365 specReg = MISCREG_MVFR1;
2366 break;
2367 case 7:
2368 specReg = MISCREG_MVFR0;
2369 break;
2370 case 8:
2371 specReg = MISCREG_FPEXC;
2372 break;
2373 default:
2374 return new Unknown(machInst);
2375 }
2376 if (rt == 0xf) {
2377 if (specReg == MISCREG_FPSCR) {
2378 return new VmrsApsrFpscr(machInst);
2379 } else {
2380 return new Unknown(machInst);
2381 }
2382 } else if (specReg == MISCREG_FPSCR) {
2383 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2384 } else {
2385 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2386 reg, a, bits(machInst, 7, 5));
2387 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2388 }
2389 }
2390 } else {
2391 uint32_t vd = (bits(machInst, 7) << 5) |
2392 (bits(machInst, 19, 16) << 1);
2393 // Handle indexing into each single precision half of the vector.
2394 vd += bits(machInst, 21);
2395 uint32_t index;
2396 const IntRegIndex rt =
2397 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2398 const bool u = (bits(machInst, 23) == 1);
2399 if (bits(machInst, 22) == 1) {
2400 index = bits(machInst, 6, 5);
2401 if (u) {
2402 return new VmovRegCoreUB(machInst, rt,
2403 (IntRegIndex)vd, index);
2404 } else {
2405 return new VmovRegCoreSB(machInst, rt,
2406 (IntRegIndex)vd, index);
2407 }
2408 } else if (bits(machInst, 5) == 1) {
2409 index = bits(machInst, 6);
2410 if (u) {
2411 return new VmovRegCoreUH(machInst, rt,
2412 (IntRegIndex)vd, index);
2413 } else {
2414 return new VmovRegCoreSH(machInst, rt,
2415 (IntRegIndex)vd, index);
2416 }
2417 } else if (bits(machInst, 6) == 0 && !u) {
2418 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2419 } else {
2420 return new Unknown(machInst);
2421 }
2422 }
2423 return new Unknown(machInst);
2424 }
2425 '''
2426}};
2427
2428def format ShortFpTransfer() {{
2429 decode_block = '''
2430 return decodeShortFpTransfer(machInst);
2431 '''
2432}};
2433
2434let {{
2435 header_output = '''
2436 StaticInstPtr
2437 decodeVfpData(ExtMachInst machInst);
2438 '''
2439 decoder_output = '''
2440 StaticInstPtr
2441 decodeVfpData(ExtMachInst machInst)
2442 {
2443 const uint32_t opc1 = bits(machInst, 23, 20);
2444 const uint32_t opc2 = bits(machInst, 19, 16);
2445 const uint32_t opc3 = bits(machInst, 7, 6);
2446 //const uint32_t opc4 = bits(machInst, 3, 0);
2447 const bool single = (bits(machInst, 8) == 0);
2448 // Used to select between vcmp and vcmpe.
2449 const bool e = (bits(machInst, 7) == 1);
2450 IntRegIndex vd;
2451 IntRegIndex vm;
2452 IntRegIndex vn;
2453 if (single) {
2454 vd = (IntRegIndex)(bits(machInst, 22) |
2455 (bits(machInst, 15, 12) << 1));
2456 vm = (IntRegIndex)(bits(machInst, 5) |
2457 (bits(machInst, 3, 0) << 1));
2458 vn = (IntRegIndex)(bits(machInst, 7) |
2459 (bits(machInst, 19, 16) << 1));
2460 } else {
2461 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2462 (bits(machInst, 15, 12) << 1));
2463 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2464 (bits(machInst, 3, 0) << 1));
2465 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2466 (bits(machInst, 19, 16) << 1));
2467 }
2468 switch (opc1 & 0xb /* 1011 */) {
2469 case 0x0:
2470 if (bits(machInst, 6) == 0) {
2471 if (single) {
2472 return decodeVfpRegRegRegOp<VmlaS>(
2473 machInst, vd, vn, vm, false);
2474 } else {
2475 return decodeVfpRegRegRegOp<VmlaD>(
2476 machInst, vd, vn, vm, true);
2477 }
2478 } else {
2479 if (single) {
2480 return decodeVfpRegRegRegOp<VmlsS>(
2481 machInst, vd, vn, vm, false);
2482 } else {
2483 return decodeVfpRegRegRegOp<VmlsD>(
2484 machInst, vd, vn, vm, true);
2485 }
2486 }
2487 case 0x1:
2488 if (bits(machInst, 6) == 1) {
2489 if (single) {
2490 return decodeVfpRegRegRegOp<VnmlaS>(
2491 machInst, vd, vn, vm, false);
2492 } else {
2493 return decodeVfpRegRegRegOp<VnmlaD>(
2494 machInst, vd, vn, vm, true);
2495 }
2496 } else {
2497 if (single) {
2498 return decodeVfpRegRegRegOp<VnmlsS>(
2499 machInst, vd, vn, vm, false);
2500 } else {
2501 return decodeVfpRegRegRegOp<VnmlsD>(
2502 machInst, vd, vn, vm, true);
2503 }
2504 }
2505 case 0x2:
2506 if ((opc3 & 0x1) == 0) {
2507 if (single) {
2508 return decodeVfpRegRegRegOp<VmulS>(
2509 machInst, vd, vn, vm, false);
2510 } else {
2511 return decodeVfpRegRegRegOp<VmulD>(
2512 machInst, vd, vn, vm, true);
2513 }
2514 } else {
2515 if (single) {
2516 return decodeVfpRegRegRegOp<VnmulS>(
2517 machInst, vd, vn, vm, false);
2518 } else {
2519 return decodeVfpRegRegRegOp<VnmulD>(
2520 machInst, vd, vn, vm, true);
2521 }
2522 }
2523 case 0x3:
2524 if ((opc3 & 0x1) == 0) {
2525 if (single) {
2526 return decodeVfpRegRegRegOp<VaddS>(
2527 machInst, vd, vn, vm, false);
2528 } else {
2529 return decodeVfpRegRegRegOp<VaddD>(
2530 machInst, vd, vn, vm, true);
2531 }
2532 } else {
2533 if (single) {
2534 return decodeVfpRegRegRegOp<VsubS>(
2535 machInst, vd, vn, vm, false);
2536 } else {
2537 return decodeVfpRegRegRegOp<VsubD>(
2538 machInst, vd, vn, vm, true);
2539 }
2540 }
2541 case 0x8:
2542 if (machInst.condCode == 0xF) {
2543 const bool op = bits(machInst, 6);
2544 const uint32_t size = bits(machInst, 9, 8);
2545 if (op) {
2546 if (size == 1) {
2547 return new FailUnimplemented("vminnm.f16", machInst);
2548 }
2549 return decodeNeonSizeSingleDouble<VminnmS, VminnmD>(
2550 size, machInst, vd, vn, vm);
2551 } else {
2552 if (size == 1) {
2553 return new FailUnimplemented("vmaxnm.f16", machInst);
2554 }
2555 return decodeNeonSizeSingleDouble<VmaxnmS, VmaxnmD>(
2556 size, machInst, vd, vn, vm);
2557 }
2558 }
2542 if ((opc3 & 0x1) == 0) {
2543 if (single) {
2544 return decodeVfpRegRegRegOp<VdivS>(
2545 machInst, vd, vn, vm, false);
2546 } else {
2547 return decodeVfpRegRegRegOp<VdivD>(
2548 machInst, vd, vn, vm, true);
2549 }
2550 }
2551 break;
2552 case 0x9:
2553 if ((opc3 & 0x1) == 0) {
2554 if (single) {
2555 return decodeVfpRegRegRegOp<VfnmaS>(
2556 machInst, vd, vn, vm, false);
2557 } else {
2558 return decodeVfpRegRegRegOp<VfnmaD>(
2559 machInst, vd, vn, vm, true);
2560 }
2561 } else {
2562 if (single) {
2563 return decodeVfpRegRegRegOp<VfnmsS>(
2564 machInst, vd, vn, vm, false);
2565 } else {
2566 return decodeVfpRegRegRegOp<VfnmsD>(
2567 machInst, vd, vn, vm, true);
2568 }
2569 }
2570 break;
2571 case 0xa:
2572 if ((opc3 & 0x1) == 0) {
2573 if (single) {
2574 return decodeVfpRegRegRegOp<VfmaS>(
2575 machInst, vd, vn, vm, false);
2576 } else {
2577 return decodeVfpRegRegRegOp<VfmaD>(
2578 machInst, vd, vn, vm, true);
2579 }
2580 } else {
2581 if (single) {
2582 return decodeVfpRegRegRegOp<VfmsS>(
2583 machInst, vd, vn, vm, false);
2584 } else {
2585 return decodeVfpRegRegRegOp<VfmsD>(
2586 machInst, vd, vn, vm, true);
2587 }
2588 }
2589 break;
2590 case 0xb:
2591 if ((opc3 & 0x1) == 0) {
2592 const uint32_t baseImm =
2593 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2594 if (single) {
2595 uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32);
2596 return decodeVfpRegImmOp<VmovImmS>(
2597 machInst, vd, imm, false);
2598 } else {
2599 uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64);
2600 return decodeVfpRegImmOp<VmovImmD>(
2601 machInst, vd, imm, true);
2602 }
2603 }
2604 switch (opc2) {
2605 case 0x0:
2606 if (opc3 == 1) {
2607 if (single) {
2608 return decodeVfpRegRegOp<VmovRegS>(
2609 machInst, vd, vm, false);
2610 } else {
2611 return decodeVfpRegRegOp<VmovRegD>(
2612 machInst, vd, vm, true);
2613 }
2614 } else {
2615 if (single) {
2616 return decodeVfpRegRegOp<VabsS>(
2617 machInst, vd, vm, false);
2618 } else {
2619 return decodeVfpRegRegOp<VabsD>(
2620 machInst, vd, vm, true);
2621 }
2622 }
2623 case 0x1:
2624 if (opc3 == 1) {
2625 if (single) {
2626 return decodeVfpRegRegOp<VnegS>(
2627 machInst, vd, vm, false);
2628 } else {
2629 return decodeVfpRegRegOp<VnegD>(
2630 machInst, vd, vm, true);
2631 }
2632 } else {
2633 if (single) {
2634 return decodeVfpRegRegOp<VsqrtS>(
2635 machInst, vd, vm, false);
2636 } else {
2637 return decodeVfpRegRegOp<VsqrtD>(
2638 machInst, vd, vm, true);
2639 }
2640 }
2641 case 0x2:
2642 case 0x3:
2643 {
2644 const bool toHalf = bits(machInst, 16);
2645 const bool top = bits(machInst, 7);
2646 if (top) {
2647 if (toHalf) {
2648 return new VcvtFpSFpHT(machInst, vd, vm);
2649 } else {
2650 return new VcvtFpHTFpS(machInst, vd, vm);
2651 }
2652 } else {
2653 if (toHalf) {
2654 return new VcvtFpSFpHB(machInst, vd, vm);
2655 } else {
2656 return new VcvtFpHBFpS(machInst, vd, vm);
2657 }
2658 }
2659 }
2660 case 0x4:
2661 if (single) {
2662 if (e) {
2663 return new VcmpeS(machInst, vd, vm);
2664 } else {
2665 return new VcmpS(machInst, vd, vm);
2666 }
2667 } else {
2668 if (e) {
2669 return new VcmpeD(machInst, vd, vm);
2670 } else {
2671 return new VcmpD(machInst, vd, vm);
2672 }
2673 }
2674 case 0x5:
2675 if (single) {
2676 if (e) {
2677 return new VcmpeZeroS(machInst, vd, 0);
2678 } else {
2679 return new VcmpZeroS(machInst, vd, 0);
2680 }
2681 } else {
2682 if (e) {
2683 return new VcmpeZeroD(machInst, vd, 0);
2684 } else {
2685 return new VcmpZeroD(machInst, vd, 0);
2686 }
2687 }
2688 case 0x7:
2689 if (opc3 == 0x3) {
2690 if (single) {
2691 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2692 (bits(machInst, 15, 12) << 1));
2693 return new VcvtFpSFpD(machInst, vd, vm);
2694 } else {
2695 vd = (IntRegIndex)(bits(machInst, 22) |
2696 (bits(machInst, 15, 12) << 1));
2697 return new VcvtFpDFpS(machInst, vd, vm);
2698 }
2699 }
2700 break;
2701 case 0x8:
2702 if (bits(machInst, 7) == 0) {
2703 if (single) {
2704 return new VcvtUIntFpS(machInst, vd, vm);
2705 } else {
2706 vm = (IntRegIndex)(bits(machInst, 5) |
2707 (bits(machInst, 3, 0) << 1));
2708 return new VcvtUIntFpD(machInst, vd, vm);
2709 }
2710 } else {
2711 if (single) {
2712 return new VcvtSIntFpS(machInst, vd, vm);
2713 } else {
2714 vm = (IntRegIndex)(bits(machInst, 5) |
2715 (bits(machInst, 3, 0) << 1));
2716 return new VcvtSIntFpD(machInst, vd, vm);
2717 }
2718 }
2719 case 0xa:
2720 {
2721 const bool half = (bits(machInst, 7) == 0);
2722 const uint32_t imm = bits(machInst, 5) |
2723 (bits(machInst, 3, 0) << 1);
2724 const uint32_t size =
2725 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2726 if (single) {
2727 if (half) {
2728 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2729 } else {
2730 return new VcvtSFixedFpS(machInst, vd, vd, size);
2731 }
2732 } else {
2733 if (half) {
2734 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2735 } else {
2736 return new VcvtSFixedFpD(machInst, vd, vd, size);
2737 }
2738 }
2739 }
2740 case 0xb:
2741 {
2742 const bool half = (bits(machInst, 7) == 0);
2743 const uint32_t imm = bits(machInst, 5) |
2744 (bits(machInst, 3, 0) << 1);
2745 const uint32_t size =
2746 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2747 if (single) {
2748 if (half) {
2749 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2750 } else {
2751 return new VcvtUFixedFpS(machInst, vd, vd, size);
2752 }
2753 } else {
2754 if (half) {
2755 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2756 } else {
2757 return new VcvtUFixedFpD(machInst, vd, vd, size);
2758 }
2759 }
2760 }
2761 case 0xc:
2762 if (bits(machInst, 7) == 0) {
2763 if (single) {
2764 return new VcvtFpUIntSR(machInst, vd, vm);
2765 } else {
2766 vd = (IntRegIndex)(bits(machInst, 22) |
2767 (bits(machInst, 15, 12) << 1));
2768 return new VcvtFpUIntDR(machInst, vd, vm);
2769 }
2770 } else {
2771 if (single) {
2772 return new VcvtFpUIntS(machInst, vd, vm);
2773 } else {
2774 vd = (IntRegIndex)(bits(machInst, 22) |
2775 (bits(machInst, 15, 12) << 1));
2776 return new VcvtFpUIntD(machInst, vd, vm);
2777 }
2778 }
2779 case 0xd:
2780 if (bits(machInst, 7) == 0) {
2781 if (single) {
2782 return new VcvtFpSIntSR(machInst, vd, vm);
2783 } else {
2784 vd = (IntRegIndex)(bits(machInst, 22) |
2785 (bits(machInst, 15, 12) << 1));
2786 return new VcvtFpSIntDR(machInst, vd, vm);
2787 }
2788 } else {
2789 if (single) {
2790 return new VcvtFpSIntS(machInst, vd, vm);
2791 } else {
2792 vd = (IntRegIndex)(bits(machInst, 22) |
2793 (bits(machInst, 15, 12) << 1));
2794 return new VcvtFpSIntD(machInst, vd, vm);
2795 }
2796 }
2797 case 0xe:
2798 {
2799 const bool half = (bits(machInst, 7) == 0);
2800 const uint32_t imm = bits(machInst, 5) |
2801 (bits(machInst, 3, 0) << 1);
2802 const uint32_t size =
2803 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2804 if (single) {
2805 if (half) {
2806 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2807 } else {
2808 return new VcvtFpSFixedS(machInst, vd, vd, size);
2809 }
2810 } else {
2811 if (half) {
2812 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2813 } else {
2814 return new VcvtFpSFixedD(machInst, vd, vd, size);
2815 }
2816 }
2817 }
2818 case 0xf:
2819 {
2820 const bool half = (bits(machInst, 7) == 0);
2821 const uint32_t imm = bits(machInst, 5) |
2822 (bits(machInst, 3, 0) << 1);
2823 const uint32_t size =
2824 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2825 if (single) {
2826 if (half) {
2827 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2828 } else {
2829 return new VcvtFpUFixedS(machInst, vd, vd, size);
2830 }
2831 } else {
2832 if (half) {
2833 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2834 } else {
2835 return new VcvtFpUFixedD(machInst, vd, vd, size);
2836 }
2837 }
2838 }
2839 }
2840 break;
2841 }
2842 return new Unknown(machInst);
2843 }
2844 '''
2845}};
2846
2847def format VfpData() {{
2848 decode_block = '''
2849 return decodeVfpData(machInst);
2850 '''
2851}};
2559 if ((opc3 & 0x1) == 0) {
2560 if (single) {
2561 return decodeVfpRegRegRegOp<VdivS>(
2562 machInst, vd, vn, vm, false);
2563 } else {
2564 return decodeVfpRegRegRegOp<VdivD>(
2565 machInst, vd, vn, vm, true);
2566 }
2567 }
2568 break;
2569 case 0x9:
2570 if ((opc3 & 0x1) == 0) {
2571 if (single) {
2572 return decodeVfpRegRegRegOp<VfnmaS>(
2573 machInst, vd, vn, vm, false);
2574 } else {
2575 return decodeVfpRegRegRegOp<VfnmaD>(
2576 machInst, vd, vn, vm, true);
2577 }
2578 } else {
2579 if (single) {
2580 return decodeVfpRegRegRegOp<VfnmsS>(
2581 machInst, vd, vn, vm, false);
2582 } else {
2583 return decodeVfpRegRegRegOp<VfnmsD>(
2584 machInst, vd, vn, vm, true);
2585 }
2586 }
2587 break;
2588 case 0xa:
2589 if ((opc3 & 0x1) == 0) {
2590 if (single) {
2591 return decodeVfpRegRegRegOp<VfmaS>(
2592 machInst, vd, vn, vm, false);
2593 } else {
2594 return decodeVfpRegRegRegOp<VfmaD>(
2595 machInst, vd, vn, vm, true);
2596 }
2597 } else {
2598 if (single) {
2599 return decodeVfpRegRegRegOp<VfmsS>(
2600 machInst, vd, vn, vm, false);
2601 } else {
2602 return decodeVfpRegRegRegOp<VfmsD>(
2603 machInst, vd, vn, vm, true);
2604 }
2605 }
2606 break;
2607 case 0xb:
2608 if ((opc3 & 0x1) == 0) {
2609 const uint32_t baseImm =
2610 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2611 if (single) {
2612 uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32);
2613 return decodeVfpRegImmOp<VmovImmS>(
2614 machInst, vd, imm, false);
2615 } else {
2616 uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64);
2617 return decodeVfpRegImmOp<VmovImmD>(
2618 machInst, vd, imm, true);
2619 }
2620 }
2621 switch (opc2) {
2622 case 0x0:
2623 if (opc3 == 1) {
2624 if (single) {
2625 return decodeVfpRegRegOp<VmovRegS>(
2626 machInst, vd, vm, false);
2627 } else {
2628 return decodeVfpRegRegOp<VmovRegD>(
2629 machInst, vd, vm, true);
2630 }
2631 } else {
2632 if (single) {
2633 return decodeVfpRegRegOp<VabsS>(
2634 machInst, vd, vm, false);
2635 } else {
2636 return decodeVfpRegRegOp<VabsD>(
2637 machInst, vd, vm, true);
2638 }
2639 }
2640 case 0x1:
2641 if (opc3 == 1) {
2642 if (single) {
2643 return decodeVfpRegRegOp<VnegS>(
2644 machInst, vd, vm, false);
2645 } else {
2646 return decodeVfpRegRegOp<VnegD>(
2647 machInst, vd, vm, true);
2648 }
2649 } else {
2650 if (single) {
2651 return decodeVfpRegRegOp<VsqrtS>(
2652 machInst, vd, vm, false);
2653 } else {
2654 return decodeVfpRegRegOp<VsqrtD>(
2655 machInst, vd, vm, true);
2656 }
2657 }
2658 case 0x2:
2659 case 0x3:
2660 {
2661 const bool toHalf = bits(machInst, 16);
2662 const bool top = bits(machInst, 7);
2663 if (top) {
2664 if (toHalf) {
2665 return new VcvtFpSFpHT(machInst, vd, vm);
2666 } else {
2667 return new VcvtFpHTFpS(machInst, vd, vm);
2668 }
2669 } else {
2670 if (toHalf) {
2671 return new VcvtFpSFpHB(machInst, vd, vm);
2672 } else {
2673 return new VcvtFpHBFpS(machInst, vd, vm);
2674 }
2675 }
2676 }
2677 case 0x4:
2678 if (single) {
2679 if (e) {
2680 return new VcmpeS(machInst, vd, vm);
2681 } else {
2682 return new VcmpS(machInst, vd, vm);
2683 }
2684 } else {
2685 if (e) {
2686 return new VcmpeD(machInst, vd, vm);
2687 } else {
2688 return new VcmpD(machInst, vd, vm);
2689 }
2690 }
2691 case 0x5:
2692 if (single) {
2693 if (e) {
2694 return new VcmpeZeroS(machInst, vd, 0);
2695 } else {
2696 return new VcmpZeroS(machInst, vd, 0);
2697 }
2698 } else {
2699 if (e) {
2700 return new VcmpeZeroD(machInst, vd, 0);
2701 } else {
2702 return new VcmpZeroD(machInst, vd, 0);
2703 }
2704 }
2705 case 0x7:
2706 if (opc3 == 0x3) {
2707 if (single) {
2708 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2709 (bits(machInst, 15, 12) << 1));
2710 return new VcvtFpSFpD(machInst, vd, vm);
2711 } else {
2712 vd = (IntRegIndex)(bits(machInst, 22) |
2713 (bits(machInst, 15, 12) << 1));
2714 return new VcvtFpDFpS(machInst, vd, vm);
2715 }
2716 }
2717 break;
2718 case 0x8:
2719 if (bits(machInst, 7) == 0) {
2720 if (single) {
2721 return new VcvtUIntFpS(machInst, vd, vm);
2722 } else {
2723 vm = (IntRegIndex)(bits(machInst, 5) |
2724 (bits(machInst, 3, 0) << 1));
2725 return new VcvtUIntFpD(machInst, vd, vm);
2726 }
2727 } else {
2728 if (single) {
2729 return new VcvtSIntFpS(machInst, vd, vm);
2730 } else {
2731 vm = (IntRegIndex)(bits(machInst, 5) |
2732 (bits(machInst, 3, 0) << 1));
2733 return new VcvtSIntFpD(machInst, vd, vm);
2734 }
2735 }
2736 case 0xa:
2737 {
2738 const bool half = (bits(machInst, 7) == 0);
2739 const uint32_t imm = bits(machInst, 5) |
2740 (bits(machInst, 3, 0) << 1);
2741 const uint32_t size =
2742 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2743 if (single) {
2744 if (half) {
2745 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2746 } else {
2747 return new VcvtSFixedFpS(machInst, vd, vd, size);
2748 }
2749 } else {
2750 if (half) {
2751 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2752 } else {
2753 return new VcvtSFixedFpD(machInst, vd, vd, size);
2754 }
2755 }
2756 }
2757 case 0xb:
2758 {
2759 const bool half = (bits(machInst, 7) == 0);
2760 const uint32_t imm = bits(machInst, 5) |
2761 (bits(machInst, 3, 0) << 1);
2762 const uint32_t size =
2763 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2764 if (single) {
2765 if (half) {
2766 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2767 } else {
2768 return new VcvtUFixedFpS(machInst, vd, vd, size);
2769 }
2770 } else {
2771 if (half) {
2772 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2773 } else {
2774 return new VcvtUFixedFpD(machInst, vd, vd, size);
2775 }
2776 }
2777 }
2778 case 0xc:
2779 if (bits(machInst, 7) == 0) {
2780 if (single) {
2781 return new VcvtFpUIntSR(machInst, vd, vm);
2782 } else {
2783 vd = (IntRegIndex)(bits(machInst, 22) |
2784 (bits(machInst, 15, 12) << 1));
2785 return new VcvtFpUIntDR(machInst, vd, vm);
2786 }
2787 } else {
2788 if (single) {
2789 return new VcvtFpUIntS(machInst, vd, vm);
2790 } else {
2791 vd = (IntRegIndex)(bits(machInst, 22) |
2792 (bits(machInst, 15, 12) << 1));
2793 return new VcvtFpUIntD(machInst, vd, vm);
2794 }
2795 }
2796 case 0xd:
2797 if (bits(machInst, 7) == 0) {
2798 if (single) {
2799 return new VcvtFpSIntSR(machInst, vd, vm);
2800 } else {
2801 vd = (IntRegIndex)(bits(machInst, 22) |
2802 (bits(machInst, 15, 12) << 1));
2803 return new VcvtFpSIntDR(machInst, vd, vm);
2804 }
2805 } else {
2806 if (single) {
2807 return new VcvtFpSIntS(machInst, vd, vm);
2808 } else {
2809 vd = (IntRegIndex)(bits(machInst, 22) |
2810 (bits(machInst, 15, 12) << 1));
2811 return new VcvtFpSIntD(machInst, vd, vm);
2812 }
2813 }
2814 case 0xe:
2815 {
2816 const bool half = (bits(machInst, 7) == 0);
2817 const uint32_t imm = bits(machInst, 5) |
2818 (bits(machInst, 3, 0) << 1);
2819 const uint32_t size =
2820 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2821 if (single) {
2822 if (half) {
2823 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2824 } else {
2825 return new VcvtFpSFixedS(machInst, vd, vd, size);
2826 }
2827 } else {
2828 if (half) {
2829 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2830 } else {
2831 return new VcvtFpSFixedD(machInst, vd, vd, size);
2832 }
2833 }
2834 }
2835 case 0xf:
2836 {
2837 const bool half = (bits(machInst, 7) == 0);
2838 const uint32_t imm = bits(machInst, 5) |
2839 (bits(machInst, 3, 0) << 1);
2840 const uint32_t size =
2841 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2842 if (single) {
2843 if (half) {
2844 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2845 } else {
2846 return new VcvtFpUFixedS(machInst, vd, vd, size);
2847 }
2848 } else {
2849 if (half) {
2850 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2851 } else {
2852 return new VcvtFpUFixedD(machInst, vd, vd, size);
2853 }
2854 }
2855 }
2856 }
2857 break;
2858 }
2859 return new Unknown(machInst);
2860 }
2861 '''
2862}};
2863
2864def format VfpData() {{
2865 decode_block = '''
2866 return decodeVfpData(machInst);
2867 '''
2868}};