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