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