3 // Copyright (c) 2010 ARM Limited
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.
15 // Copyright (c) 2007-2008 The Florida State University
16 // All rights reserved.
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.
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.
41 // Authors: Stephen Hines
43 ////////////////////////////////////////////////////////////////////
45 // Floating Point operate instructions
50 template<template <typename T> class Base>
52 newNeonMemInst(const unsigned size,
53 const ExtMachInst &machInst,
54 const RegIndex dest, const RegIndex ra,
55 const uint32_t imm, const unsigned extraMemFlags)
59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
71 template<template <typename T> class Base>
73 newNeonMixInst(const unsigned size,
74 const ExtMachInst &machInst,
75 const RegIndex dest, const RegIndex op1,
80 return new Base<uint8_t>(machInst, dest, op1, step);
82 return new Base<uint16_t>(machInst, dest, op1, step);
84 return new Base<uint32_t>(machInst, dest, op1, step);
86 return new Base<uint64_t>(machInst, dest, op1, step);
88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
97 decodeNeonMem(ExtMachInst machInst);
100 decodeNeonData(ExtMachInst machInst);
105 decodeNeonMem(ExtMachInst machInst)
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);
115 width = bits(b, 1, 0) + 1;
117 switch (bits(b, 3, 1)) {
120 case 0x1: width = (b & 0x1) ? 2 : 1;
129 if ((b & 0x1) == 0) {
133 // Fall through on purpose.
135 return new Unknown(machInst);
138 assert(width > 0 && width <= 4);
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);
146 uint32_t align = TLB::MustBeOne;
152 size = bits(machInst, 7, 6);
153 bool t = bits(machInst, 5);
154 unsigned eBytes = (1 << size);
155 align = (eBytes - 1) | TLB::AllowUnaligned;
166 if (bits(machInst, 4))
167 align = width * eBytes - 1;
173 if (bits(machInst, 4) == 0)
174 return new Unknown(machInst);
177 } else if (size == 2) {
178 if (bits(machInst, 4))
181 if (bits(machInst, 4))
182 align = 4 * eBytes - 1;
187 size = bits(machInst, 11, 10);
188 unsigned eBytes = (1 << size);
189 align = (eBytes - 1) | TLB::AllowUnaligned;
191 unsigned indexAlign = bits(machInst, 7, 4);
192 // If width is 1, inc is always 1. That's overridden later.
196 lane = bits(indexAlign, 3, 1);
199 inc = bits(indexAlign, 1) ? 2 : 1;
200 lane = bits(indexAlign, 3, 2);
203 inc = bits(indexAlign, 2) ? 2 : 1;
204 lane = bits(indexAlign, 3);
207 // Override inc for width of 1.
217 if (bits(indexAlign, 0))
221 if (bits(indexAlign, 1, 0))
227 if (bits(indexAlign, 0))
228 align = (2 * eBytes) - 1;
236 if (bits(indexAlign, 0))
237 align = (4 * eBytes) - 1;
240 if (bits(indexAlign, 0))
241 align = (4 << bits(indexAlign, 1, 0)) - 1;
248 return new Unknown(machInst);
251 size = bits(machInst, 7, 6);
252 align = bits(machInst, 5, 4);
254 // @align wasn't specified, so alignment can be turned off.
255 align = ((1 << size) - 1) | TLB::AllowUnaligned;
257 align = ((4 << align) - 1);
271 return new Unknown(machInst);
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.
279 case 0x8: regs = 2; inc = 1;
281 case 0x9: regs = 2; inc = 2;
283 case 0x3: regs = 4; inc = 2;
286 return new Unknown(machInst);
297 return new Unknown(machInst);
308 return new Unknown(machInst);
315 // Load instructions.
317 return new VldSingle(machInst, singleAll, width, rn, vd,
318 regs, inc, size, align, rm, lane);
320 return new VldMult(machInst, width, rn, vd,
321 regs, inc, size, align, rm);
324 // Store instructions.
327 return new Unknown(machInst);
329 return new VstSingle(machInst, false, width, rn, vd,
330 regs, inc, size, align, rm, lane);
333 return new VstMult(machInst, width, rn, vd,
334 regs, inc, size, align, rm);
337 return new Unknown(machInst);
341 decoder_output += '''
343 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
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);
366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
367 q, size, machInst, vd, vn, vm);
369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
370 q, size, machInst, vd, vn, vm);
374 return new Unknown(machInst);
375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
376 q, u, size, machInst, vd, vn, vm);
380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
381 q, u, size, machInst, vd, vn, vm);
387 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
389 return new VeorD<uint64_t>(machInst, vd, vn, vm);
393 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
395 return new VbslD<uint64_t>(machInst, vd, vn, vm);
399 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
401 return new VbitD<uint64_t>(machInst, vd, vn, vm);
405 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
407 return new VbifD<uint64_t>(machInst, vd, vn, vm);
414 return new VandQ<uint64_t>(machInst, vd, vn, vm);
416 return new VandD<uint64_t>(machInst, vd, vn, vm);
420 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
422 return new VbicD<uint64_t>(machInst, vd, vn, vm);
427 return new VmovQ<uint64_t>(
428 machInst, vd, vn, vm);
430 return new VmovD<uint64_t>(
431 machInst, vd, vn, vm);
435 return new VorrQ<uint64_t>(
436 machInst, vd, vn, vm);
438 return new VorrD<uint64_t>(
439 machInst, vd, vn, vm);
444 return new VornQ<uint64_t>(
445 machInst, vd, vn, vm);
447 return new VornD<uint64_t>(
448 machInst, vd, vn, vm);
456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
457 q, size, machInst, vd, vn, vm);
459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
460 q, size, machInst, vd, vn, vm);
464 return new Unknown(machInst);
465 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
466 q, u, size, machInst, vd, vn, vm);
470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
471 q, u, size, machInst, vd, vn, vm);
473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
474 q, u, size, machInst, vd, vn, vm);
479 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
480 q, size, machInst, vd, vm, vn);
482 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
483 q, size, machInst, vd, vm, vn);
486 return decodeNeonUSThreeReg<VshlD, VshlQ>(
487 q, u, size, machInst, vd, vm, vn);
492 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
493 q, size, machInst, vd, vm, vn);
495 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
496 q, size, machInst, vd, vm, vn);
499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
500 q, u, size, machInst, vd, vm, vn);
504 return decodeNeonUSThreeReg<VminD, VminQ>(
505 q, u, size, machInst, vd, vn, vm);
507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
508 q, u, size, machInst, vd, vn, vm);
512 return decodeNeonUSThreeReg<VabaD, VabaQ>(
513 q, u, size, machInst, vd, vn, vm);
515 if (bits(machInst, 23) == 1) {
517 return new Unknown(machInst);
519 return decodeNeonUSThreeUSReg<Vabdl>(
520 u, size, machInst, vd, vn, vm);
523 return decodeNeonUSThreeReg<VabdD, VabdQ>(
524 q, u, size, machInst, vd, vn, vm);
530 return decodeNeonUThreeReg<VceqD, VceqQ>(
531 q, size, machInst, vd, vn, vm);
533 return decodeNeonUThreeReg<VtstD, VtstQ>(
534 q, size, machInst, vd, vn, vm);
538 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
539 q, size, machInst, vd, vn, vm);
541 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
542 q, size, machInst, vd, vn, vm);
548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
549 q, size, machInst, vd, vn, vm);
551 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
552 q, size, machInst, vd, vn, vm);
556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
557 q, u, size, machInst, vd, vn, vm);
559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
560 q, u, size, machInst, vd, vn, vm);
565 return decodeNeonUSThreeReg<VpminD, VpminQ>(
566 q, u, size, machInst, vd, vn, vm);
568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
569 q, u, size, machInst, vd, vn, vm);
574 return new Unknown(machInst);
576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
577 q, size, machInst, vd, vn, vm);
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582 q, size, machInst, vd, vn, vm);
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585 q, size, machInst, vd, vn, vm);
589 return new Unknown(machInst);
593 if (bits(c, 1) == 0) {
595 return new NVmulQFp<float>(machInst, vd, vn, vm);
597 return new NVmulDFp<float>(machInst, vd, vn, vm);
600 return new Unknown(machInst);
603 if (bits(c, 1) == 0) {
605 return new NVmlaQFp<float>(machInst, vd, vn, vm);
607 return new NVmlaDFp<float>(machInst, vd, vn, vm);
611 return new NVmlsQFp<float>(machInst, vd, vn, vm);
613 return new NVmlsDFp<float>(machInst, vd, vn, vm);
619 if (bits(c, 1) == 0) {
621 return new VpaddQFp<float>(machInst, vd, vn, vm);
623 return new VpaddDFp<float>(machInst, vd, vn, vm);
627 return new VabdQFp<float>(machInst, vd, vn, vm);
629 return new VabdDFp<float>(machInst, vd, vn, vm);
633 if (bits(c, 1) == 0) {
635 return new VaddQFp<float>(machInst, vd, vn, vm);
637 return new VaddDFp<float>(machInst, vd, vn, vm);
641 return new VsubQFp<float>(machInst, vd, vn, vm);
643 return new VsubDFp<float>(machInst, vd, vn, vm);
651 if (bits(c, 1) == 0) {
653 return new VacgeQFp<float>(machInst, vd, vn, vm);
655 return new VacgeDFp<float>(machInst, vd, vn, vm);
659 return new VacgtQFp<float>(machInst, vd, vn, vm);
661 return new VacgtDFp<float>(machInst, vd, vn, vm);
665 return new Unknown(machInst);
669 if (bits(c, 1) == 0) {
671 return new VcgeQFp<float>(machInst, vd, vn, vm);
673 return new VcgeDFp<float>(machInst, vd, vn, vm);
677 return new VcgtQFp<float>(machInst, vd, vn, vm);
679 return new VcgtDFp<float>(machInst, vd, vn, vm);
683 if (bits(c, 1) == 0) {
685 return new VceqQFp<float>(machInst, vd, vn, vm);
687 return new VceqDFp<float>(machInst, vd, vn, vm);
690 return new Unknown(machInst);
697 return new Unknown(machInst);
699 if (bits(c, 1) == 0) {
701 return new VrecpsQFp<float>(machInst, vd, vn, vm);
703 return new VrecpsDFp<float>(machInst, vd, vn, vm);
707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
715 if (bits(c, 1) == 0) {
717 return new VpmaxQFp<float>(machInst, vd, vn, vm);
719 return new VpmaxDFp<float>(machInst, vd, vn, vm);
723 return new VpminQFp<float>(machInst, vd, vn, vm);
725 return new VpminDFp<float>(machInst, vd, vn, vm);
729 if (bits(c, 1) == 0) {
731 return new VmaxQFp<float>(machInst, vd, vn, vm);
733 return new VmaxDFp<float>(machInst, vd, vn, vm);
737 return new VminQFp<float>(machInst, vd, vn, vm);
739 return new VminDFp<float>(machInst, vd, vn, vm);
745 return new Unknown(machInst);
749 decodeNeonOneRegModImm(ExtMachInst machInst)
751 const IntRegIndex vd =
752 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
753 (bits(machInst, 22) << 4)));
754 const bool q = bits(machInst, 6);
755 const bool op = bits(machInst, 5);
756 const uint8_t cmode = bits(machInst, 11, 8);
757 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
758 bits(machInst, 24)) << 7) |
759 (bits(machInst, 18, 16) << 4) |
760 (bits(machInst, 3, 0) << 0);
762 // Check for invalid immediate encodings and return an unknown op
764 bool immValid = true;
765 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
767 return new Unknown(machInst);
771 if (bits(cmode, 3) == 0) {
772 if (bits(cmode, 0) == 0) {
774 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
776 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
779 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
781 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
784 if (bits(cmode, 2) == 1) {
785 switch (bits(cmode, 1, 0)) {
789 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
791 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
796 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
799 return new Unknown(machInst);
801 return new Unknown(machInst);
804 if (bits(cmode, 0) == 0) {
806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
808 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
811 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
813 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
818 if (bits(cmode, 3) == 0) {
819 if (bits(cmode, 0) == 0) {
821 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
823 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
826 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
828 return new NVorriD<uint64_t>(machInst, vd, bigImm);
831 if (bits(cmode, 2) == 1) {
833 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
835 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
837 if (bits(cmode, 0) == 0) {
839 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
841 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
844 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
846 return new NVorriD<uint64_t>(machInst, vd, bigImm);
851 return new Unknown(machInst);
855 decodeNeonTwoRegAndShift(ExtMachInst machInst)
857 const uint32_t a = bits(machInst, 11, 8);
858 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
859 const bool b = bits(machInst, 6);
860 const bool l = bits(machInst, 7);
861 const IntRegIndex vd =
862 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
863 (bits(machInst, 22) << 4)));
864 const IntRegIndex vm =
865 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
866 (bits(machInst, 5) << 4)));
867 unsigned imm6 = bits(machInst, 21, 16);
868 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
870 unsigned lShiftAmt = 0;
872 for (bitSel = 1 << 6; true; bitSel >>= 1) {
876 return new Unknown(machInst);
879 lShiftAmt = imm6 & ~bitSel;
880 unsigned rShiftAmt = 0;
881 if (a != 0xe && a != 0xf) {
883 rShiftAmt = 64 - imm6;
885 rShiftAmt = 2 * (8 << size) - imm6;
890 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
891 b, u, size, machInst, vd, vm, rShiftAmt);
893 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
894 b, u, size, machInst, vd, vm, rShiftAmt);
896 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
897 b, u, size, machInst, vd, vm, rShiftAmt);
899 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
900 b, u, size, machInst, vd, vm, rShiftAmt);
903 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
904 b, size, machInst, vd, vm, rShiftAmt);
906 return new Unknown(machInst);
910 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
911 b, size, machInst, vd, vm, lShiftAmt);
913 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
914 b, size, machInst, vd, vm, lShiftAmt);
920 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
921 b, size, machInst, vd, vm, lShiftAmt);
923 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
924 b, size, machInst, vd, vm, lShiftAmt);
927 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
928 b, size, machInst, vd, vm, lShiftAmt);
932 return new Unknown(machInst);
934 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
935 b, size, machInst, vd, vm, rShiftAmt);
937 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
938 b, size, machInst, vd, vm, rShiftAmt);
942 return new Unknown(machInst);
944 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
945 b, size, machInst, vd, vm, rShiftAmt);
947 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
948 b, size, machInst, vd, vm, rShiftAmt);
952 return new Unknown(machInst);
954 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
955 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
959 return new Unknown(machInst);
961 if (bits(imm6, 5) == 0)
962 return new Unknown(machInst);
965 return new NVcvtu2fpQ<float>(
966 machInst, vd, vm, 64 - imm6);
968 return new NVcvtu2fpD<float>(
969 machInst, vd, vm, 64 - imm6);
973 return new NVcvts2fpQ<float>(
974 machInst, vd, vm, 64 - imm6);
976 return new NVcvts2fpD<float>(
977 machInst, vd, vm, 64 - imm6);
983 return new Unknown(machInst);
985 if (bits(imm6, 5) == 0)
986 return new Unknown(machInst);
989 return new NVcvt2ufxQ<float>(
990 machInst, vd, vm, 64 - imm6);
992 return new NVcvt2ufxD<float>(
993 machInst, vd, vm, 64 - imm6);
997 return new NVcvt2sfxQ<float>(
998 machInst, vd, vm, 64 - imm6);
1000 return new NVcvt2sfxD<float>(
1001 machInst, vd, vm, 64 - imm6);
1006 return new Unknown(machInst);
1009 static StaticInstPtr
1010 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1012 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1013 const uint32_t a = bits(machInst, 11, 8);
1014 const IntRegIndex vd =
1015 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1016 (bits(machInst, 22) << 4)));
1017 const IntRegIndex vn =
1018 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1019 (bits(machInst, 7) << 4)));
1020 const IntRegIndex vm =
1021 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1022 (bits(machInst, 5) << 4)));
1023 const unsigned size = bits(machInst, 21, 20);
1026 return decodeNeonUSThreeUSReg<Vaddl>(
1027 u, size, machInst, vd, vn, vm);
1029 return decodeNeonUSThreeUSReg<Vaddw>(
1030 u, size, machInst, vd, vn, vm);
1032 return decodeNeonUSThreeUSReg<Vsubl>(
1033 u, size, machInst, vd, vn, vm);
1035 return decodeNeonUSThreeUSReg<Vsubw>(
1036 u, size, machInst, vd, vn, vm);
1039 return decodeNeonUThreeUSReg<Vraddhn>(
1040 size, machInst, vd, vn, vm);
1042 return decodeNeonUThreeUSReg<Vaddhn>(
1043 size, machInst, vd, vn, vm);
1046 return decodeNeonUSThreeUSReg<Vabal>(
1047 u, size, machInst, vd, vn, vm);
1050 return decodeNeonUThreeUSReg<Vrsubhn>(
1051 size, machInst, vd, vn, vm);
1053 return decodeNeonUThreeUSReg<Vsubhn>(
1054 size, machInst, vd, vn, vm);
1057 if (bits(machInst, 23)) {
1058 return decodeNeonUSThreeUSReg<Vabdl>(
1059 u, size, machInst, vd, vn, vm);
1061 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1062 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1065 return decodeNeonUSThreeUSReg<Vmlal>(
1066 u, size, machInst, vd, vn, vm);
1068 return decodeNeonUSThreeUSReg<Vmlsl>(
1069 u, size, machInst, vd, vn, vm);
1072 return new Unknown(machInst);
1074 return decodeNeonSThreeUSReg<Vqdmlal>(
1075 size, machInst, vd, vn, vm);
1079 return new Unknown(machInst);
1081 return decodeNeonSThreeUSReg<Vqdmlsl>(
1082 size, machInst, vd, vn, vm);
1085 return decodeNeonUSThreeUSReg<Vmull>(
1086 u, size, machInst, vd, vn, vm);
1089 return new Unknown(machInst);
1091 return decodeNeonSThreeUSReg<Vqdmull>(
1092 size, machInst, vd, vn, vm);
1095 return decodeNeonUThreeUSReg<Vmullp>(
1096 size, machInst, vd, vn, vm);
1098 return new Unknown(machInst);
1101 static StaticInstPtr
1102 decodeNeonTwoRegScalar(ExtMachInst machInst)
1104 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1105 const uint32_t a = bits(machInst, 11, 8);
1106 const unsigned size = bits(machInst, 21, 20);
1107 const IntRegIndex vd =
1108 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1109 (bits(machInst, 22) << 4)));
1110 const IntRegIndex vn =
1111 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1112 (bits(machInst, 7) << 4)));
1113 const IntRegIndex vm = (size == 2) ?
1114 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1115 (IntRegIndex)(2 * bits(machInst, 2, 0));
1116 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1117 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1123 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1125 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1127 return new Unknown(machInst);
1132 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1134 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1136 return new Unknown(machInst);
1141 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1143 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1148 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1150 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1152 return new Unknown(machInst);
1157 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1159 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1161 return new Unknown(machInst);
1166 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1168 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1173 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1175 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1177 return new Unknown(machInst);
1182 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1184 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1186 return new Unknown(machInst);
1193 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1195 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1197 return new Unknown(machInst);
1202 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1204 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1206 return new Unknown(machInst);
1211 return new Unknown(machInst);
1215 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1217 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1219 return new Unknown(machInst);
1224 return new Unknown(machInst);
1228 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1230 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1232 return new Unknown(machInst);
1239 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1241 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1243 return new Unknown(machInst);
1248 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1250 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1252 return new Unknown(machInst);
1257 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1259 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1264 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1266 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1268 return new Unknown(machInst);
1273 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1275 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1277 return new Unknown(machInst);
1282 return new Unknown(machInst);
1287 return new Vqdmulls<uint16_t>(
1288 machInst, vd, vn, vm, index);
1290 return new Vqdmulls<uint32_t>(
1291 machInst, vd, vn, vm, index);
1293 return new Unknown(machInst);
1298 return new Vqdmulls<int16_t>(
1299 machInst, vd, vn, vm, index);
1301 return new Vqdmulls<int32_t>(
1302 machInst, vd, vn, vm, index);
1304 return new Unknown(machInst);
1312 return new VqdmulhsQ<int16_t>(
1313 machInst, vd, vn, vm, index);
1315 return new VqdmulhsQ<int32_t>(
1316 machInst, vd, vn, vm, index);
1318 return new Unknown(machInst);
1323 return new VqdmulhsD<int16_t>(
1324 machInst, vd, vn, vm, index);
1326 return new VqdmulhsD<int32_t>(
1327 machInst, vd, vn, vm, index);
1329 return new Unknown(machInst);
1336 return new VqrdmulhsQ<int16_t>(
1337 machInst, vd, vn, vm, index);
1339 return new VqrdmulhsQ<int32_t>(
1340 machInst, vd, vn, vm, index);
1342 return new Unknown(machInst);
1347 return new VqrdmulhsD<int16_t>(
1348 machInst, vd, vn, vm, index);
1350 return new VqrdmulhsD<int32_t>(
1351 machInst, vd, vn, vm, index);
1353 return new Unknown(machInst);
1357 return new Unknown(machInst);
1360 static StaticInstPtr
1361 decodeNeonTwoRegMisc(ExtMachInst machInst)
1363 const uint32_t a = bits(machInst, 17, 16);
1364 const uint32_t b = bits(machInst, 10, 6);
1365 const bool q = bits(machInst, 6);
1366 const IntRegIndex vd =
1367 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1368 (bits(machInst, 22) << 4)));
1369 const IntRegIndex vm =
1370 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1371 (bits(machInst, 5) << 4)));
1372 const unsigned size = bits(machInst, 19, 18);
1375 switch (bits(b, 4, 1)) {
1380 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1382 return new NVrev64D<uint8_t>(machInst, vd, vm);
1386 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1388 return new NVrev64D<uint16_t>(machInst, vd, vm);
1392 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1394 return new NVrev64D<uint32_t>(machInst, vd, vm);
1397 return new Unknown(machInst);
1403 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1405 return new NVrev32D<uint8_t>(machInst, vd, vm);
1409 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1411 return new NVrev32D<uint16_t>(machInst, vd, vm);
1414 return new Unknown(machInst);
1418 return new Unknown(machInst);
1420 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1422 return new NVrev16D<uint8_t>(machInst, vd, vm);
1425 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1426 q, size, machInst, vd, vm);
1428 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1429 q, size, machInst, vd, vm);
1431 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1432 q, size, machInst, vd, vm);
1434 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1435 q, size, machInst, vd, vm);
1437 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1438 q, size, machInst, vd, vm);
1441 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1443 return new NVmvnD<uint64_t>(machInst, vd, vm);
1445 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1446 q, size, machInst, vd, vm);
1448 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1449 q, size, machInst, vd, vm);
1451 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1452 q, size, machInst, vd, vm);
1454 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1455 q, size, machInst, vd, vm);
1457 return new Unknown(machInst);
1460 switch (bits(b, 3, 1)) {
1464 return new NVcgtQFp<float>(machInst, vd, vm);
1466 return new NVcgtDFp<float>(machInst, vd, vm);
1469 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1470 q, size, machInst, vd, vm);
1475 return new NVcgeQFp<float>(machInst, vd, vm);
1477 return new NVcgeDFp<float>(machInst, vd, vm);
1480 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1481 q, size, machInst, vd, vm);
1486 return new NVceqQFp<float>(machInst, vd, vm);
1488 return new NVceqDFp<float>(machInst, vd, vm);
1491 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1492 q, size, machInst, vd, vm);
1497 return new NVcleQFp<float>(machInst, vd, vm);
1499 return new NVcleDFp<float>(machInst, vd, vm);
1502 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1503 q, size, machInst, vd, vm);
1508 return new NVcltQFp<float>(machInst, vd, vm);
1510 return new NVcltDFp<float>(machInst, vd, vm);
1513 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1514 q, size, machInst, vd, vm);
1517 if (bits(machInst, 10)) {
1519 return new NVabsQFp<float>(machInst, vd, vm);
1521 return new NVabsDFp<float>(machInst, vd, vm);
1523 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1524 q, size, machInst, vd, vm);
1527 if (bits(machInst, 10)) {
1529 return new NVnegQFp<float>(machInst, vd, vm);
1531 return new NVnegDFp<float>(machInst, vd, vm);
1533 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1534 q, size, machInst, vd, vm);
1538 switch (bits(b, 4, 1)) {
1541 return new NVswpQ<uint64_t>(machInst, vd, vm);
1543 return new NVswpD<uint64_t>(machInst, vd, vm);
1545 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
1546 q, size, machInst, vd, vm);
1548 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1549 q, size, machInst, vd, vm);
1551 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1552 q, size, machInst, vd, vm);
1555 return decodeNeonUTwoMiscUSReg<NVmovn>(
1556 size, machInst, vd, vm);
1558 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1559 size, machInst, vd, vm);
1563 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1564 size, machInst, vd, vm);
1566 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1567 size, machInst, vd, vm);
1571 const IntRegIndex vd =
1572 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1573 (bits(machInst, 22) << 4)));
1574 const IntRegIndex vm =
1575 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1576 (bits(machInst, 5) << 4)));
1577 unsigned size = bits(machInst, 19, 18);
1578 return decodeNeonSTwoShiftUSReg<NVshll>(
1579 size, machInst, vd, vm, 8 << size);
1581 return new Unknown(machInst);
1586 if (size != 1 || (vm % 2))
1587 return new Unknown(machInst);
1588 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1589 } else if (b == 0x1c) {
1590 if (size != 1 || (vd % 2))
1591 return new Unknown(machInst);
1592 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1594 return new Unknown(machInst);
1597 return new Unknown(machInst);
1600 if (bits(b, 4, 3) == 0x3) {
1601 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1602 return new Unknown(machInst);
1607 return new NVcvt2ufxQ<float>(
1608 machInst, vd, vm, 0);
1610 return new NVcvt2ufxD<float>(
1611 machInst, vd, vm, 0);
1615 return new NVcvt2sfxQ<float>(
1616 machInst, vd, vm, 0);
1618 return new NVcvt2sfxD<float>(
1619 machInst, vd, vm, 0);
1625 return new NVcvtu2fpQ<float>(
1626 machInst, vd, vm, 0);
1628 return new NVcvtu2fpD<float>(
1629 machInst, vd, vm, 0);
1633 return new NVcvts2fpQ<float>(
1634 machInst, vd, vm, 0);
1636 return new NVcvts2fpD<float>(
1637 machInst, vd, vm, 0);
1642 } else if ((b & 0x1a) == 0x10) {
1645 return new NVrecpeQFp<float>(machInst, vd, vm);
1647 return new NVrecpeDFp<float>(machInst, vd, vm);
1651 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1653 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1656 } else if ((b & 0x1a) == 0x12) {
1659 return new NVrsqrteQFp<float>(machInst, vd, vm);
1661 return new NVrsqrteDFp<float>(machInst, vd, vm);
1665 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1667 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1671 return new Unknown(machInst);
1674 return new Unknown(machInst);
1678 decodeNeonData(ExtMachInst machInst)
1680 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1681 const uint32_t a = bits(machInst, 23, 19);
1682 const uint32_t b = bits(machInst, 11, 8);
1683 const uint32_t c = bits(machInst, 7, 4);
1684 if (bits(a, 4) == 0) {
1685 return decodeNeonThreeRegistersSameLength(machInst);
1686 } else if ((c & 0x9) == 1) {
1687 if ((a & 0x7) == 0) {
1688 return decodeNeonOneRegModImm(machInst);
1690 return decodeNeonTwoRegAndShift(machInst);
1692 } else if ((c & 0x9) == 9) {
1693 return decodeNeonTwoRegAndShift(machInst);
1694 } else if (bits(a, 2, 1) != 0x3) {
1695 if ((c & 0x5) == 0) {
1696 return decodeNeonThreeRegDiffLengths(machInst);
1697 } else if ((c & 0x5) == 4) {
1698 return decodeNeonTwoRegScalar(machInst);
1700 } else if ((a & 0x16) == 0x16) {
1701 const IntRegIndex vd =
1702 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1703 (bits(machInst, 22) << 4)));
1704 const IntRegIndex vn =
1705 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1706 (bits(machInst, 7) << 4)));
1707 const IntRegIndex vm =
1708 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1709 (bits(machInst, 5) << 4)));
1711 if (bits(c, 0) == 0) {
1712 unsigned imm4 = bits(machInst, 11, 8);
1713 bool q = bits(machInst, 6);
1714 if (imm4 >= 16 && !q)
1715 return new Unknown(machInst);
1717 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1719 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1722 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1723 return decodeNeonTwoRegMisc(machInst);
1724 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1725 unsigned length = bits(machInst, 9, 8) + 1;
1726 if ((uint32_t)vn / 2 + length > 32)
1727 return new Unknown(machInst);
1728 if (bits(machInst, 6) == 0) {
1731 return new NVtbl1(machInst, vd, vn, vm);
1733 return new NVtbl2(machInst, vd, vn, vm);
1735 return new NVtbl3(machInst, vd, vn, vm);
1737 return new NVtbl4(machInst, vd, vn, vm);
1742 return new NVtbx1(machInst, vd, vn, vm);
1744 return new NVtbx2(machInst, vd, vn, vm);
1746 return new NVtbx3(machInst, vd, vn, vm);
1748 return new NVtbx4(machInst, vd, vn, vm);
1751 } else if (b == 0xc && (c & 0x9) == 0) {
1752 unsigned imm4 = bits(machInst, 19, 16);
1753 if (bits(imm4, 2, 0) == 0)
1754 return new Unknown(machInst);
1756 while ((imm4 & 0x1) == 0) {
1760 unsigned index = imm4 >> 1;
1761 const bool q = bits(machInst, 6);
1762 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1763 q, size, machInst, vd, vm, index);
1766 return new Unknown(machInst);
1771 def format ThumbNeonMem() {{
1773 return decodeNeonMem(machInst);
1777 def format ThumbNeonData() {{
1779 return decodeNeonData(machInst);
1786 decodeExtensionRegLoadStore(ExtMachInst machInst);
1788 decoder_output = '''
1790 decodeExtensionRegLoadStore(ExtMachInst machInst)
1792 const uint32_t opcode = bits(machInst, 24, 20);
1793 const uint32_t offset = bits(machInst, 7, 0);
1794 const bool single = (bits(machInst, 8) == 0);
1795 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1798 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1799 bits(machInst, 22));
1801 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1802 (bits(machInst, 22) << 5));
1804 switch (bits(opcode, 4, 3)) {
1806 if (bits(opcode, 4, 1) == 0x2 &&
1807 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1808 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1809 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1812 const IntRegIndex rt =
1813 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1814 const IntRegIndex rt2 =
1815 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1816 const bool op = bits(machInst, 20);
1819 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1821 vm = (bits(machInst, 3, 0) << 1) |
1822 (bits(machInst, 5) << 5);
1825 return new Vmov2Core2Reg(machInst, rt, rt2,
1828 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1835 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1838 switch (bits(opcode, 1, 0)) {
1840 return new VLdmStm(machInst, rn, vd, single,
1841 true, false, false, offset);
1843 return new VLdmStm(machInst, rn, vd, single,
1844 true, false, true, offset);
1846 return new VLdmStm(machInst, rn, vd, single,
1847 true, true, false, offset);
1849 // If rn == sp, then this is called vpop.
1850 return new VLdmStm(machInst, rn, vd, single,
1851 true, true, true, offset);
1855 if (bits(opcode, 1, 0) == 0x2) {
1856 // If rn == sp, then this is called vpush.
1857 return new VLdmStm(machInst, rn, vd, single,
1858 false, true, false, offset);
1859 } else if (bits(opcode, 1, 0) == 0x3) {
1860 return new VLdmStm(machInst, rn, vd, single,
1861 false, true, true, offset);
1863 // Fall through on purpose
1865 const bool up = (bits(machInst, 23) == 1);
1866 const uint32_t imm = bits(machInst, 7, 0) << 2;
1869 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1870 (bits(machInst, 22)));
1872 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1873 (bits(machInst, 22) << 5));
1875 if (bits(opcode, 1, 0) == 0x0) {
1878 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1880 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1884 return new %(vstr_ud)s(machInst, vd, vd + 1,
1887 return new %(vstr_d)s(machInst, vd, vd + 1,
1891 } else if (bits(opcode, 1, 0) == 0x1) {
1894 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1896 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1900 return new %(vldr_ud)s(machInst, vd, vd + 1,
1903 return new %(vldr_d)s(machInst, vd, vd + 1,
1909 return new Unknown(machInst);
1912 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1913 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1914 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1915 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1916 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1917 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1918 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1919 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1923 def format ExtensionRegLoadStore() {{
1925 return decodeExtensionRegLoadStore(machInst);
1932 decodeShortFpTransfer(ExtMachInst machInst);
1934 decoder_output = '''
1936 decodeShortFpTransfer(ExtMachInst machInst)
1938 const uint32_t l = bits(machInst, 20);
1939 const uint32_t c = bits(machInst, 8);
1940 const uint32_t a = bits(machInst, 23, 21);
1941 const uint32_t b = bits(machInst, 6, 5);
1942 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1943 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1944 return new Unknown(machInst);
1946 if (l == 0 && c == 0) {
1948 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1950 const IntRegIndex rt =
1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1952 if (bits(machInst, 20) == 1) {
1953 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1955 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1957 } else if (a == 0x7) {
1958 const IntRegIndex rt =
1959 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1960 uint32_t specReg = bits(machInst, 19, 16);
1963 specReg = MISCREG_FPSID;
1966 specReg = MISCREG_FPSCR;
1969 specReg = MISCREG_MVFR1;
1972 specReg = MISCREG_MVFR0;
1975 specReg = MISCREG_FPEXC;
1978 return new Unknown(machInst);
1980 if (specReg == MISCREG_FPSCR) {
1981 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1983 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1986 } else if (l == 0 && c == 1) {
1987 if (bits(a, 2) == 0) {
1988 uint32_t vd = (bits(machInst, 7) << 5) |
1989 (bits(machInst, 19, 16) << 1);
1990 // Handle accessing each single precision half of the vector.
1991 vd += bits(machInst, 21);
1992 const IntRegIndex rt =
1993 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1994 if (bits(machInst, 22) == 1) {
1995 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1996 rt, bits(machInst, 6, 5));
1997 } else if (bits(machInst, 5) == 1) {
1998 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1999 rt, bits(machInst, 6));
2000 } else if (bits(machInst, 6) == 0) {
2001 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2003 return new Unknown(machInst);
2005 } else if (bits(b, 1) == 0) {
2006 bool q = bits(machInst, 21);
2007 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2008 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2009 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2010 IntRegIndex rt = (IntRegIndex)(uint32_t)
2011 bits(machInst, 15, 12);
2015 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2017 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2019 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2021 return new Unknown(machInst);
2026 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2028 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2030 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2032 return new Unknown(machInst);
2036 } else if (l == 1 && c == 0) {
2038 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2040 const IntRegIndex rt =
2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042 if (bits(machInst, 20) == 1) {
2043 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2045 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2047 } else if (a == 7) {
2048 const IntRegIndex rt =
2049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2050 uint32_t specReg = bits(machInst, 19, 16);
2053 specReg = MISCREG_FPSID;
2056 specReg = MISCREG_FPSCR;
2059 specReg = MISCREG_MVFR1;
2062 specReg = MISCREG_MVFR0;
2065 specReg = MISCREG_FPEXC;
2068 return new Unknown(machInst);
2076 if (specReg == MISCREG_FPSCR) {
2077 return new VmrsApsrFpscr(machInst, INTREG_CONDCODES,
2078 (IntRegIndex)specReg, (uint32_t)cpsrMask);
2080 return new VmrsApsr(machInst, INTREG_CONDCODES,
2081 (IntRegIndex)specReg, (uint32_t)cpsrMask);
2083 } else if (specReg == MISCREG_FPSCR) {
2084 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2086 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2090 uint32_t vd = (bits(machInst, 7) << 5) |
2091 (bits(machInst, 19, 16) << 1);
2092 // Handle indexing into each single precision half of the vector.
2093 vd += bits(machInst, 21);
2095 const IntRegIndex rt =
2096 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2097 const bool u = (bits(machInst, 23) == 1);
2098 if (bits(machInst, 22) == 1) {
2099 index = bits(machInst, 6, 5);
2101 return new VmovRegCoreUB(machInst, rt,
2102 (IntRegIndex)vd, index);
2104 return new VmovRegCoreSB(machInst, rt,
2105 (IntRegIndex)vd, index);
2107 } else if (bits(machInst, 5) == 1) {
2108 index = bits(machInst, 6);
2110 return new VmovRegCoreUH(machInst, rt,
2111 (IntRegIndex)vd, index);
2113 return new VmovRegCoreSH(machInst, rt,
2114 (IntRegIndex)vd, index);
2116 } else if (bits(machInst, 6) == 0 && !u) {
2117 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2119 return new Unknown(machInst);
2122 return new Unknown(machInst);
2127 def format ShortFpTransfer() {{
2129 return decodeShortFpTransfer(machInst);
2136 decodeVfpData(ExtMachInst machInst);
2138 decoder_output = '''
2140 decodeVfpData(ExtMachInst machInst)
2142 const uint32_t opc1 = bits(machInst, 23, 20);
2143 const uint32_t opc2 = bits(machInst, 19, 16);
2144 const uint32_t opc3 = bits(machInst, 7, 6);
2145 //const uint32_t opc4 = bits(machInst, 3, 0);
2146 const bool single = (bits(machInst, 8) == 0);
2147 // Used to select between vcmp and vcmpe.
2148 const bool e = (bits(machInst, 7) == 1);
2153 vd = (IntRegIndex)(bits(machInst, 22) |
2154 (bits(machInst, 15, 12) << 1));
2155 vm = (IntRegIndex)(bits(machInst, 5) |
2156 (bits(machInst, 3, 0) << 1));
2157 vn = (IntRegIndex)(bits(machInst, 7) |
2158 (bits(machInst, 19, 16) << 1));
2160 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2161 (bits(machInst, 15, 12) << 1));
2162 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2163 (bits(machInst, 3, 0) << 1));
2164 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2165 (bits(machInst, 19, 16) << 1));
2167 switch (opc1 & 0xb /* 1011 */) {
2169 if (bits(machInst, 6) == 0) {
2171 return decodeVfpRegRegRegOp<VmlaS>(
2172 machInst, vd, vn, vm, false);
2174 return decodeVfpRegRegRegOp<VmlaD>(
2175 machInst, vd, vn, vm, true);
2179 return decodeVfpRegRegRegOp<VmlsS>(
2180 machInst, vd, vn, vm, false);
2182 return decodeVfpRegRegRegOp<VmlsD>(
2183 machInst, vd, vn, vm, true);
2187 if (bits(machInst, 6) == 1) {
2189 return decodeVfpRegRegRegOp<VnmlaS>(
2190 machInst, vd, vn, vm, false);
2192 return decodeVfpRegRegRegOp<VnmlaD>(
2193 machInst, vd, vn, vm, true);
2197 return decodeVfpRegRegRegOp<VnmlsS>(
2198 machInst, vd, vn, vm, false);
2200 return decodeVfpRegRegRegOp<VnmlsD>(
2201 machInst, vd, vn, vm, true);
2205 if ((opc3 & 0x1) == 0) {
2207 return decodeVfpRegRegRegOp<VmulS>(
2208 machInst, vd, vn, vm, false);
2210 return decodeVfpRegRegRegOp<VmulD>(
2211 machInst, vd, vn, vm, true);
2215 return decodeVfpRegRegRegOp<VnmulS>(
2216 machInst, vd, vn, vm, false);
2218 return decodeVfpRegRegRegOp<VnmulD>(
2219 machInst, vd, vn, vm, true);
2223 if ((opc3 & 0x1) == 0) {
2225 return decodeVfpRegRegRegOp<VaddS>(
2226 machInst, vd, vn, vm, false);
2228 return decodeVfpRegRegRegOp<VaddD>(
2229 machInst, vd, vn, vm, true);
2233 return decodeVfpRegRegRegOp<VsubS>(
2234 machInst, vd, vn, vm, false);
2236 return decodeVfpRegRegRegOp<VsubD>(
2237 machInst, vd, vn, vm, true);
2241 if ((opc3 & 0x1) == 0) {
2243 return decodeVfpRegRegRegOp<VdivS>(
2244 machInst, vd, vn, vm, false);
2246 return decodeVfpRegRegRegOp<VdivD>(
2247 machInst, vd, vn, vm, true);
2252 if ((opc3 & 0x1) == 0) {
2253 const uint32_t baseImm =
2254 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2256 uint32_t imm = vfp_modified_imm(baseImm, false);
2257 return decodeVfpRegImmOp<VmovImmS>(
2258 machInst, vd, imm, false);
2260 uint64_t imm = vfp_modified_imm(baseImm, true);
2261 return decodeVfpRegImmOp<VmovImmD>(
2262 machInst, vd, imm, true);
2269 return decodeVfpRegRegOp<VmovRegS>(
2270 machInst, vd, vm, false);
2272 return decodeVfpRegRegOp<VmovRegD>(
2273 machInst, vd, vm, true);
2277 return decodeVfpRegRegOp<VabsS>(
2278 machInst, vd, vm, false);
2280 return decodeVfpRegRegOp<VabsD>(
2281 machInst, vd, vm, true);
2287 return decodeVfpRegRegOp<VnegS>(
2288 machInst, vd, vm, false);
2290 return decodeVfpRegRegOp<VnegD>(
2291 machInst, vd, vm, true);
2295 return decodeVfpRegRegOp<VsqrtS>(
2296 machInst, vd, vm, false);
2298 return decodeVfpRegRegOp<VsqrtD>(
2299 machInst, vd, vm, true);
2305 const bool toHalf = bits(machInst, 16);
2306 const bool top = bits(machInst, 7);
2309 return new VcvtFpSFpHT(machInst, vd, vm);
2311 return new VcvtFpHTFpS(machInst, vd, vm);
2315 return new VcvtFpSFpHB(machInst, vd, vm);
2317 return new VcvtFpHBFpS(machInst, vd, vm);
2324 return new VcmpeS(machInst, vd, vm);
2326 return new VcmpS(machInst, vd, vm);
2330 return new VcmpeD(machInst, vd, vm);
2332 return new VcmpD(machInst, vd, vm);
2338 return new VcmpeZeroS(machInst, vd, 0);
2340 return new VcmpZeroS(machInst, vd, 0);
2344 return new VcmpeZeroD(machInst, vd, 0);
2346 return new VcmpZeroD(machInst, vd, 0);
2352 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2353 (bits(machInst, 15, 12) << 1));
2354 return new VcvtFpSFpD(machInst, vd, vm);
2356 vd = (IntRegIndex)(bits(machInst, 22) |
2357 (bits(machInst, 15, 12) << 1));
2358 return new VcvtFpDFpS(machInst, vd, vm);
2363 if (bits(machInst, 7) == 0) {
2365 return new VcvtUIntFpS(machInst, vd, vm);
2367 vm = (IntRegIndex)(bits(machInst, 5) |
2368 (bits(machInst, 3, 0) << 1));
2369 return new VcvtUIntFpD(machInst, vd, vm);
2373 return new VcvtSIntFpS(machInst, vd, vm);
2375 vm = (IntRegIndex)(bits(machInst, 5) |
2376 (bits(machInst, 3, 0) << 1));
2377 return new VcvtSIntFpD(machInst, vd, vm);
2382 const bool half = (bits(machInst, 7) == 0);
2383 const uint32_t imm = bits(machInst, 5) |
2384 (bits(machInst, 3, 0) << 1);
2385 const uint32_t size =
2386 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2389 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2391 return new VcvtSFixedFpS(machInst, vd, vd, size);
2395 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2397 return new VcvtSFixedFpD(machInst, vd, vd, size);
2403 const bool half = (bits(machInst, 7) == 0);
2404 const uint32_t imm = bits(machInst, 5) |
2405 (bits(machInst, 3, 0) << 1);
2406 const uint32_t size =
2407 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2410 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2412 return new VcvtUFixedFpS(machInst, vd, vd, size);
2416 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2418 return new VcvtUFixedFpD(machInst, vd, vd, size);
2423 if (bits(machInst, 7) == 0) {
2425 return new VcvtFpUIntSR(machInst, vd, vm);
2427 vd = (IntRegIndex)(bits(machInst, 22) |
2428 (bits(machInst, 15, 12) << 1));
2429 return new VcvtFpUIntDR(machInst, vd, vm);
2433 return new VcvtFpUIntS(machInst, vd, vm);
2435 vd = (IntRegIndex)(bits(machInst, 22) |
2436 (bits(machInst, 15, 12) << 1));
2437 return new VcvtFpUIntD(machInst, vd, vm);
2441 if (bits(machInst, 7) == 0) {
2443 return new VcvtFpSIntSR(machInst, vd, vm);
2445 vd = (IntRegIndex)(bits(machInst, 22) |
2446 (bits(machInst, 15, 12) << 1));
2447 return new VcvtFpSIntDR(machInst, vd, vm);
2451 return new VcvtFpSIntS(machInst, vd, vm);
2453 vd = (IntRegIndex)(bits(machInst, 22) |
2454 (bits(machInst, 15, 12) << 1));
2455 return new VcvtFpSIntD(machInst, vd, vm);
2460 const bool half = (bits(machInst, 7) == 0);
2461 const uint32_t imm = bits(machInst, 5) |
2462 (bits(machInst, 3, 0) << 1);
2463 const uint32_t size =
2464 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2467 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2469 return new VcvtFpSFixedS(machInst, vd, vd, size);
2473 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2475 return new VcvtFpSFixedD(machInst, vd, vd, size);
2481 const bool half = (bits(machInst, 7) == 0);
2482 const uint32_t imm = bits(machInst, 5) |
2483 (bits(machInst, 3, 0) << 1);
2484 const uint32_t size =
2485 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2488 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2490 return new VcvtFpUFixedS(machInst, vd, vd, size);
2494 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2496 return new VcvtFpUFixedD(machInst, vd, vd, size);
2503 return new Unknown(machInst);
2508 def format VfpData() {{
2510 return decodeVfpData(machInst);