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