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