Deleted Added
sdiff udiff text old ( 8303:5a95f1d2494e ) new ( 8607:5fb918115c07 )
full compact
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 = TLB::MustBeOne;
147 unsigned inc = 1;
148 unsigned regs = 1;
149 unsigned lane = 0;
150 if (single) {
151 if (singleAll) {
152 size = bits(machInst, 7, 6);
153 bool t = bits(machInst, 5);
154 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 (q)
565 return new Unknown(machInst);
566 if (b) {
567 return decodeNeonUSThreeUSReg<VpminD>(
568 u, size, machInst, vd, vn, vm);
569 } else {
570 return decodeNeonUSThreeUSReg<VpmaxD>(
571 u, size, machInst, vd, vn, vm);
572 }
573 case 0xb:
574 if (b) {
575 if (u || q) {
576 return new Unknown(machInst);
577 } else {
578 return decodeNeonUThreeUSReg<NVpaddD>(
579 size, machInst, vd, vn, vm);
580 }
581 } else {
582 if (u) {
583 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
584 q, size, machInst, vd, vn, vm);
585 } else {
586 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
587 q, size, machInst, vd, vn, vm);
588 }
589 }
590 case 0xc:
591 return new Unknown(machInst);
592 case 0xd:
593 if (b) {
594 if (u) {
595 if (bits(c, 1) == 0) {
596 if (q) {
597 return new NVmulQFp<float>(machInst, vd, vn, vm);
598 } else {
599 return new NVmulDFp<float>(machInst, vd, vn, vm);
600 }
601 } else {
602 return new Unknown(machInst);
603 }
604 } else {
605 if (bits(c, 1) == 0) {
606 if (q) {
607 return new NVmlaQFp<float>(machInst, vd, vn, vm);
608 } else {
609 return new NVmlaDFp<float>(machInst, vd, vn, vm);
610 }
611 } else {
612 if (q) {
613 return new NVmlsQFp<float>(machInst, vd, vn, vm);
614 } else {
615 return new NVmlsDFp<float>(machInst, vd, vn, vm);
616 }
617 }
618 }
619 } else {
620 if (u) {
621 if (bits(c, 1) == 0) {
622 if (q) {
623 return new VpaddQFp<float>(machInst, vd, vn, vm);
624 } else {
625 return new VpaddDFp<float>(machInst, vd, vn, vm);
626 }
627 } else {
628 if (q) {
629 return new VabdQFp<float>(machInst, vd, vn, vm);
630 } else {
631 return new VabdDFp<float>(machInst, vd, vn, vm);
632 }
633 }
634 } else {
635 if (bits(c, 1) == 0) {
636 if (q) {
637 return new VaddQFp<float>(machInst, vd, vn, vm);
638 } else {
639 return new VaddDFp<float>(machInst, vd, vn, vm);
640 }
641 } else {
642 if (q) {
643 return new VsubQFp<float>(machInst, vd, vn, vm);
644 } else {
645 return new VsubDFp<float>(machInst, vd, vn, vm);
646 }
647 }
648 }
649 }
650 case 0xe:
651 if (b) {
652 if (u) {
653 if (bits(c, 1) == 0) {
654 if (q) {
655 return new VacgeQFp<float>(machInst, vd, vn, vm);
656 } else {
657 return new VacgeDFp<float>(machInst, vd, vn, vm);
658 }
659 } else {
660 if (q) {
661 return new VacgtQFp<float>(machInst, vd, vn, vm);
662 } else {
663 return new VacgtDFp<float>(machInst, vd, vn, vm);
664 }
665 }
666 } else {
667 return new Unknown(machInst);
668 }
669 } else {
670 if (u) {
671 if (bits(c, 1) == 0) {
672 if (q) {
673 return new VcgeQFp<float>(machInst, vd, vn, vm);
674 } else {
675 return new VcgeDFp<float>(machInst, vd, vn, vm);
676 }
677 } else {
678 if (q) {
679 return new VcgtQFp<float>(machInst, vd, vn, vm);
680 } else {
681 return new VcgtDFp<float>(machInst, vd, vn, vm);
682 }
683 }
684 } else {
685 if (bits(c, 1) == 0) {
686 if (q) {
687 return new VceqQFp<float>(machInst, vd, vn, vm);
688 } else {
689 return new VceqDFp<float>(machInst, vd, vn, vm);
690 }
691 } else {
692 return new Unknown(machInst);
693 }
694 }
695 }
696 case 0xf:
697 if (b) {
698 if (u) {
699 return new Unknown(machInst);
700 } else {
701 if (bits(c, 1) == 0) {
702 if (q) {
703 return new VrecpsQFp<float>(machInst, vd, vn, vm);
704 } else {
705 return new VrecpsDFp<float>(machInst, vd, vn, vm);
706 }
707 } else {
708 if (q) {
709 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
710 } else {
711 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
712 }
713 }
714 }
715 } else {
716 if (u) {
717 if (bits(c, 1) == 0) {
718 if (q) {
719 return new VpmaxQFp<float>(machInst, vd, vn, vm);
720 } else {
721 return new VpmaxDFp<float>(machInst, vd, vn, vm);
722 }
723 } else {
724 if (q) {
725 return new VpminQFp<float>(machInst, vd, vn, vm);
726 } else {
727 return new VpminDFp<float>(machInst, vd, vn, vm);
728 }
729 }
730 } else {
731 if (bits(c, 1) == 0) {
732 if (q) {
733 return new VmaxQFp<float>(machInst, vd, vn, vm);
734 } else {
735 return new VmaxDFp<float>(machInst, vd, vn, vm);
736 }
737 } else {
738 if (q) {
739 return new VminQFp<float>(machInst, vd, vn, vm);
740 } else {
741 return new VminDFp<float>(machInst, vd, vn, vm);
742 }
743 }
744 }
745 }
746 }
747 return new Unknown(machInst);
748 }
749
750 static StaticInstPtr
751 decodeNeonOneRegModImm(ExtMachInst machInst)
752 {
753 const IntRegIndex vd =
754 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
755 (bits(machInst, 22) << 4)));
756 const bool q = bits(machInst, 6);
757 const bool op = bits(machInst, 5);
758 const uint8_t cmode = bits(machInst, 11, 8);
759 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
760 bits(machInst, 24)) << 7) |
761 (bits(machInst, 18, 16) << 4) |
762 (bits(machInst, 3, 0) << 0);
763
764 // Check for invalid immediate encodings and return an unknown op
765 // if it happens
766 bool immValid = true;
767 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
768 if (!immValid) {
769 return new Unknown(machInst);
770 }
771
772 if (op) {
773 if (bits(cmode, 3) == 0) {
774 if (bits(cmode, 0) == 0) {
775 if (q)
776 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
777 else
778 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
779 } else {
780 if (q)
781 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
782 else
783 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
784 }
785 } else {
786 if (bits(cmode, 2) == 1) {
787 switch (bits(cmode, 1, 0)) {
788 case 0:
789 case 1:
790 if (q)
791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
792 else
793 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794 case 2:
795 if (q)
796 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
797 else
798 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
799 case 3:
800 if (q)
801 return new Unknown(machInst);
802 else
803 return new Unknown(machInst);
804 }
805 } else {
806 if (bits(cmode, 0) == 0) {
807 if (q)
808 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
809 else
810 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
811 } else {
812 if (q)
813 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
814 else
815 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
816 }
817 }
818 }
819 } else {
820 if (bits(cmode, 3) == 0) {
821 if (bits(cmode, 0) == 0) {
822 if (q)
823 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
824 else
825 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
826 } else {
827 if (q)
828 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
829 else
830 return new NVorriD<uint64_t>(machInst, vd, bigImm);
831 }
832 } else {
833 if (bits(cmode, 2) == 1) {
834 if (q)
835 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
836 else
837 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
838 } else {
839 if (bits(cmode, 0) == 0) {
840 if (q)
841 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
842 else
843 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
844 } else {
845 if (q)
846 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
847 else
848 return new NVorriD<uint64_t>(machInst, vd, bigImm);
849 }
850 }
851 }
852 }
853 return new Unknown(machInst);
854 }
855
856 static StaticInstPtr
857 decodeNeonTwoRegAndShift(ExtMachInst machInst)
858 {
859 const uint32_t a = bits(machInst, 11, 8);
860 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
861 const bool b = bits(machInst, 6);
862 const bool l = bits(machInst, 7);
863 const IntRegIndex vd =
864 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
865 (bits(machInst, 22) << 4)));
866 const IntRegIndex vm =
867 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
868 (bits(machInst, 5) << 4)));
869 unsigned imm6 = bits(machInst, 21, 16);
870 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
871 unsigned size = 3;
872 unsigned lShiftAmt = 0;
873 unsigned bitSel;
874 for (bitSel = 1 << 6; true; bitSel >>= 1) {
875 if (bitSel & imm)
876 break;
877 else if (!size)
878 return new Unknown(machInst);
879 size--;
880 }
881 lShiftAmt = imm6 & ~bitSel;
882 unsigned rShiftAmt = 0;
883 if (a != 0xe && a != 0xf) {
884 if (size > 2)
885 rShiftAmt = 64 - imm6;
886 else
887 rShiftAmt = 2 * (8 << size) - imm6;
888 }
889
890 switch (a) {
891 case 0x0:
892 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
893 b, u, size, machInst, vd, vm, rShiftAmt);
894 case 0x1:
895 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
896 b, u, size, machInst, vd, vm, rShiftAmt);
897 case 0x2:
898 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
899 b, u, size, machInst, vd, vm, rShiftAmt);
900 case 0x3:
901 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
902 b, u, size, machInst, vd, vm, rShiftAmt);
903 case 0x4:
904 if (u) {
905 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
906 b, size, machInst, vd, vm, rShiftAmt);
907 } else {
908 return new Unknown(machInst);
909 }
910 case 0x5:
911 if (u) {
912 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
913 b, size, machInst, vd, vm, lShiftAmt);
914 } else {
915 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
916 b, size, machInst, vd, vm, lShiftAmt);
917 }
918 case 0x6:
919 case 0x7:
920 if (u) {
921 if (a == 0x6) {
922 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
923 b, size, machInst, vd, vm, lShiftAmt);
924 } else {
925 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
926 b, size, machInst, vd, vm, lShiftAmt);
927 }
928 } else {
929 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
930 b, size, machInst, vd, vm, lShiftAmt);
931 }
932 case 0x8:
933 if (l) {
934 return new Unknown(machInst);
935 } else if (u) {
936 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
937 b, size, machInst, vd, vm, rShiftAmt);
938 } else {
939 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
940 b, size, machInst, vd, vm, rShiftAmt);
941 }
942 case 0x9:
943 if (l) {
944 return new Unknown(machInst);
945 } else if (u) {
946 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
947 b, size, machInst, vd, vm, rShiftAmt);
948 } else {
949 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
950 b, size, machInst, vd, vm, rShiftAmt);
951 }
952 case 0xa:
953 if (l || b) {
954 return new Unknown(machInst);
955 } else {
956 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
957 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
958 }
959 case 0xe:
960 if (l) {
961 return new Unknown(machInst);
962 } else {
963 if (bits(imm6, 5) == 0)
964 return new Unknown(machInst);
965 if (u) {
966 if (b) {
967 return new NVcvtu2fpQ<float>(
968 machInst, vd, vm, 64 - imm6);
969 } else {
970 return new NVcvtu2fpD<float>(
971 machInst, vd, vm, 64 - imm6);
972 }
973 } else {
974 if (b) {
975 return new NVcvts2fpQ<float>(
976 machInst, vd, vm, 64 - imm6);
977 } else {
978 return new NVcvts2fpD<float>(
979 machInst, vd, vm, 64 - imm6);
980 }
981 }
982 }
983 case 0xf:
984 if (l) {
985 return new Unknown(machInst);
986 } else {
987 if (bits(imm6, 5) == 0)
988 return new Unknown(machInst);
989 if (u) {
990 if (b) {
991 return new NVcvt2ufxQ<float>(
992 machInst, vd, vm, 64 - imm6);
993 } else {
994 return new NVcvt2ufxD<float>(
995 machInst, vd, vm, 64 - imm6);
996 }
997 } else {
998 if (b) {
999 return new NVcvt2sfxQ<float>(
1000 machInst, vd, vm, 64 - imm6);
1001 } else {
1002 return new NVcvt2sfxD<float>(
1003 machInst, vd, vm, 64 - imm6);
1004 }
1005 }
1006 }
1007 }
1008 return new Unknown(machInst);
1009 }
1010
1011 static StaticInstPtr
1012 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1013 {
1014 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1015 const uint32_t a = bits(machInst, 11, 8);
1016 const IntRegIndex vd =
1017 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1018 (bits(machInst, 22) << 4)));
1019 const IntRegIndex vn =
1020 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1021 (bits(machInst, 7) << 4)));
1022 const IntRegIndex vm =
1023 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1024 (bits(machInst, 5) << 4)));
1025 const unsigned size = bits(machInst, 21, 20);
1026 switch (a) {
1027 case 0x0:
1028 return decodeNeonUSThreeUSReg<Vaddl>(
1029 u, size, machInst, vd, vn, vm);
1030 case 0x1:
1031 return decodeNeonUSThreeUSReg<Vaddw>(
1032 u, size, machInst, vd, vn, vm);
1033 case 0x2:
1034 return decodeNeonUSThreeUSReg<Vsubl>(
1035 u, size, machInst, vd, vn, vm);
1036 case 0x3:
1037 return decodeNeonUSThreeUSReg<Vsubw>(
1038 u, size, machInst, vd, vn, vm);
1039 case 0x4:
1040 if (u) {
1041 return decodeNeonUThreeUSReg<Vraddhn>(
1042 size, machInst, vd, vn, vm);
1043 } else {
1044 return decodeNeonUThreeUSReg<Vaddhn>(
1045 size, machInst, vd, vn, vm);
1046 }
1047 case 0x5:
1048 return decodeNeonUSThreeUSReg<Vabal>(
1049 u, size, machInst, vd, vn, vm);
1050 case 0x6:
1051 if (u) {
1052 return decodeNeonUThreeUSReg<Vrsubhn>(
1053 size, machInst, vd, vn, vm);
1054 } else {
1055 return decodeNeonUThreeUSReg<Vsubhn>(
1056 size, machInst, vd, vn, vm);
1057 }
1058 case 0x7:
1059 if (bits(machInst, 23)) {
1060 return decodeNeonUSThreeUSReg<Vabdl>(
1061 u, size, machInst, vd, vn, vm);
1062 } else {
1063 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1064 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1065 }
1066 case 0x8:
1067 return decodeNeonUSThreeUSReg<Vmlal>(
1068 u, size, machInst, vd, vn, vm);
1069 case 0xa:
1070 return decodeNeonUSThreeUSReg<Vmlsl>(
1071 u, size, machInst, vd, vn, vm);
1072 case 0x9:
1073 if (u) {
1074 return new Unknown(machInst);
1075 } else {
1076 return decodeNeonSThreeUSReg<Vqdmlal>(
1077 size, machInst, vd, vn, vm);
1078 }
1079 case 0xb:
1080 if (u) {
1081 return new Unknown(machInst);
1082 } else {
1083 return decodeNeonSThreeUSReg<Vqdmlsl>(
1084 size, machInst, vd, vn, vm);
1085 }
1086 case 0xc:
1087 return decodeNeonUSThreeUSReg<Vmull>(
1088 u, size, machInst, vd, vn, vm);
1089 case 0xd:
1090 if (u) {
1091 return new Unknown(machInst);
1092 } else {
1093 return decodeNeonSThreeUSReg<Vqdmull>(
1094 size, machInst, vd, vn, vm);
1095 }
1096 case 0xe:
1097 return decodeNeonUThreeUSReg<Vmullp>(
1098 size, machInst, vd, vn, vm);
1099 }
1100 return new Unknown(machInst);
1101 }
1102
1103 static StaticInstPtr
1104 decodeNeonTwoRegScalar(ExtMachInst machInst)
1105 {
1106 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1107 const uint32_t a = bits(machInst, 11, 8);
1108 const unsigned size = bits(machInst, 21, 20);
1109 const IntRegIndex vd =
1110 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1111 (bits(machInst, 22) << 4)));
1112 const IntRegIndex vn =
1113 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1114 (bits(machInst, 7) << 4)));
1115 const IntRegIndex vm = (size == 2) ?
1116 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1117 (IntRegIndex)(2 * bits(machInst, 2, 0));
1118 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1119 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1120 switch (a) {
1121 case 0x0:
1122 if (u) {
1123 switch (size) {
1124 case 1:
1125 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1126 case 2:
1127 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1128 default:
1129 return new Unknown(machInst);
1130 }
1131 } else {
1132 switch (size) {
1133 case 1:
1134 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1135 case 2:
1136 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1137 default:
1138 return new Unknown(machInst);
1139 }
1140 }
1141 case 0x1:
1142 if (u)
1143 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1144 else
1145 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1146 case 0x4:
1147 if (u) {
1148 switch (size) {
1149 case 1:
1150 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1151 case 2:
1152 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1153 default:
1154 return new Unknown(machInst);
1155 }
1156 } else {
1157 switch (size) {
1158 case 1:
1159 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1160 case 2:
1161 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1162 default:
1163 return new Unknown(machInst);
1164 }
1165 }
1166 case 0x5:
1167 if (u)
1168 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1169 else
1170 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1171 case 0x2:
1172 if (u) {
1173 switch (size) {
1174 case 1:
1175 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1176 case 2:
1177 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1178 default:
1179 return new Unknown(machInst);
1180 }
1181 } else {
1182 switch (size) {
1183 case 1:
1184 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1185 case 2:
1186 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1187 default:
1188 return new Unknown(machInst);
1189 }
1190 }
1191 case 0x6:
1192 if (u) {
1193 switch (size) {
1194 case 1:
1195 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1196 case 2:
1197 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1198 default:
1199 return new Unknown(machInst);
1200 }
1201 } else {
1202 switch (size) {
1203 case 1:
1204 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1205 case 2:
1206 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1207 default:
1208 return new Unknown(machInst);
1209 }
1210 }
1211 case 0x3:
1212 if (u) {
1213 return new Unknown(machInst);
1214 } else {
1215 switch (size) {
1216 case 1:
1217 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1218 case 2:
1219 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1220 default:
1221 return new Unknown(machInst);
1222 }
1223 }
1224 case 0x7:
1225 if (u) {
1226 return new Unknown(machInst);
1227 } else {
1228 switch (size) {
1229 case 1:
1230 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1231 case 2:
1232 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1233 default:
1234 return new Unknown(machInst);
1235 }
1236 }
1237 case 0x8:
1238 if (u) {
1239 switch (size) {
1240 case 1:
1241 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1242 case 2:
1243 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1244 default:
1245 return new Unknown(machInst);
1246 }
1247 } else {
1248 switch (size) {
1249 case 1:
1250 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1251 case 2:
1252 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1253 default:
1254 return new Unknown(machInst);
1255 }
1256 }
1257 case 0x9:
1258 if (u)
1259 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1260 else
1261 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1262 case 0xa:
1263 if (u) {
1264 switch (size) {
1265 case 1:
1266 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1267 case 2:
1268 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1269 default:
1270 return new Unknown(machInst);
1271 }
1272 } else {
1273 switch (size) {
1274 case 1:
1275 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1276 case 2:
1277 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1278 default:
1279 return new Unknown(machInst);
1280 }
1281 }
1282 case 0xb:
1283 if (u) {
1284 return new Unknown(machInst);
1285 } else {
1286 if (u) {
1287 switch (size) {
1288 case 1:
1289 return new Vqdmulls<uint16_t>(
1290 machInst, vd, vn, vm, index);
1291 case 2:
1292 return new Vqdmulls<uint32_t>(
1293 machInst, vd, vn, vm, index);
1294 default:
1295 return new Unknown(machInst);
1296 }
1297 } else {
1298 switch (size) {
1299 case 1:
1300 return new Vqdmulls<int16_t>(
1301 machInst, vd, vn, vm, index);
1302 case 2:
1303 return new Vqdmulls<int32_t>(
1304 machInst, vd, vn, vm, index);
1305 default:
1306 return new Unknown(machInst);
1307 }
1308 }
1309 }
1310 case 0xc:
1311 if (u) {
1312 switch (size) {
1313 case 1:
1314 return new VqdmulhsQ<int16_t>(
1315 machInst, vd, vn, vm, index);
1316 case 2:
1317 return new VqdmulhsQ<int32_t>(
1318 machInst, vd, vn, vm, index);
1319 default:
1320 return new Unknown(machInst);
1321 }
1322 } else {
1323 switch (size) {
1324 case 1:
1325 return new VqdmulhsD<int16_t>(
1326 machInst, vd, vn, vm, index);
1327 case 2:
1328 return new VqdmulhsD<int32_t>(
1329 machInst, vd, vn, vm, index);
1330 default:
1331 return new Unknown(machInst);
1332 }
1333 }
1334 case 0xd:
1335 if (u) {
1336 switch (size) {
1337 case 1:
1338 return new VqrdmulhsQ<int16_t>(
1339 machInst, vd, vn, vm, index);
1340 case 2:
1341 return new VqrdmulhsQ<int32_t>(
1342 machInst, vd, vn, vm, index);
1343 default:
1344 return new Unknown(machInst);
1345 }
1346 } else {
1347 switch (size) {
1348 case 1:
1349 return new VqrdmulhsD<int16_t>(
1350 machInst, vd, vn, vm, index);
1351 case 2:
1352 return new VqrdmulhsD<int32_t>(
1353 machInst, vd, vn, vm, index);
1354 default:
1355 return new Unknown(machInst);
1356 }
1357 }
1358 }
1359 return new Unknown(machInst);
1360 }
1361
1362 static StaticInstPtr
1363 decodeNeonTwoRegMisc(ExtMachInst machInst)
1364 {
1365 const uint32_t a = bits(machInst, 17, 16);
1366 const uint32_t b = bits(machInst, 10, 6);
1367 const bool q = bits(machInst, 6);
1368 const IntRegIndex vd =
1369 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1370 (bits(machInst, 22) << 4)));
1371 const IntRegIndex vm =
1372 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1373 (bits(machInst, 5) << 4)));
1374 const unsigned size = bits(machInst, 19, 18);
1375 switch (a) {
1376 case 0x0:
1377 switch (bits(b, 4, 1)) {
1378 case 0x0:
1379 switch (size) {
1380 case 0:
1381 if (q) {
1382 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1383 } else {
1384 return new NVrev64D<uint8_t>(machInst, vd, vm);
1385 }
1386 case 1:
1387 if (q) {
1388 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1389 } else {
1390 return new NVrev64D<uint16_t>(machInst, vd, vm);
1391 }
1392 case 2:
1393 if (q) {
1394 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1395 } else {
1396 return new NVrev64D<uint32_t>(machInst, vd, vm);
1397 }
1398 default:
1399 return new Unknown(machInst);
1400 }
1401 case 0x1:
1402 switch (size) {
1403 case 0:
1404 if (q) {
1405 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1406 } else {
1407 return new NVrev32D<uint8_t>(machInst, vd, vm);
1408 }
1409 case 1:
1410 if (q) {
1411 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1412 } else {
1413 return new NVrev32D<uint16_t>(machInst, vd, vm);
1414 }
1415 default:
1416 return new Unknown(machInst);
1417 }
1418 case 0x2:
1419 if (size != 0) {
1420 return new Unknown(machInst);
1421 } else if (q) {
1422 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1423 } else {
1424 return new NVrev16D<uint8_t>(machInst, vd, vm);
1425 }
1426 case 0x4:
1427 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1428 q, size, machInst, vd, vm);
1429 case 0x5:
1430 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1431 q, size, machInst, vd, vm);
1432 case 0x8:
1433 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1434 q, size, machInst, vd, vm);
1435 case 0x9:
1436 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1437 q, size, machInst, vd, vm);
1438 case 0xa:
1439 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1440 q, size, machInst, vd, vm);
1441 case 0xb:
1442 if (q)
1443 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1444 else
1445 return new NVmvnD<uint64_t>(machInst, vd, vm);
1446 case 0xc:
1447 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1448 q, size, machInst, vd, vm);
1449 case 0xd:
1450 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1451 q, size, machInst, vd, vm);
1452 case 0xe:
1453 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1454 q, size, machInst, vd, vm);
1455 case 0xf:
1456 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1457 q, size, machInst, vd, vm);
1458 default:
1459 return new Unknown(machInst);
1460 }
1461 case 0x1:
1462 switch (bits(b, 3, 1)) {
1463 case 0x0:
1464 if (bits(b, 4)) {
1465 if (q) {
1466 return new NVcgtQFp<float>(machInst, vd, vm);
1467 } else {
1468 return new NVcgtDFp<float>(machInst, vd, vm);
1469 }
1470 } else {
1471 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1472 q, size, machInst, vd, vm);
1473 }
1474 case 0x1:
1475 if (bits(b, 4)) {
1476 if (q) {
1477 return new NVcgeQFp<float>(machInst, vd, vm);
1478 } else {
1479 return new NVcgeDFp<float>(machInst, vd, vm);
1480 }
1481 } else {
1482 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1483 q, size, machInst, vd, vm);
1484 }
1485 case 0x2:
1486 if (bits(b, 4)) {
1487 if (q) {
1488 return new NVceqQFp<float>(machInst, vd, vm);
1489 } else {
1490 return new NVceqDFp<float>(machInst, vd, vm);
1491 }
1492 } else {
1493 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1494 q, size, machInst, vd, vm);
1495 }
1496 case 0x3:
1497 if (bits(b, 4)) {
1498 if (q) {
1499 return new NVcleQFp<float>(machInst, vd, vm);
1500 } else {
1501 return new NVcleDFp<float>(machInst, vd, vm);
1502 }
1503 } else {
1504 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1505 q, size, machInst, vd, vm);
1506 }
1507 case 0x4:
1508 if (bits(b, 4)) {
1509 if (q) {
1510 return new NVcltQFp<float>(machInst, vd, vm);
1511 } else {
1512 return new NVcltDFp<float>(machInst, vd, vm);
1513 }
1514 } else {
1515 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1516 q, size, machInst, vd, vm);
1517 }
1518 case 0x6:
1519 if (bits(machInst, 10)) {
1520 if (q)
1521 return new NVabsQFp<float>(machInst, vd, vm);
1522 else
1523 return new NVabsDFp<float>(machInst, vd, vm);
1524 } else {
1525 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1526 q, size, machInst, vd, vm);
1527 }
1528 case 0x7:
1529 if (bits(machInst, 10)) {
1530 if (q)
1531 return new NVnegQFp<float>(machInst, vd, vm);
1532 else
1533 return new NVnegDFp<float>(machInst, vd, vm);
1534 } else {
1535 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1536 q, size, machInst, vd, vm);
1537 }
1538 }
1539 case 0x2:
1540 switch (bits(b, 4, 1)) {
1541 case 0x0:
1542 if (q)
1543 return new NVswpQ<uint64_t>(machInst, vd, vm);
1544 else
1545 return new NVswpD<uint64_t>(machInst, vd, vm);
1546 case 0x1:
1547 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1548 q, size, machInst, vd, vm);
1549 case 0x2:
1550 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1551 q, size, machInst, vd, vm);
1552 case 0x3:
1553 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1554 q, size, machInst, vd, vm);
1555 case 0x4:
1556 if (b == 0x8) {
1557 return decodeNeonUTwoMiscUSReg<NVmovn>(
1558 size, machInst, vd, vm);
1559 } else {
1560 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1561 size, machInst, vd, vm);
1562 }
1563 case 0x5:
1564 if (q) {
1565 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1566 size, machInst, vd, vm);
1567 } else {
1568 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1569 size, machInst, vd, vm);
1570 }
1571 case 0x6:
1572 if (b == 0xc) {
1573 const IntRegIndex vd =
1574 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1575 (bits(machInst, 22) << 4)));
1576 const IntRegIndex vm =
1577 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1578 (bits(machInst, 5) << 4)));
1579 unsigned size = bits(machInst, 19, 18);
1580 return decodeNeonSTwoShiftUSReg<NVshll>(
1581 size, machInst, vd, vm, 8 << size);
1582 } else {
1583 return new Unknown(machInst);
1584 }
1585 case 0xc:
1586 case 0xe:
1587 if (b == 0x18) {
1588 if (size != 1 || (vm % 2))
1589 return new Unknown(machInst);
1590 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1591 } else if (b == 0x1c) {
1592 if (size != 1 || (vd % 2))
1593 return new Unknown(machInst);
1594 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1595 } else {
1596 return new Unknown(machInst);
1597 }
1598 default:
1599 return new Unknown(machInst);
1600 }
1601 case 0x3:
1602 if (bits(b, 4, 3) == 0x3) {
1603 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1604 return new Unknown(machInst);
1605 } else {
1606 if (bits(b, 2)) {
1607 if (bits(b, 1)) {
1608 if (q) {
1609 return new NVcvt2ufxQ<float>(
1610 machInst, vd, vm, 0);
1611 } else {
1612 return new NVcvt2ufxD<float>(
1613 machInst, vd, vm, 0);
1614 }
1615 } else {
1616 if (q) {
1617 return new NVcvt2sfxQ<float>(
1618 machInst, vd, vm, 0);
1619 } else {
1620 return new NVcvt2sfxD<float>(
1621 machInst, vd, vm, 0);
1622 }
1623 }
1624 } else {
1625 if (bits(b, 1)) {
1626 if (q) {
1627 return new NVcvtu2fpQ<float>(
1628 machInst, vd, vm, 0);
1629 } else {
1630 return new NVcvtu2fpD<float>(
1631 machInst, vd, vm, 0);
1632 }
1633 } else {
1634 if (q) {
1635 return new NVcvts2fpQ<float>(
1636 machInst, vd, vm, 0);
1637 } else {
1638 return new NVcvts2fpD<float>(
1639 machInst, vd, vm, 0);
1640 }
1641 }
1642 }
1643 }
1644 } else if ((b & 0x1a) == 0x10) {
1645 if (bits(b, 2)) {
1646 if (q) {
1647 return new NVrecpeQFp<float>(machInst, vd, vm);
1648 } else {
1649 return new NVrecpeDFp<float>(machInst, vd, vm);
1650 }
1651 } else {
1652 if (q) {
1653 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1654 } else {
1655 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1656 }
1657 }
1658 } else if ((b & 0x1a) == 0x12) {
1659 if (bits(b, 2)) {
1660 if (q) {
1661 return new NVrsqrteQFp<float>(machInst, vd, vm);
1662 } else {
1663 return new NVrsqrteDFp<float>(machInst, vd, vm);
1664 }
1665 } else {
1666 if (q) {
1667 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1668 } else {
1669 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1670 }
1671 }
1672 } else {
1673 return new Unknown(machInst);
1674 }
1675 }
1676 return new Unknown(machInst);
1677 }
1678
1679 StaticInstPtr
1680 decodeNeonData(ExtMachInst machInst)
1681 {
1682 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1683 const uint32_t a = bits(machInst, 23, 19);
1684 const uint32_t b = bits(machInst, 11, 8);
1685 const uint32_t c = bits(machInst, 7, 4);
1686 if (bits(a, 4) == 0) {
1687 return decodeNeonThreeRegistersSameLength(machInst);
1688 } else if ((c & 0x9) == 1) {
1689 if ((a & 0x7) == 0) {
1690 return decodeNeonOneRegModImm(machInst);
1691 } else {
1692 return decodeNeonTwoRegAndShift(machInst);
1693 }
1694 } else if ((c & 0x9) == 9) {
1695 return decodeNeonTwoRegAndShift(machInst);
1696 } else if (bits(a, 2, 1) != 0x3) {
1697 if ((c & 0x5) == 0) {
1698 return decodeNeonThreeRegDiffLengths(machInst);
1699 } else if ((c & 0x5) == 4) {
1700 return decodeNeonTwoRegScalar(machInst);
1701 }
1702 } else if ((a & 0x16) == 0x16) {
1703 const IntRegIndex vd =
1704 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1705 (bits(machInst, 22) << 4)));
1706 const IntRegIndex vn =
1707 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1708 (bits(machInst, 7) << 4)));
1709 const IntRegIndex vm =
1710 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1711 (bits(machInst, 5) << 4)));
1712 if (!u) {
1713 if (bits(c, 0) == 0) {
1714 unsigned imm4 = bits(machInst, 11, 8);
1715 bool q = bits(machInst, 6);
1716 if (imm4 >= 16 && !q)
1717 return new Unknown(machInst);
1718 if (q) {
1719 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1720 } else {
1721 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1722 }
1723 }
1724 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1725 return decodeNeonTwoRegMisc(machInst);
1726 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1727 unsigned length = bits(machInst, 9, 8) + 1;
1728 if ((uint32_t)vn / 2 + length > 32)
1729 return new Unknown(machInst);
1730 if (bits(machInst, 6) == 0) {
1731 switch (length) {
1732 case 1:
1733 return new NVtbl1(machInst, vd, vn, vm);
1734 case 2:
1735 return new NVtbl2(machInst, vd, vn, vm);
1736 case 3:
1737 return new NVtbl3(machInst, vd, vn, vm);
1738 case 4:
1739 return new NVtbl4(machInst, vd, vn, vm);
1740 }
1741 } else {
1742 switch (length) {
1743 case 1:
1744 return new NVtbx1(machInst, vd, vn, vm);
1745 case 2:
1746 return new NVtbx2(machInst, vd, vn, vm);
1747 case 3:
1748 return new NVtbx3(machInst, vd, vn, vm);
1749 case 4:
1750 return new NVtbx4(machInst, vd, vn, vm);
1751 }
1752 }
1753 } else if (b == 0xc && (c & 0x9) == 0) {
1754 unsigned imm4 = bits(machInst, 19, 16);
1755 if (bits(imm4, 2, 0) == 0)
1756 return new Unknown(machInst);
1757 unsigned size = 0;
1758 while ((imm4 & 0x1) == 0) {
1759 size++;
1760 imm4 >>= 1;
1761 }
1762 unsigned index = imm4 >> 1;
1763 const bool q = bits(machInst, 6);
1764 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1765 q, size, machInst, vd, vm, index);
1766 }
1767 }
1768 return new Unknown(machInst);
1769 }
1770 '''
1771}};
1772
1773def format ThumbNeonMem() {{
1774 decode_block = '''
1775 return decodeNeonMem(machInst);
1776 '''
1777}};
1778
1779def format ThumbNeonData() {{
1780 decode_block = '''
1781 return decodeNeonData(machInst);
1782 '''
1783}};
1784
1785let {{
1786 header_output = '''
1787 StaticInstPtr
1788 decodeExtensionRegLoadStore(ExtMachInst machInst);
1789 '''
1790 decoder_output = '''
1791 StaticInstPtr
1792 decodeExtensionRegLoadStore(ExtMachInst machInst)
1793 {
1794 const uint32_t opcode = bits(machInst, 24, 20);
1795 const uint32_t offset = bits(machInst, 7, 0);
1796 const bool single = (bits(machInst, 8) == 0);
1797 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1798 RegIndex vd;
1799 if (single) {
1800 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1801 bits(machInst, 22));
1802 } else {
1803 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1804 (bits(machInst, 22) << 5));
1805 }
1806 switch (bits(opcode, 4, 3)) {
1807 case 0x0:
1808 if (bits(opcode, 4, 1) == 0x2 &&
1809 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1810 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1811 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1812 break;
1813 }
1814 const IntRegIndex rt =
1815 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1816 const IntRegIndex rt2 =
1817 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1818 const bool op = bits(machInst, 20);
1819 uint32_t vm;
1820 if (single) {
1821 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1822 } else {
1823 vm = (bits(machInst, 3, 0) << 1) |
1824 (bits(machInst, 5) << 5);
1825 }
1826 if (op) {
1827 return new Vmov2Core2Reg(machInst, rt, rt2,
1828 (IntRegIndex)vm);
1829 } else {
1830 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1831 rt, rt2);
1832 }
1833 }
1834 break;
1835 case 0x1:
1836 {
1837 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1838 break;
1839 }
1840 switch (bits(opcode, 1, 0)) {
1841 case 0x0:
1842 return new VLdmStm(machInst, rn, vd, single,
1843 true, false, false, offset);
1844 case 0x1:
1845 return new VLdmStm(machInst, rn, vd, single,
1846 true, false, true, offset);
1847 case 0x2:
1848 return new VLdmStm(machInst, rn, vd, single,
1849 true, true, false, offset);
1850 case 0x3:
1851 // If rn == sp, then this is called vpop.
1852 return new VLdmStm(machInst, rn, vd, single,
1853 true, true, true, offset);
1854 }
1855 }
1856 case 0x2:
1857 if (bits(opcode, 1, 0) == 0x2) {
1858 // If rn == sp, then this is called vpush.
1859 return new VLdmStm(machInst, rn, vd, single,
1860 false, true, false, offset);
1861 } else if (bits(opcode, 1, 0) == 0x3) {
1862 return new VLdmStm(machInst, rn, vd, single,
1863 false, true, true, offset);
1864 }
1865 // Fall through on purpose
1866 case 0x3:
1867 const bool up = (bits(machInst, 23) == 1);
1868 const uint32_t imm = bits(machInst, 7, 0) << 2;
1869 RegIndex vd;
1870 if (single) {
1871 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1872 (bits(machInst, 22)));
1873 } else {
1874 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1875 (bits(machInst, 22) << 5));
1876 }
1877 if (bits(opcode, 1, 0) == 0x0) {
1878 if (single) {
1879 if (up) {
1880 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1881 } else {
1882 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1883 }
1884 } else {
1885 if (up) {
1886 return new %(vstr_ud)s(machInst, vd, vd + 1,
1887 rn, up, imm);
1888 } else {
1889 return new %(vstr_d)s(machInst, vd, vd + 1,
1890 rn, up, imm);
1891 }
1892 }
1893 } else if (bits(opcode, 1, 0) == 0x1) {
1894 if (single) {
1895 if (up) {
1896 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1897 } else {
1898 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1899 }
1900 } else {
1901 if (up) {
1902 return new %(vldr_ud)s(machInst, vd, vd + 1,
1903 rn, up, imm);
1904 } else {
1905 return new %(vldr_d)s(machInst, vd, vd + 1,
1906 rn, up, imm);
1907 }
1908 }
1909 }
1910 }
1911 return new Unknown(machInst);
1912 }
1913 ''' % {
1914 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1915 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1916 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1917 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1918 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1919 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1920 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1921 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1922 }
1923}};
1924
1925def format ExtensionRegLoadStore() {{
1926 decode_block = '''
1927 return decodeExtensionRegLoadStore(machInst);
1928 '''
1929}};
1930
1931let {{
1932 header_output = '''
1933 StaticInstPtr
1934 decodeShortFpTransfer(ExtMachInst machInst);
1935 '''
1936 decoder_output = '''
1937 StaticInstPtr
1938 decodeShortFpTransfer(ExtMachInst machInst)
1939 {
1940 const uint32_t l = bits(machInst, 20);
1941 const uint32_t c = bits(machInst, 8);
1942 const uint32_t a = bits(machInst, 23, 21);
1943 const uint32_t b = bits(machInst, 6, 5);
1944 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1945 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1946 return new Unknown(machInst);
1947 }
1948 if (l == 0 && c == 0) {
1949 if (a == 0) {
1950 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1951 bits(machInst, 7);
1952 const IntRegIndex rt =
1953 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1954 if (bits(machInst, 20) == 1) {
1955 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1956 } else {
1957 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1958 }
1959 } else if (a == 0x7) {
1960 const IntRegIndex rt =
1961 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1962 uint32_t specReg = bits(machInst, 19, 16);
1963 switch (specReg) {
1964 case 0:
1965 specReg = MISCREG_FPSID;
1966 break;
1967 case 1:
1968 specReg = MISCREG_FPSCR;
1969 break;
1970 case 6:
1971 specReg = MISCREG_MVFR1;
1972 break;
1973 case 7:
1974 specReg = MISCREG_MVFR0;
1975 break;
1976 case 8:
1977 specReg = MISCREG_FPEXC;
1978 break;
1979 default:
1980 return new Unknown(machInst);
1981 }
1982 if (specReg == MISCREG_FPSCR) {
1983 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1984 } else {
1985 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1986 }
1987 }
1988 } else if (l == 0 && c == 1) {
1989 if (bits(a, 2) == 0) {
1990 uint32_t vd = (bits(machInst, 7) << 5) |
1991 (bits(machInst, 19, 16) << 1);
1992 // Handle accessing each single precision half of the vector.
1993 vd += bits(machInst, 21);
1994 const IntRegIndex rt =
1995 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1996 if (bits(machInst, 22) == 1) {
1997 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1998 rt, bits(machInst, 6, 5));
1999 } else if (bits(machInst, 5) == 1) {
2000 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2001 rt, bits(machInst, 6));
2002 } else if (bits(machInst, 6) == 0) {
2003 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2004 } else {
2005 return new Unknown(machInst);
2006 }
2007 } else if (bits(b, 1) == 0) {
2008 bool q = bits(machInst, 21);
2009 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2010 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2011 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2012 IntRegIndex rt = (IntRegIndex)(uint32_t)
2013 bits(machInst, 15, 12);
2014 if (q) {
2015 switch (be) {
2016 case 0:
2017 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2018 case 1:
2019 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2020 case 2:
2021 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2022 case 3:
2023 return new Unknown(machInst);
2024 }
2025 } else {
2026 switch (be) {
2027 case 0:
2028 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2029 case 1:
2030 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2031 case 2:
2032 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2033 case 3:
2034 return new Unknown(machInst);
2035 }
2036 }
2037 }
2038 } else if (l == 1 && c == 0) {
2039 if (a == 0) {
2040 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2041 bits(machInst, 7);
2042 const IntRegIndex rt =
2043 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2044 if (bits(machInst, 20) == 1) {
2045 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2046 } else {
2047 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2048 }
2049 } else if (a == 7) {
2050 const IntRegIndex rt =
2051 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2052 uint32_t specReg = bits(machInst, 19, 16);
2053 switch (specReg) {
2054 case 0:
2055 specReg = MISCREG_FPSID;
2056 break;
2057 case 1:
2058 specReg = MISCREG_FPSCR;
2059 break;
2060 case 6:
2061 specReg = MISCREG_MVFR1;
2062 break;
2063 case 7:
2064 specReg = MISCREG_MVFR0;
2065 break;
2066 case 8:
2067 specReg = MISCREG_FPEXC;
2068 break;
2069 default:
2070 return new Unknown(machInst);
2071 }
2072 if (rt == 0xf) {
2073 if (specReg == MISCREG_FPSCR) {
2074 return new VmrsApsrFpscr(machInst);
2075 } else {
2076 return new Unknown(machInst);
2077 }
2078 } else if (specReg == MISCREG_FPSCR) {
2079 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2080 } else {
2081 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2082 }
2083 }
2084 } else {
2085 uint32_t vd = (bits(machInst, 7) << 5) |
2086 (bits(machInst, 19, 16) << 1);
2087 // Handle indexing into each single precision half of the vector.
2088 vd += bits(machInst, 21);
2089 uint32_t index;
2090 const IntRegIndex rt =
2091 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2092 const bool u = (bits(machInst, 23) == 1);
2093 if (bits(machInst, 22) == 1) {
2094 index = bits(machInst, 6, 5);
2095 if (u) {
2096 return new VmovRegCoreUB(machInst, rt,
2097 (IntRegIndex)vd, index);
2098 } else {
2099 return new VmovRegCoreSB(machInst, rt,
2100 (IntRegIndex)vd, index);
2101 }
2102 } else if (bits(machInst, 5) == 1) {
2103 index = bits(machInst, 6);
2104 if (u) {
2105 return new VmovRegCoreUH(machInst, rt,
2106 (IntRegIndex)vd, index);
2107 } else {
2108 return new VmovRegCoreSH(machInst, rt,
2109 (IntRegIndex)vd, index);
2110 }
2111 } else if (bits(machInst, 6) == 0 && !u) {
2112 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2113 } else {
2114 return new Unknown(machInst);
2115 }
2116 }
2117 return new Unknown(machInst);
2118 }
2119 '''
2120}};
2121
2122def format ShortFpTransfer() {{
2123 decode_block = '''
2124 return decodeShortFpTransfer(machInst);
2125 '''
2126}};
2127
2128let {{
2129 header_output = '''
2130 StaticInstPtr
2131 decodeVfpData(ExtMachInst machInst);
2132 '''
2133 decoder_output = '''
2134 StaticInstPtr
2135 decodeVfpData(ExtMachInst machInst)
2136 {
2137 const uint32_t opc1 = bits(machInst, 23, 20);
2138 const uint32_t opc2 = bits(machInst, 19, 16);
2139 const uint32_t opc3 = bits(machInst, 7, 6);
2140 //const uint32_t opc4 = bits(machInst, 3, 0);
2141 const bool single = (bits(machInst, 8) == 0);
2142 // Used to select between vcmp and vcmpe.
2143 const bool e = (bits(machInst, 7) == 1);
2144 IntRegIndex vd;
2145 IntRegIndex vm;
2146 IntRegIndex vn;
2147 if (single) {
2148 vd = (IntRegIndex)(bits(machInst, 22) |
2149 (bits(machInst, 15, 12) << 1));
2150 vm = (IntRegIndex)(bits(machInst, 5) |
2151 (bits(machInst, 3, 0) << 1));
2152 vn = (IntRegIndex)(bits(machInst, 7) |
2153 (bits(machInst, 19, 16) << 1));
2154 } else {
2155 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2156 (bits(machInst, 15, 12) << 1));
2157 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2158 (bits(machInst, 3, 0) << 1));
2159 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2160 (bits(machInst, 19, 16) << 1));
2161 }
2162 switch (opc1 & 0xb /* 1011 */) {
2163 case 0x0:
2164 if (bits(machInst, 6) == 0) {
2165 if (single) {
2166 return decodeVfpRegRegRegOp<VmlaS>(
2167 machInst, vd, vn, vm, false);
2168 } else {
2169 return decodeVfpRegRegRegOp<VmlaD>(
2170 machInst, vd, vn, vm, true);
2171 }
2172 } else {
2173 if (single) {
2174 return decodeVfpRegRegRegOp<VmlsS>(
2175 machInst, vd, vn, vm, false);
2176 } else {
2177 return decodeVfpRegRegRegOp<VmlsD>(
2178 machInst, vd, vn, vm, true);
2179 }
2180 }
2181 case 0x1:
2182 if (bits(machInst, 6) == 1) {
2183 if (single) {
2184 return decodeVfpRegRegRegOp<VnmlaS>(
2185 machInst, vd, vn, vm, false);
2186 } else {
2187 return decodeVfpRegRegRegOp<VnmlaD>(
2188 machInst, vd, vn, vm, true);
2189 }
2190 } else {
2191 if (single) {
2192 return decodeVfpRegRegRegOp<VnmlsS>(
2193 machInst, vd, vn, vm, false);
2194 } else {
2195 return decodeVfpRegRegRegOp<VnmlsD>(
2196 machInst, vd, vn, vm, true);
2197 }
2198 }
2199 case 0x2:
2200 if ((opc3 & 0x1) == 0) {
2201 if (single) {
2202 return decodeVfpRegRegRegOp<VmulS>(
2203 machInst, vd, vn, vm, false);
2204 } else {
2205 return decodeVfpRegRegRegOp<VmulD>(
2206 machInst, vd, vn, vm, true);
2207 }
2208 } else {
2209 if (single) {
2210 return decodeVfpRegRegRegOp<VnmulS>(
2211 machInst, vd, vn, vm, false);
2212 } else {
2213 return decodeVfpRegRegRegOp<VnmulD>(
2214 machInst, vd, vn, vm, true);
2215 }
2216 }
2217 case 0x3:
2218 if ((opc3 & 0x1) == 0) {
2219 if (single) {
2220 return decodeVfpRegRegRegOp<VaddS>(
2221 machInst, vd, vn, vm, false);
2222 } else {
2223 return decodeVfpRegRegRegOp<VaddD>(
2224 machInst, vd, vn, vm, true);
2225 }
2226 } else {
2227 if (single) {
2228 return decodeVfpRegRegRegOp<VsubS>(
2229 machInst, vd, vn, vm, false);
2230 } else {
2231 return decodeVfpRegRegRegOp<VsubD>(
2232 machInst, vd, vn, vm, true);
2233 }
2234 }
2235 case 0x8:
2236 if ((opc3 & 0x1) == 0) {
2237 if (single) {
2238 return decodeVfpRegRegRegOp<VdivS>(
2239 machInst, vd, vn, vm, false);
2240 } else {
2241 return decodeVfpRegRegRegOp<VdivD>(
2242 machInst, vd, vn, vm, true);
2243 }
2244 }
2245 break;
2246 case 0xb:
2247 if ((opc3 & 0x1) == 0) {
2248 const uint32_t baseImm =
2249 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2250 if (single) {
2251 uint32_t imm = vfp_modified_imm(baseImm, false);
2252 return decodeVfpRegImmOp<VmovImmS>(
2253 machInst, vd, imm, false);
2254 } else {
2255 uint64_t imm = vfp_modified_imm(baseImm, true);
2256 return decodeVfpRegImmOp<VmovImmD>(
2257 machInst, vd, imm, true);
2258 }
2259 }
2260 switch (opc2) {
2261 case 0x0:
2262 if (opc3 == 1) {
2263 if (single) {
2264 return decodeVfpRegRegOp<VmovRegS>(
2265 machInst, vd, vm, false);
2266 } else {
2267 return decodeVfpRegRegOp<VmovRegD>(
2268 machInst, vd, vm, true);
2269 }
2270 } else {
2271 if (single) {
2272 return decodeVfpRegRegOp<VabsS>(
2273 machInst, vd, vm, false);
2274 } else {
2275 return decodeVfpRegRegOp<VabsD>(
2276 machInst, vd, vm, true);
2277 }
2278 }
2279 case 0x1:
2280 if (opc3 == 1) {
2281 if (single) {
2282 return decodeVfpRegRegOp<VnegS>(
2283 machInst, vd, vm, false);
2284 } else {
2285 return decodeVfpRegRegOp<VnegD>(
2286 machInst, vd, vm, true);
2287 }
2288 } else {
2289 if (single) {
2290 return decodeVfpRegRegOp<VsqrtS>(
2291 machInst, vd, vm, false);
2292 } else {
2293 return decodeVfpRegRegOp<VsqrtD>(
2294 machInst, vd, vm, true);
2295 }
2296 }
2297 case 0x2:
2298 case 0x3:
2299 {
2300 const bool toHalf = bits(machInst, 16);
2301 const bool top = bits(machInst, 7);
2302 if (top) {
2303 if (toHalf) {
2304 return new VcvtFpSFpHT(machInst, vd, vm);
2305 } else {
2306 return new VcvtFpHTFpS(machInst, vd, vm);
2307 }
2308 } else {
2309 if (toHalf) {
2310 return new VcvtFpSFpHB(machInst, vd, vm);
2311 } else {
2312 return new VcvtFpHBFpS(machInst, vd, vm);
2313 }
2314 }
2315 }
2316 case 0x4:
2317 if (single) {
2318 if (e) {
2319 return new VcmpeS(machInst, vd, vm);
2320 } else {
2321 return new VcmpS(machInst, vd, vm);
2322 }
2323 } else {
2324 if (e) {
2325 return new VcmpeD(machInst, vd, vm);
2326 } else {
2327 return new VcmpD(machInst, vd, vm);
2328 }
2329 }
2330 case 0x5:
2331 if (single) {
2332 if (e) {
2333 return new VcmpeZeroS(machInst, vd, 0);
2334 } else {
2335 return new VcmpZeroS(machInst, vd, 0);
2336 }
2337 } else {
2338 if (e) {
2339 return new VcmpeZeroD(machInst, vd, 0);
2340 } else {
2341 return new VcmpZeroD(machInst, vd, 0);
2342 }
2343 }
2344 case 0x7:
2345 if (opc3 == 0x3) {
2346 if (single) {
2347 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2348 (bits(machInst, 15, 12) << 1));
2349 return new VcvtFpSFpD(machInst, vd, vm);
2350 } else {
2351 vd = (IntRegIndex)(bits(machInst, 22) |
2352 (bits(machInst, 15, 12) << 1));
2353 return new VcvtFpDFpS(machInst, vd, vm);
2354 }
2355 }
2356 break;
2357 case 0x8:
2358 if (bits(machInst, 7) == 0) {
2359 if (single) {
2360 return new VcvtUIntFpS(machInst, vd, vm);
2361 } else {
2362 vm = (IntRegIndex)(bits(machInst, 5) |
2363 (bits(machInst, 3, 0) << 1));
2364 return new VcvtUIntFpD(machInst, vd, vm);
2365 }
2366 } else {
2367 if (single) {
2368 return new VcvtSIntFpS(machInst, vd, vm);
2369 } else {
2370 vm = (IntRegIndex)(bits(machInst, 5) |
2371 (bits(machInst, 3, 0) << 1));
2372 return new VcvtSIntFpD(machInst, vd, vm);
2373 }
2374 }
2375 case 0xa:
2376 {
2377 const bool half = (bits(machInst, 7) == 0);
2378 const uint32_t imm = bits(machInst, 5) |
2379 (bits(machInst, 3, 0) << 1);
2380 const uint32_t size =
2381 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2382 if (single) {
2383 if (half) {
2384 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2385 } else {
2386 return new VcvtSFixedFpS(machInst, vd, vd, size);
2387 }
2388 } else {
2389 if (half) {
2390 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2391 } else {
2392 return new VcvtSFixedFpD(machInst, vd, vd, size);
2393 }
2394 }
2395 }
2396 case 0xb:
2397 {
2398 const bool half = (bits(machInst, 7) == 0);
2399 const uint32_t imm = bits(machInst, 5) |
2400 (bits(machInst, 3, 0) << 1);
2401 const uint32_t size =
2402 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2403 if (single) {
2404 if (half) {
2405 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2406 } else {
2407 return new VcvtUFixedFpS(machInst, vd, vd, size);
2408 }
2409 } else {
2410 if (half) {
2411 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2412 } else {
2413 return new VcvtUFixedFpD(machInst, vd, vd, size);
2414 }
2415 }
2416 }
2417 case 0xc:
2418 if (bits(machInst, 7) == 0) {
2419 if (single) {
2420 return new VcvtFpUIntSR(machInst, vd, vm);
2421 } else {
2422 vd = (IntRegIndex)(bits(machInst, 22) |
2423 (bits(machInst, 15, 12) << 1));
2424 return new VcvtFpUIntDR(machInst, vd, vm);
2425 }
2426 } else {
2427 if (single) {
2428 return new VcvtFpUIntS(machInst, vd, vm);
2429 } else {
2430 vd = (IntRegIndex)(bits(machInst, 22) |
2431 (bits(machInst, 15, 12) << 1));
2432 return new VcvtFpUIntD(machInst, vd, vm);
2433 }
2434 }
2435 case 0xd:
2436 if (bits(machInst, 7) == 0) {
2437 if (single) {
2438 return new VcvtFpSIntSR(machInst, vd, vm);
2439 } else {
2440 vd = (IntRegIndex)(bits(machInst, 22) |
2441 (bits(machInst, 15, 12) << 1));
2442 return new VcvtFpSIntDR(machInst, vd, vm);
2443 }
2444 } else {
2445 if (single) {
2446 return new VcvtFpSIntS(machInst, vd, vm);
2447 } else {
2448 vd = (IntRegIndex)(bits(machInst, 22) |
2449 (bits(machInst, 15, 12) << 1));
2450 return new VcvtFpSIntD(machInst, vd, vm);
2451 }
2452 }
2453 case 0xe:
2454 {
2455 const bool half = (bits(machInst, 7) == 0);
2456 const uint32_t imm = bits(machInst, 5) |
2457 (bits(machInst, 3, 0) << 1);
2458 const uint32_t size =
2459 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2460 if (single) {
2461 if (half) {
2462 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2463 } else {
2464 return new VcvtFpSFixedS(machInst, vd, vd, size);
2465 }
2466 } else {
2467 if (half) {
2468 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2469 } else {
2470 return new VcvtFpSFixedD(machInst, vd, vd, size);
2471 }
2472 }
2473 }
2474 case 0xf:
2475 {
2476 const bool half = (bits(machInst, 7) == 0);
2477 const uint32_t imm = bits(machInst, 5) |
2478 (bits(machInst, 3, 0) << 1);
2479 const uint32_t size =
2480 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2481 if (single) {
2482 if (half) {
2483 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2484 } else {
2485 return new VcvtFpUFixedS(machInst, vd, vd, size);
2486 }
2487 } else {
2488 if (half) {
2489 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2490 } else {
2491 return new VcvtFpUFixedD(machInst, vd, vd, size);
2492 }
2493 }
2494 }
2495 }
2496 break;
2497 }
2498 return new Unknown(machInst);
2499 }
2500 '''
2501}};
2502
2503def format VfpData() {{
2504 decode_block = '''
2505 return decodeVfpData(machInst);
2506 '''
2507}};