aarch64.isa revision 13759:9941fca869a9
11917SN/A// Copyright (c) 2011-2018 ARM Limited
21917SN/A// All rights reserved
31917SN/A//
41917SN/A// The license below extends only to copyright in the software and shall
51917SN/A// not be construed as granting a license to any other intellectual
61917SN/A// property including but not limited to intellectual property relating
71917SN/A// to a hardware implementation of the functionality of the software
81917SN/A// licensed hereunder.  You may use the software subject to the license
91917SN/A// terms below provided that you ensure that this notice is replicated
101917SN/A// unmodified and in its entirety in all distributions of the software,
111917SN/A// modified or unmodified, in source code or in binary form.
121917SN/A//
131917SN/A// Redistribution and use in source and binary forms, with or without
141917SN/A// modification, are permitted provided that the following conditions are
151917SN/A// met: redistributions of source code must retain the above copyright
161917SN/A// notice, this list of conditions and the following disclaimer;
171917SN/A// redistributions in binary form must reproduce the above copyright
181917SN/A// notice, this list of conditions and the following disclaimer in the
191917SN/A// documentation and/or other materials provided with the distribution;
201917SN/A// neither the name of the copyright holders nor the names of its
211917SN/A// contributors may be used to endorse or promote products derived from
221917SN/A// this software without specific prior written permission.
231917SN/A//
241917SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
251917SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
261917SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272665Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282665Ssaidi@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
291917SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
301917SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
311917SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
321917SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
331917SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
341917SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351917SN/A//
361917SN/A// Authors: Gabe Black
371917SN/A//          Thomas Grocutt
381917SN/A//          Mbou Eyole
392680Sktlim@umich.edu//          Giacomo Gabrielli
402235SN/A
411917SN/Aoutput header {{
421917SN/Anamespace Aarch64
432107SN/A{
441917SN/A    StaticInstPtr decodeDataProcImm(ExtMachInst machInst);
452680Sktlim@umich.edu    StaticInstPtr decodeBranchExcSys(ExtMachInst machInst);
462680Sktlim@umich.edu    StaticInstPtr decodeLoadsStores(ExtMachInst machInst);
471917SN/A    StaticInstPtr decodeDataProcReg(ExtMachInst machInst);
481917SN/A
491917SN/A    template <typename DecoderFeatures>
502680Sktlim@umich.edu    StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst);
511917SN/A    StaticInstPtr decodeFp(ExtMachInst machInst);
522680Sktlim@umich.edu    template <typename DecoderFeatures>
531917SN/A    StaticInstPtr decodeAdvSIMD(ExtMachInst machInst);
542680Sktlim@umich.edu    StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst);
551917SN/A
562680Sktlim@umich.edu    StaticInstPtr decodeSveInt(ExtMachInst machInst);
571917SN/A    StaticInstPtr decodeSveFp(ExtMachInst machInst);
582680Sktlim@umich.edu    StaticInstPtr decodeSveMem(ExtMachInst machInst);
591917SN/A
602680Sktlim@umich.edu    StaticInstPtr decodeGem5Ops(ExtMachInst machInst);
611917SN/A}
622680Sktlim@umich.edu}};
631917SN/A
642680Sktlim@umich.eduoutput decoder {{
651917SN/Anamespace Aarch64
662680Sktlim@umich.edu{
671917SN/A    StaticInstPtr
682680Sktlim@umich.edu    decodeDataProcImm(ExtMachInst machInst)
691917SN/A    {
701917SN/A        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
711917SN/A        IntRegIndex rdsp = makeSP(rd);
721917SN/A        IntRegIndex rdzr = makeZero(rd);
731917SN/A        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
741917SN/A        IntRegIndex rnsp = makeSP(rn);
751917SN/A
761917SN/A        uint8_t opc = bits(machInst, 30, 29);
771917SN/A        bool sf = bits(machInst, 31);
782680Sktlim@umich.edu        bool n = bits(machInst, 22);
791917SN/A        uint8_t immr = bits(machInst, 21, 16);
801917SN/A        uint8_t imms = bits(machInst, 15, 10);
811917SN/A        switch (bits(machInst, 25, 23)) {
821917SN/A          case 0x0:
831917SN/A          case 0x1:
841917SN/A          {
851917SN/A            uint64_t immlo = bits(machInst, 30, 29);
861917SN/A            uint64_t immhi = bits(machInst, 23, 5);
871917SN/A            uint64_t imm = (immlo << 0) | (immhi << 2);
882680Sktlim@umich.edu            if (bits(machInst, 31) == 0)
891917SN/A                return new AdrXImm(machInst, rdzr, INTREG_ZERO, sext<21>(imm));
901917SN/A            else
911917SN/A                return new AdrpXImm(machInst, rdzr, INTREG_ZERO,
921917SN/A                                    sext<33>(imm << 12));
931917SN/A          }
941917SN/A          case 0x2:
951917SN/A          case 0x3:
961917SN/A          {
971917SN/A            uint32_t imm12 = bits(machInst, 21, 10);
981917SN/A            uint8_t shift = bits(machInst, 23, 22);
992680Sktlim@umich.edu            uint32_t imm;
1001917SN/A            if (shift == 0x0)
1011917SN/A                imm = imm12 << 0;
1021917SN/A            else if (shift == 0x1)
1031917SN/A                imm = imm12 << 12;
1041917SN/A            else
1051917SN/A                return new Unknown64(machInst);
1061977SN/A            switch (opc) {
1072680Sktlim@umich.edu              case 0x0:
1081917SN/A                return new AddXImm(machInst, rdsp, rnsp, imm);
1091977SN/A              case 0x1:
1101977SN/A                return new AddXImmCc(machInst, rdzr, rnsp, imm);
1112680Sktlim@umich.edu              case 0x2:
1122680Sktlim@umich.edu                return new SubXImm(machInst, rdsp, rnsp, imm);
1131977SN/A              case 0x3:
1142680Sktlim@umich.edu                return new SubXImmCc(machInst, rdzr, rnsp, imm);
1151977SN/A              default:
1161977SN/A                M5_UNREACHABLE;
1171977SN/A            }
1181977SN/A          }
1191977SN/A          case 0x4:
1201977SN/A          {
1211977SN/A            if (!sf && n)
1222680Sktlim@umich.edu                return new Unknown64(machInst);
1231977SN/A            // len = MSB(n:NOT(imms)), len < 1 is undefined.
1242680Sktlim@umich.edu            uint8_t len = 0;
1251977SN/A            if (n) {
1262680Sktlim@umich.edu                len = 6;
1271917SN/A            } else if (imms == 0x3f || imms == 0x3e) {
1282680Sktlim@umich.edu                return new Unknown64(machInst);
1292680Sktlim@umich.edu            } else {
1302680Sktlim@umich.edu                len = findMsbSet(imms ^ 0x3f);
1311917SN/A            }
1321917SN/A            // Generate r, s, and size.
1331977SN/A            uint64_t r = bits(immr, len - 1, 0);
1341917SN/A            uint64_t s = bits(imms, len - 1, 0);
1351917SN/A            uint8_t size = 1 << len;
1361917SN/A            if (s == size - 1)
1371917SN/A                return new Unknown64(machInst);
1381977SN/A            // Generate the pattern with s 1s, rotated by r, with size bits.
1391917SN/A            uint64_t pattern = mask(s + 1);
1401917SN/A            if (r) {
1411917SN/A                pattern = (pattern >> r) | (pattern << (size - r));
1422680Sktlim@umich.edu                pattern &= mask(size);
1432680Sktlim@umich.edu            }
1441917SN/A            uint8_t width = sf ? 64 : 32;
1451917SN/A            // Replicate that to fill up the immediate.
1461917SN/A            for (unsigned i = 1; i < (width / size); i *= 2)
1471917SN/A                pattern |= (pattern << (i * size));
1481917SN/A            uint64_t imm = pattern;
1491917SN/A
1501917SN/A            switch (opc) {
1511917SN/A              case 0x0:
1522680Sktlim@umich.edu                return new AndXImm(machInst, rdsp, rn, imm);
1531917SN/A              case 0x1:
1541917SN/A                return new OrrXImm(machInst, rdsp, rn, imm);
1551917SN/A              case 0x2:
1561917SN/A                return new EorXImm(machInst, rdsp, rn, imm);
1571917SN/A              case 0x3:
1581917SN/A                return new AndXImmCc(machInst, rdzr, rn, imm);
1591917SN/A              default:
1601917SN/A                M5_UNREACHABLE;
1611917SN/A            }
1621917SN/A          }
1631917SN/A          case 0x5:
1641917SN/A          {
1651917SN/A            IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1661917SN/A            IntRegIndex rdzr = makeZero(rd);
1671917SN/A            uint32_t imm16 = bits(machInst, 20, 5);
1681917SN/A            uint32_t hw = bits(machInst, 22, 21);
1691917SN/A            switch (opc) {
1701917SN/A              case 0x0:
1711917SN/A                return new Movn(machInst, rdzr, imm16, hw * 16);
1721977SN/A              case 0x1:
1731977SN/A                return new Unknown64(machInst);
1741977SN/A              case 0x2:
1751977SN/A                return new Movz(machInst, rdzr, imm16, hw * 16);
1761977SN/A              case 0x3:
1771917SN/A                return new Movk(machInst, rdzr, imm16, hw * 16);
1781917SN/A              default:
1791917SN/A                M5_UNREACHABLE;
1801977SN/A            }
1811917SN/A          }
1821917SN/A          case 0x6:
1831917SN/A            if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5))))
1842680Sktlim@umich.edu                return new Unknown64(machInst);
1852680Sktlim@umich.edu            switch (opc) {
1861917SN/A              case 0x0:
1871917SN/A                return new Sbfm64(machInst, rdzr, rn, immr, imms);
1881977SN/A              case 0x1:
1891977SN/A                return new Bfm64(machInst, rdzr, rn, immr, imms);
1901977SN/A              case 0x2:
1911917SN/A                return new Ubfm64(machInst, rdzr, rn, immr, imms);
1921917SN/A              case 0x3:
1931917SN/A                return new Unknown64(machInst);
1941917SN/A              default:
1951917SN/A                M5_UNREACHABLE;
1961917SN/A            }
1971917SN/A          case 0x7:
1981917SN/A          {
1992680Sktlim@umich.edu            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
2001917SN/A            if (opc || bits(machInst, 21))
2011917SN/A                return new Unknown64(machInst);
2022680Sktlim@umich.edu            else
2031917SN/A                return new Extr64(machInst, rdzr, rn, rm, imms);
2041917SN/A          }
2052680Sktlim@umich.edu        }
2061917SN/A        return new FailUnimplemented("Unhandled Case8", machInst);
2071917SN/A    }
2082680Sktlim@umich.edu}
2091917SN/A}};
2101917SN/A
2112680Sktlim@umich.eduoutput decoder {{
2121917SN/Anamespace Aarch64
2131917SN/A{
2142680Sktlim@umich.edu    StaticInstPtr
2151917SN/A    decodeBranchExcSys(ExtMachInst machInst)
2161917SN/A    {
2171917SN/A        switch (bits(machInst, 30, 29)) {
2181917SN/A          case 0x0:
2191917SN/A          {
2201917SN/A            int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2;
2211917SN/A            if (bits(machInst, 31) == 0)
2221917SN/A                return new B64(machInst, imm);
2231917SN/A            else
2241917SN/A                return new Bl64(machInst, imm);
2251917SN/A          }
2261917SN/A          case 0x1:
2271917SN/A          {
2281917SN/A            IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
2291917SN/A            if (bits(machInst, 25) == 0) {
2301917SN/A                int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
2311917SN/A                if (bits(machInst, 24) == 0)
2321917SN/A                    return new Cbz64(machInst, imm, rt);
2331917SN/A                else
2341917SN/A                    return new Cbnz64(machInst, imm, rt);
2351917SN/A            } else {
2361917SN/A                uint64_t bitmask = 0x1;
2371917SN/A                bitmask <<= bits(machInst, 23, 19);
2381917SN/A                int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2;
2391917SN/A                if (bits(machInst, 31))
2401917SN/A                    bitmask <<= 32;
2411917SN/A                if (bits(machInst, 24) == 0)
2421917SN/A                    return new Tbz64(machInst, bitmask, imm, rt);
2431917SN/A                else
2441917SN/A                    return new Tbnz64(machInst, bitmask, imm, rt);
2451917SN/A            }
2461917SN/A          }
2471917SN/A          case 0x2:
2481917SN/A            // bit 30:26=10101
2491917SN/A            if (bits(machInst, 31) == 0) {
2501917SN/A                if (bits(machInst, 25, 24) || bits(machInst, 4))
2511917SN/A                    return new Unknown64(machInst);
2521917SN/A                int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
2531917SN/A                ConditionCode condCode =
2541917SN/A                    (ConditionCode)(uint8_t)(bits(machInst, 3, 0));
2551917SN/A                return new BCond64(machInst, imm, condCode);
2561917SN/A            } else if (bits(machInst, 25, 24) == 0x0) {
2571917SN/A
2581917SN/A                if (bits(machInst, 4, 2))
2591917SN/A                    return new Unknown64(machInst);
2601917SN/A
2611917SN/A                auto imm16 = bits(machInst, 20, 5);
2621917SN/A                uint8_t decVal = (bits(machInst, 1, 0) << 0) |
2631917SN/A                                 (bits(machInst, 23, 21) << 2);
2641917SN/A
2651917SN/A                switch (decVal) {
2661917SN/A                  case 0x01:
2671917SN/A                    return new Svc64(machInst, imm16);
2681917SN/A                  case 0x02:
2691917SN/A                    return new Hvc64(machInst, imm16);
2701917SN/A                  case 0x03:
2711917SN/A                    return new Smc64(machInst, imm16);
2721917SN/A                  case 0x04:
2731917SN/A                    return new Brk64(machInst, imm16);
2741917SN/A                  case 0x08:
2751917SN/A                    return new Hlt64(machInst, imm16);
2761917SN/A                  case 0x15:
2771917SN/A                    return new FailUnimplemented("dcps1", machInst);
2781917SN/A                  case 0x16:
2791917SN/A                    return new FailUnimplemented("dcps2", machInst);
2801917SN/A                  case 0x17:
2811917SN/A                    return new FailUnimplemented("dcps3", machInst);
2821917SN/A                  default:
2831917SN/A                    return new Unknown64(machInst);
2841917SN/A                }
2851917SN/A            } else if (bits(machInst, 25, 22) == 0x4) {
2861917SN/A                // bit 31:22=1101010100
2871917SN/A                bool l = bits(machInst, 21);
2881917SN/A                uint8_t op0 = bits(machInst, 20, 19);
2891917SN/A                uint8_t op1 = bits(machInst, 18, 16);
2901917SN/A                uint8_t crn = bits(machInst, 15, 12);
2911917SN/A                uint8_t crm = bits(machInst, 11, 8);
2921917SN/A                uint8_t op2 = bits(machInst, 7, 5);
2931917SN/A                IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
2941917SN/A                switch (op0) {
2951917SN/A                  case 0x0:
2961917SN/A                    if (rt != 0x1f || l)
2971917SN/A                        return new Unknown64(machInst);
2981917SN/A                    if (crn == 0x2 && op1 == 0x3) {
2992680Sktlim@umich.edu                        switch (crm) {
3001917SN/A                          case 0x0:
3011917SN/A                            switch (op2) {
3021917SN/A                              case 0x0:
3031917SN/A                                return new NopInst(machInst);
3041917SN/A                              case 0x1:
3051917SN/A                                return new YieldInst(machInst);
3061917SN/A                              case 0x2:
3071917SN/A                                return new WfeInst(machInst);
3081917SN/A                              case 0x3:
3091917SN/A                                return new WfiInst(machInst);
3102680Sktlim@umich.edu                              case 0x4:
3111917SN/A                                return new SevInst(machInst);
3121917SN/A                              case 0x5:
3131917SN/A                                return new SevlInst(machInst);
3141917SN/A                            }
3151917SN/A                            break;
3161917SN/A                          case 0x1:
3171917SN/A                            switch (op2) {
3181917SN/A                              case 0x0:
3191917SN/A                                return new WarnUnimplemented(
3201917SN/A                                        "pacia", machInst);
3211917SN/A                              case 0x2:
3221917SN/A                                return new WarnUnimplemented(
3231917SN/A                                        "pacib", machInst);
3241917SN/A                              case 0x4:
3251917SN/A                                return new WarnUnimplemented(
3262680Sktlim@umich.edu                                        "autia", machInst);
3272680Sktlim@umich.edu                              case 0x6:
3281917SN/A                                return new WarnUnimplemented(
3291917SN/A                                        "autib", machInst);
3301917SN/A                            }
3311917SN/A                            break;
3321917SN/A                          case 0x2:
3331917SN/A                            switch (op2) {
3341977SN/A                              case 0x0:
3351917SN/A                                return new WarnUnimplemented(
3361977SN/A                                        "esb", machInst);
3371917SN/A                              case 0x1:
3381977SN/A                                return new WarnUnimplemented(
3391917SN/A                                        "psb csync", machInst);
3401917SN/A                              case 0x2:
3411917SN/A                                return new WarnUnimplemented(
3421917SN/A                                        "tsb csync", machInst);
3431917SN/A                              case 0x4:
3441917SN/A                                return new WarnUnimplemented(
3451917SN/A                                        "csdb", machInst);
3461917SN/A                            }
347                            break;
348                          case 0x3:
349                            switch (op2) {
350                              case 0x0:
351                              case 0x1:
352                                return new WarnUnimplemented(
353                                        "pacia", machInst);
354                              case 0x2:
355                              case 0x3:
356                                return new WarnUnimplemented(
357                                        "pacib", machInst);
358                              case 0x4:
359                              case 0x5:
360                                return new WarnUnimplemented(
361                                        "autia", machInst);
362                              case 0x6:
363                              case 0x7:
364                                return new WarnUnimplemented(
365                                        "autib", machInst);
366                            }
367                            break;
368                          case 0x4:
369                            switch (op2 & 0x1) {
370                              case 0x0:
371                                return new WarnUnimplemented(
372                                        "bti", machInst);
373                            }
374                            break;
375                        }
376                        return new WarnUnimplemented(
377                                "unallocated_hint", machInst);
378                    } else if (crn == 0x3 && op1 == 0x3) {
379                        switch (op2) {
380                          case 0x2:
381                            return new Clrex64(machInst);
382                          case 0x4:
383                            return new Dsb64(machInst);
384                          case 0x5:
385                            return new Dmb64(machInst);
386                          case 0x6:
387                            return new Isb64(machInst);
388                          default:
389                            return new Unknown64(machInst);
390                        }
391                    } else if (crn == 0x4) {
392                        // MSR immediate
393                        switch (op1 << 3 | op2) {
394                          case 0x5:
395                            // SP
396                            return new MsrSP64(machInst,
397                                               (IntRegIndex) MISCREG_SPSEL,
398                                               INTREG_ZERO,
399                                               crm & 0x1);
400                          case 0x1e:
401                            // DAIFSet
402                            return new MsrDAIFSet64(
403                                machInst,
404                                (IntRegIndex) MISCREG_DAIF,
405                                INTREG_ZERO,
406                                crm);
407                          case 0x1f:
408                            // DAIFClr
409                            return new MsrDAIFClr64(
410                                machInst,
411                                (IntRegIndex) MISCREG_DAIF,
412                                INTREG_ZERO,
413                                crm);
414                          default:
415                            return new Unknown64(machInst);
416                        }
417                    } else {
418                        return new Unknown64(machInst);
419                    }
420                    break;
421                  case 0x1:
422                  case 0x2:
423                  case 0x3:
424                  {
425                    // bit 31:22=1101010100, 20:19=11
426                    bool read = l;
427                    MiscRegIndex miscReg =
428                        decodeAArch64SysReg(op0, op1, crn, crm, op2);
429                    if (read) {
430                        if ((miscReg == MISCREG_DC_CIVAC_Xt) ||
431                            (miscReg == MISCREG_DC_CVAC_Xt) ||
432                            (miscReg == MISCREG_DC_IVAC_Xt)  ||
433                            (miscReg == MISCREG_DC_ZVA_Xt)) {
434                            return new Unknown64(machInst);
435                        }
436                    }
437                    // Check for invalid registers
438                    if (miscReg == MISCREG_UNKNOWN) {
439                        auto full_mnemonic =
440                            csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
441                                     read ? "mrs" : "msr",
442                                     op0, op1, crn, crm, op2);
443
444                        return new FailUnimplemented(read ? "mrs" : "msr",
445                            machInst, full_mnemonic);
446
447                    } else if (miscReg == MISCREG_IMPDEF_UNIMPL) {
448                        auto full_mnemonic =
449                            csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
450                                     read ? "mrs" : "msr",
451                                     op0, op1, crn, crm, op2);
452
453                        uint32_t iss = msrMrs64IssBuild(
454                            read, op0, op1, crn, crm, op2, rt);
455
456                        return new MiscRegImplDefined64(
457                            read ? "mrs" : "msr",
458                            machInst, miscReg, read, iss, full_mnemonic,
459                            miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]);
460
461                    } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
462                        if (miscReg == MISCREG_NZCV) {
463                            if (read)
464                                return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg);
465                            else
466                                return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt);
467                        }
468                        uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt);
469                        if (read) {
470                            StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss);
471                            if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
472                                si->setFlag(StaticInst::IsUnverifiable);
473                            return si;
474                        } else {
475                            switch (miscReg) {
476                              case MISCREG_DC_ZVA_Xt:
477                                return new Dczva(machInst, rt, miscReg, iss);
478                              case MISCREG_DC_CVAU_Xt:
479                                return new Dccvau(machInst, rt, miscReg, iss);
480                              case MISCREG_DC_CVAC_Xt:
481                                return new Dccvac(machInst, rt, miscReg, iss);
482                              case MISCREG_DC_CIVAC_Xt:
483                                return new Dccivac(machInst, rt, miscReg, iss);
484                              case MISCREG_DC_IVAC_Xt:
485                                return new Dcivac(machInst, rt, miscReg, iss);
486                              default:
487                                return new Msr64(machInst, miscReg, rt, iss);
488                            }
489                        }
490                    } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
491                        std::string full_mnem = csprintf("%s %s",
492                            read ? "mrs" : "msr", miscRegName[miscReg]);
493                        return new WarnUnimplemented(read ? "mrs" : "msr",
494                                                     machInst, full_mnem);
495                    } else {
496                        return new FailUnimplemented(read ? "mrs" : "msr",
497                                    machInst,
498                                    csprintf("%s %s",
499                                      read ? "mrs" : "msr",
500                                      miscRegName[miscReg]));
501                    }
502                  }
503                  break;
504                  default:
505                    M5_UNREACHABLE;
506                }
507            } else if (bits(machInst, 25) == 0x1) {
508                uint8_t opc = bits(machInst, 24, 21);
509                uint8_t op2 = bits(machInst, 20, 16);
510                uint8_t op3 = bits(machInst, 15, 10);
511                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
512                uint8_t op4 = bits(machInst, 4, 0);
513                if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0)
514                    return new Unknown64(machInst);
515                switch (opc) {
516                  case 0x0:
517                    return new Br64(machInst, rn);
518                  case 0x1:
519                    return new Blr64(machInst, rn);
520                  case 0x2:
521                    return new Ret64(machInst, rn);
522                  case 0x4:
523                    if (rn != 0x1f)
524                        return new Unknown64(machInst);
525                    return new Eret64(machInst);
526                  case 0x5:
527                    if (rn != 0x1f)
528                        return new Unknown64(machInst);
529                    return new FailUnimplemented("dret", machInst);
530                  default:
531                    return new Unknown64(machInst);
532                }
533            }
534          M5_FALLTHROUGH;
535          default:
536            return new Unknown64(machInst);
537        }
538        return new FailUnimplemented("Unhandled Case7", machInst);
539    }
540}
541}};
542
543output decoder {{
544namespace Aarch64
545{
546    StaticInstPtr
547    decodeLoadsStores(ExtMachInst machInst)
548    {
549        // bit 27,25=10
550        switch (bits(machInst, 29, 28)) {
551          case 0x0:
552            if (bits(machInst, 26) == 0) {
553                if (bits(machInst, 24) != 0)
554                    return new Unknown64(machInst);
555                IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
556                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
557                IntRegIndex rnsp = makeSP(rn);
558                IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
559                IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
560                uint8_t opc = (bits(machInst, 15) << 0) |
561                              (bits(machInst, 23, 21) << 1);
562                uint8_t size = bits(machInst, 31, 30);
563                switch (opc) {
564                  case 0x0:
565                    switch (size) {
566                      case 0x0:
567                        return new STXRB64(machInst, rt, rnsp, rs);
568                      case 0x1:
569                        return new STXRH64(machInst, rt, rnsp, rs);
570                      case 0x2:
571                        return new STXRW64(machInst, rt, rnsp, rs);
572                      case 0x3:
573                        return new STXRX64(machInst, rt, rnsp, rs);
574                      default:
575                        M5_UNREACHABLE;
576                    }
577                  case 0x1:
578                    switch (size) {
579                      case 0x0:
580                        return new STLXRB64(machInst, rt, rnsp, rs);
581                      case 0x1:
582                        return new STLXRH64(machInst, rt, rnsp, rs);
583                      case 0x2:
584                        return new STLXRW64(machInst, rt, rnsp, rs);
585                      case 0x3:
586                        return new STLXRX64(machInst, rt, rnsp, rs);
587                      default:
588                        M5_UNREACHABLE;
589                    }
590                  case 0x2:
591                    switch (size) {
592                      case 0x0:
593                      case 0x1:
594                        return new Unknown64(machInst);
595                      case 0x2:
596                        return new STXPW64(machInst, rs, rt, rt2, rnsp);
597                      case 0x3:
598                        return new STXPX64(machInst, rs, rt, rt2, rnsp);
599                      default:
600                        M5_UNREACHABLE;
601                    }
602
603                  case 0x3:
604                    switch (size) {
605                      case 0x0:
606                      case 0x1:
607                        return new Unknown64(machInst);
608                      case 0x2:
609                        return new STLXPW64(machInst, rs, rt, rt2, rnsp);
610                      case 0x3:
611                        return new STLXPX64(machInst, rs, rt, rt2, rnsp);
612                      default:
613                        M5_UNREACHABLE;
614                    }
615
616                  case 0x4:
617                    switch (size) {
618                      case 0x0:
619                        return new LDXRB64(machInst, rt, rnsp, rs);
620                      case 0x1:
621                        return new LDXRH64(machInst, rt, rnsp, rs);
622                      case 0x2:
623                        return new LDXRW64(machInst, rt, rnsp, rs);
624                      case 0x3:
625                        return new LDXRX64(machInst, rt, rnsp, rs);
626                      default:
627                        M5_UNREACHABLE;
628                    }
629                  case 0x5:
630                    switch (size) {
631                      case 0x0:
632                        return new LDAXRB64(machInst, rt, rnsp, rs);
633                      case 0x1:
634                        return new LDAXRH64(machInst, rt, rnsp, rs);
635                      case 0x2:
636                        return new LDAXRW64(machInst, rt, rnsp, rs);
637                      case 0x3:
638                        return new LDAXRX64(machInst, rt, rnsp, rs);
639                      default:
640                        M5_UNREACHABLE;
641                    }
642                  case 0x6:
643                    switch (size) {
644                      case 0x0:
645                      case 0x1:
646                        return new Unknown64(machInst);
647                      case 0x2:
648                        return new LDXPW64(machInst, rt, rt2, rnsp);
649                      case 0x3:
650                        return new LDXPX64(machInst, rt, rt2, rnsp);
651                      default:
652                        M5_UNREACHABLE;
653                    }
654
655                  case 0x7:
656                    switch (size) {
657                      case 0x0:
658                      case 0x1:
659                        return new Unknown64(machInst);
660                      case 0x2:
661                        return new LDAXPW64(machInst, rt, rt2, rnsp);
662                      case 0x3:
663                        return new LDAXPX64(machInst, rt, rt2, rnsp);
664                      default:
665                        M5_UNREACHABLE;
666                    }
667
668                  case 0x9:
669                    switch (size) {
670                      case 0x0:
671                        return new STLRB64(machInst, rt, rnsp);
672                      case 0x1:
673                        return new STLRH64(machInst, rt, rnsp);
674                      case 0x2:
675                        return new STLRW64(machInst, rt, rnsp);
676                      case 0x3:
677                        return new STLRX64(machInst, rt, rnsp);
678                      default:
679                        M5_UNREACHABLE;
680                    }
681                  case 0xd:
682                    switch (size) {
683                      case 0x0:
684                        return new LDARB64(machInst, rt, rnsp);
685                      case 0x1:
686                        return new LDARH64(machInst, rt, rnsp);
687                      case 0x2:
688                        return new LDARW64(machInst, rt, rnsp);
689                      case 0x3:
690                        return new LDARX64(machInst, rt, rnsp);
691                      default:
692                        M5_UNREACHABLE;
693                    }
694                  default:
695                    return new Unknown64(machInst);
696                }
697            } else if (bits(machInst, 31)) {
698                return new Unknown64(machInst);
699            } else {
700                return decodeNeonMem(machInst);
701            }
702          case 0x1:
703          {
704            if (bits(machInst, 24) != 0)
705                return new Unknown64(machInst);
706            uint8_t switchVal = (bits(machInst, 26) << 0) |
707                                (bits(machInst, 31, 30) << 1);
708            int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
709            IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
710            switch (switchVal) {
711              case 0x0:
712                return new LDRWL64_LIT(machInst, rt, imm);
713              case 0x1:
714                return new LDRSFP64_LIT(machInst, rt, imm);
715              case 0x2:
716                return new LDRXL64_LIT(machInst, rt, imm);
717              case 0x3:
718                return new LDRDFP64_LIT(machInst, rt, imm);
719              case 0x4:
720                return new LDRSWL64_LIT(machInst, rt, imm);
721              case 0x5:
722                return new BigFpMemLit("ldr", machInst, rt, imm);
723              case 0x6:
724                return new PRFM64_LIT(machInst, rt, imm);
725              default:
726                return new Unknown64(machInst);
727            }
728          }
729          case 0x2:
730          {
731            uint8_t opc = bits(machInst, 31, 30);
732            if (opc >= 3)
733                return new Unknown64(machInst);
734            uint32_t size = 0;
735            bool fp = bits(machInst, 26);
736            bool load = bits(machInst, 22);
737            if (fp) {
738                size = 4 << opc;
739            } else {
740                if ((opc == 1) && !load)
741                    return new Unknown64(machInst);
742                size = (opc == 0 || opc == 1) ? 4 : 8;
743            }
744            uint8_t type = bits(machInst, 24, 23);
745            int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
746
747            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
748            IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
749            IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
750
751            bool noAlloc = (type == 0);
752            bool signExt = !noAlloc && !fp && opc == 1;
753            PairMemOp::AddrMode mode;
754            const char *mnemonic = NULL;
755            switch (type) {
756              case 0x0:
757              case 0x2:
758                mode = PairMemOp::AddrMd_Offset;
759                break;
760              case 0x1:
761                mode = PairMemOp::AddrMd_PostIndex;
762                break;
763              case 0x3:
764                mode = PairMemOp::AddrMd_PreIndex;
765                break;
766              default:
767                return new Unknown64(machInst);
768            }
769            if (load) {
770                if (noAlloc)
771                    mnemonic = "ldnp";
772                else if (signExt)
773                    mnemonic = "ldpsw";
774                else
775                    mnemonic = "ldp";
776            } else {
777                if (noAlloc)
778                    mnemonic = "stnp";
779                else
780                    mnemonic = "stp";
781            }
782
783            return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
784                    signExt, false, false, imm, mode, rn, rt, rt2);
785          }
786          // bit 29:27=111, 25=0
787          case 0x3:
788          {
789            uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
790                                (bits(machInst, 26) << 2) |
791                                (bits(machInst, 31, 30) << 3);
792            if (bits(machInst, 24) == 1) {
793                uint64_t imm12 = bits(machInst, 21, 10);
794                IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
795                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
796                IntRegIndex rnsp = makeSP(rn);
797                switch (switchVal) {
798                  case 0x00:
799                    return new STRB64_IMM(machInst, rt, rnsp, imm12);
800                  case 0x01:
801                    return new LDRB64_IMM(machInst, rt, rnsp, imm12);
802                  case 0x02:
803                    return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
804                  case 0x03:
805                    return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
806                  case 0x04:
807                    return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
808                  case 0x05:
809                    return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
810                  case 0x06:
811                    return new BigFpMemImm("str", machInst, false,
812                                           rt, rnsp, imm12 << 4);
813                  case 0x07:
814                    return new BigFpMemImm("ldr", machInst, true,
815                                           rt, rnsp, imm12 << 4);
816                  case 0x08:
817                    return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
818                  case 0x09:
819                    return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
820                  case 0x0a:
821                    return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
822                  case 0x0b:
823                    return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
824                  case 0x0c:
825                    return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
826                  case 0x0d:
827                    return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
828                  case 0x10:
829                    return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
830                  case 0x11:
831                    return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
832                  case 0x12:
833                    return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
834                  case 0x14:
835                    return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
836                  case 0x15:
837                    return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
838                  case 0x18:
839                    return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
840                  case 0x19:
841                    return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
842                  case 0x1a:
843                    return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
844                  case 0x1c:
845                    return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
846                  case 0x1d:
847                    return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
848                  default:
849                    return new Unknown64(machInst);
850                }
851            } else if (bits(machInst, 21) == 1) {
852                uint8_t group = bits(machInst, 11, 10);
853                switch (group) {
854                  case 0x0:
855                    {
856                        if ((switchVal & 0x7) == 0x2 &&
857                                bits(machInst, 20, 12) == 0x1fc) {
858                            IntRegIndex rt = (IntRegIndex)(uint32_t)
859                                bits(machInst, 4, 0);
860                            IntRegIndex rn = (IntRegIndex)(uint32_t)
861                                bits(machInst, 9, 5);
862                            IntRegIndex rnsp = makeSP(rn);
863                            uint8_t size = bits(machInst, 31, 30);
864                            switch (size) {
865                              case 0x0:
866                                return new LDAPRB64(machInst, rt, rnsp);
867                              case 0x1:
868                                return new LDAPRH64(machInst, rt, rnsp);
869                              case 0x2:
870                                return new LDAPRW64(machInst, rt, rnsp);
871                              case 0x3:
872                                return new LDAPRX64(machInst, rt, rnsp);
873                              default:
874                                M5_UNREACHABLE;
875                            }
876                        } else {
877                            return new Unknown64(machInst);
878                        }
879                    }
880                  case 0x2:
881                    {
882                        if (!bits(machInst, 14))
883                            return new Unknown64(machInst);
884                        IntRegIndex rt = (IntRegIndex)(uint32_t)
885                            bits(machInst, 4, 0);
886                        IntRegIndex rn = (IntRegIndex)(uint32_t)
887                            bits(machInst, 9, 5);
888                        IntRegIndex rnsp = makeSP(rn);
889                        IntRegIndex rm = (IntRegIndex)(uint32_t)
890                            bits(machInst, 20, 16);
891                        ArmExtendType type =
892                            (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
893                        uint8_t s = bits(machInst, 12);
894                        switch (switchVal) {
895                          case 0x00:
896                            return new STRB64_REG(machInst, rt, rnsp, rm,
897                                                  type, 0);
898                          case 0x01:
899                            return new LDRB64_REG(machInst, rt, rnsp, rm,
900                                                  type, 0);
901                          case 0x02:
902                            return new LDRSBX64_REG(machInst, rt, rnsp, rm,
903                                                    type, 0);
904                          case 0x03:
905                            return new LDRSBW64_REG(machInst, rt, rnsp, rm,
906                                                    type, 0);
907                          case 0x04:
908                            return new STRBFP64_REG(machInst, rt, rnsp, rm,
909                                                    type, 0);
910                          case 0x05:
911                            return new LDRBFP64_REG(machInst, rt, rnsp, rm,
912                                                    type, 0);
913                          case 0x6:
914                            return new BigFpMemReg("str", machInst, false,
915                                                   rt, rnsp, rm, type, s * 4);
916                          case 0x7:
917                            return new BigFpMemReg("ldr", machInst, true,
918                                                   rt, rnsp, rm, type, s * 4);
919                          case 0x08:
920                            return new STRH64_REG(machInst, rt, rnsp, rm,
921                                                  type, s);
922                          case 0x09:
923                            return new LDRH64_REG(machInst, rt, rnsp, rm,
924                                                  type, s);
925                          case 0x0a:
926                            return new LDRSHX64_REG(machInst, rt, rnsp, rm,
927                                                    type, s);
928                          case 0x0b:
929                            return new LDRSHW64_REG(machInst, rt, rnsp, rm,
930                                                    type, s);
931                          case 0x0c:
932                            return new STRHFP64_REG(machInst, rt, rnsp, rm,
933                                                    type, s);
934                          case 0x0d:
935                            return new LDRHFP64_REG(machInst, rt, rnsp, rm,
936                                                    type, s);
937                          case 0x10:
938                            return new STRW64_REG(machInst, rt, rnsp, rm,
939                                                  type, s * 2);
940                          case 0x11:
941                            return new LDRW64_REG(machInst, rt, rnsp, rm,
942                                                  type, s * 2);
943                          case 0x12:
944                            return new LDRSW64_REG(machInst, rt, rnsp, rm,
945                                                   type, s * 2);
946                          case 0x14:
947                            return new STRSFP64_REG(machInst, rt, rnsp, rm,
948                                                    type, s * 2);
949                          case 0x15:
950                            return new LDRSFP64_REG(machInst, rt, rnsp, rm,
951                                                    type, s * 2);
952                          case 0x18:
953                            return new STRX64_REG(machInst, rt, rnsp, rm,
954                                                  type, s * 3);
955                          case 0x19:
956                            return new LDRX64_REG(machInst, rt, rnsp, rm,
957                                                  type, s * 3);
958                          case 0x1a:
959                            return new PRFM64_REG(machInst, rt, rnsp, rm,
960                                                  type, s * 3);
961                          case 0x1c:
962                            return new STRDFP64_REG(machInst, rt, rnsp, rm,
963                                                    type, s * 3);
964                          case 0x1d:
965                            return new LDRDFP64_REG(machInst, rt, rnsp, rm,
966                                                    type, s * 3);
967                          default:
968                            return new Unknown64(machInst);
969
970                        }
971                    }
972                  default:
973                    return new Unknown64(machInst);
974                }
975            } else {
976                // bit 29:27=111, 25:24=00, 21=0
977                switch (bits(machInst, 11, 10)) {
978                  case 0x0:
979                  {
980                    IntRegIndex rt =
981                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
982                    IntRegIndex rn =
983                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
984                    IntRegIndex rnsp = makeSP(rn);
985                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
986                    switch (switchVal) {
987                      case 0x00:
988                        return new STURB64_IMM(machInst, rt, rnsp, imm);
989                      case 0x01:
990                        return new LDURB64_IMM(machInst, rt, rnsp, imm);
991                      case 0x02:
992                        return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
993                      case 0x03:
994                        return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
995                      case 0x04:
996                        return new STURBFP64_IMM(machInst, rt, rnsp, imm);
997                      case 0x05:
998                        return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
999                      case 0x06:
1000                        return new BigFpMemImm("stur", machInst, false,
1001                                               rt, rnsp, imm);
1002                      case 0x07:
1003                        return new BigFpMemImm("ldur", machInst, true,
1004                                               rt, rnsp, imm);
1005                      case 0x08:
1006                        return new STURH64_IMM(machInst, rt, rnsp, imm);
1007                      case 0x09:
1008                        return new LDURH64_IMM(machInst, rt, rnsp, imm);
1009                      case 0x0a:
1010                        return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
1011                      case 0x0b:
1012                        return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
1013                      case 0x0c:
1014                        return new STURHFP64_IMM(machInst, rt, rnsp, imm);
1015                      case 0x0d:
1016                        return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
1017                      case 0x10:
1018                        return new STURW64_IMM(machInst, rt, rnsp, imm);
1019                      case 0x11:
1020                        return new LDURW64_IMM(machInst, rt, rnsp, imm);
1021                      case 0x12:
1022                        return new LDURSW64_IMM(machInst, rt, rnsp, imm);
1023                      case 0x14:
1024                        return new STURSFP64_IMM(machInst, rt, rnsp, imm);
1025                      case 0x15:
1026                        return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
1027                      case 0x18:
1028                        return new STURX64_IMM(machInst, rt, rnsp, imm);
1029                      case 0x19:
1030                        return new LDURX64_IMM(machInst, rt, rnsp, imm);
1031                      case 0x1a:
1032                        return new PRFUM64_IMM(machInst, rt, rnsp, imm);
1033                      case 0x1c:
1034                        return new STURDFP64_IMM(machInst, rt, rnsp, imm);
1035                      case 0x1d:
1036                        return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
1037                      default:
1038                        return new Unknown64(machInst);
1039                    }
1040                  }
1041                  // bit 29:27=111, 25:24=00, 21=0, 11:10=01
1042                  case 0x1:
1043                  {
1044                    IntRegIndex rt =
1045                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1046                    IntRegIndex rn =
1047                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1048                    IntRegIndex rnsp = makeSP(rn);
1049                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1050                    switch (switchVal) {
1051                      case 0x00:
1052                        return new STRB64_POST(machInst, rt, rnsp, imm);
1053                      case 0x01:
1054                        return new LDRB64_POST(machInst, rt, rnsp, imm);
1055                      case 0x02:
1056                        return new LDRSBX64_POST(machInst, rt, rnsp, imm);
1057                      case 0x03:
1058                        return new LDRSBW64_POST(machInst, rt, rnsp, imm);
1059                      case 0x04:
1060                        return new STRBFP64_POST(machInst, rt, rnsp, imm);
1061                      case 0x05:
1062                        return new LDRBFP64_POST(machInst, rt, rnsp, imm);
1063                      case 0x06:
1064                        return new BigFpMemPost("str", machInst, false,
1065                                                rt, rnsp, imm);
1066                      case 0x07:
1067                        return new BigFpMemPost("ldr", machInst, true,
1068                                                rt, rnsp, imm);
1069                      case 0x08:
1070                        return new STRH64_POST(machInst, rt, rnsp, imm);
1071                      case 0x09:
1072                        return new LDRH64_POST(machInst, rt, rnsp, imm);
1073                      case 0x0a:
1074                        return new LDRSHX64_POST(machInst, rt, rnsp, imm);
1075                      case 0x0b:
1076                        return new LDRSHW64_POST(machInst, rt, rnsp, imm);
1077                      case 0x0c:
1078                        return new STRHFP64_POST(machInst, rt, rnsp, imm);
1079                      case 0x0d:
1080                        return new LDRHFP64_POST(machInst, rt, rnsp, imm);
1081                      case 0x10:
1082                        return new STRW64_POST(machInst, rt, rnsp, imm);
1083                      case 0x11:
1084                        return new LDRW64_POST(machInst, rt, rnsp, imm);
1085                      case 0x12:
1086                        return new LDRSW64_POST(machInst, rt, rnsp, imm);
1087                      case 0x14:
1088                        return new STRSFP64_POST(machInst, rt, rnsp, imm);
1089                      case 0x15:
1090                        return new LDRSFP64_POST(machInst, rt, rnsp, imm);
1091                      case 0x18:
1092                        return new STRX64_POST(machInst, rt, rnsp, imm);
1093                      case 0x19:
1094                        return new LDRX64_POST(machInst, rt, rnsp, imm);
1095                      case 0x1c:
1096                        return new STRDFP64_POST(machInst, rt, rnsp, imm);
1097                      case 0x1d:
1098                        return new LDRDFP64_POST(machInst, rt, rnsp, imm);
1099                      default:
1100                        return new Unknown64(machInst);
1101                    }
1102                  }
1103                  case 0x2:
1104                  {
1105                    IntRegIndex rt =
1106                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1107                    IntRegIndex rn =
1108                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1109                    IntRegIndex rnsp = makeSP(rn);
1110                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1111                    switch (switchVal) {
1112                      case 0x00:
1113                        return new STTRB64_IMM(machInst, rt, rnsp, imm);
1114                      case 0x01:
1115                        return new LDTRB64_IMM(machInst, rt, rnsp, imm);
1116                      case 0x02:
1117                        return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
1118                      case 0x03:
1119                        return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
1120                      case 0x08:
1121                        return new STTRH64_IMM(machInst, rt, rnsp, imm);
1122                      case 0x09:
1123                        return new LDTRH64_IMM(machInst, rt, rnsp, imm);
1124                      case 0x0a:
1125                        return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
1126                      case 0x0b:
1127                        return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
1128                      case 0x10:
1129                        return new STTRW64_IMM(machInst, rt, rnsp, imm);
1130                      case 0x11:
1131                        return new LDTRW64_IMM(machInst, rt, rnsp, imm);
1132                      case 0x12:
1133                        return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
1134                      case 0x18:
1135                        return new STTRX64_IMM(machInst, rt, rnsp, imm);
1136                      case 0x19:
1137                        return new LDTRX64_IMM(machInst, rt, rnsp, imm);
1138                      default:
1139                        return new Unknown64(machInst);
1140                    }
1141                  }
1142                  case 0x3:
1143                  {
1144                    IntRegIndex rt =
1145                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1146                    IntRegIndex rn =
1147                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1148                    IntRegIndex rnsp = makeSP(rn);
1149                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1150                    switch (switchVal) {
1151                      case 0x00:
1152                        return new STRB64_PRE(machInst, rt, rnsp, imm);
1153                      case 0x01:
1154                        return new LDRB64_PRE(machInst, rt, rnsp, imm);
1155                      case 0x02:
1156                        return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
1157                      case 0x03:
1158                        return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
1159                      case 0x04:
1160                        return new STRBFP64_PRE(machInst, rt, rnsp, imm);
1161                      case 0x05:
1162                        return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
1163                      case 0x06:
1164                        return new BigFpMemPre("str", machInst, false,
1165                                               rt, rnsp, imm);
1166                      case 0x07:
1167                        return new BigFpMemPre("ldr", machInst, true,
1168                                               rt, rnsp, imm);
1169                      case 0x08:
1170                        return new STRH64_PRE(machInst, rt, rnsp, imm);
1171                      case 0x09:
1172                        return new LDRH64_PRE(machInst, rt, rnsp, imm);
1173                      case 0x0a:
1174                        return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
1175                      case 0x0b:
1176                        return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
1177                      case 0x0c:
1178                        return new STRHFP64_PRE(machInst, rt, rnsp, imm);
1179                      case 0x0d:
1180                        return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
1181                      case 0x10:
1182                        return new STRW64_PRE(machInst, rt, rnsp, imm);
1183                      case 0x11:
1184                        return new LDRW64_PRE(machInst, rt, rnsp, imm);
1185                      case 0x12:
1186                        return new LDRSW64_PRE(machInst, rt, rnsp, imm);
1187                      case 0x14:
1188                        return new STRSFP64_PRE(machInst, rt, rnsp, imm);
1189                      case 0x15:
1190                        return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
1191                      case 0x18:
1192                        return new STRX64_PRE(machInst, rt, rnsp, imm);
1193                      case 0x19:
1194                        return new LDRX64_PRE(machInst, rt, rnsp, imm);
1195                      case 0x1c:
1196                        return new STRDFP64_PRE(machInst, rt, rnsp, imm);
1197                      case 0x1d:
1198                        return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
1199                      default:
1200                        return new Unknown64(machInst);
1201                    }
1202                  }
1203                  default:
1204                    M5_UNREACHABLE;
1205                }
1206            }
1207          }
1208          default:
1209            M5_UNREACHABLE;
1210        }
1211        return new FailUnimplemented("Unhandled Case1", machInst);
1212    }
1213}
1214}};
1215
1216output decoder {{
1217namespace Aarch64
1218{
1219    StaticInstPtr
1220    decodeDataProcReg(ExtMachInst machInst)
1221    {
1222        uint8_t switchVal = (bits(machInst, 28) << 1) |
1223                            (bits(machInst, 24) << 0);
1224        switch (switchVal) {
1225          case 0x0:
1226          {
1227            uint8_t switchVal = (bits(machInst, 21) << 0) |
1228                                (bits(machInst, 30, 29) << 1);
1229            ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1230            uint8_t imm6 = bits(machInst, 15, 10);
1231            bool sf = bits(machInst, 31);
1232            if (!sf && (imm6 & 0x20))
1233                return new Unknown64(machInst);
1234            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1235            IntRegIndex rdzr = makeZero(rd);
1236            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1237            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1238
1239            switch (switchVal) {
1240              case 0x0:
1241                return new AndXSReg(machInst, rdzr, rn, rm, imm6, type);
1242              case 0x1:
1243                return new BicXSReg(machInst, rdzr, rn, rm, imm6, type);
1244              case 0x2:
1245                return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type);
1246              case 0x3:
1247                return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type);
1248              case 0x4:
1249                return new EorXSReg(machInst, rdzr, rn, rm, imm6, type);
1250              case 0x5:
1251                return new EonXSReg(machInst, rdzr, rn, rm, imm6, type);
1252              case 0x6:
1253                return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1254              case 0x7:
1255                return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1256              default:
1257                M5_UNREACHABLE;
1258            }
1259          }
1260          case 0x1:
1261          {
1262            uint8_t switchVal = bits(machInst, 30, 29);
1263            if (bits(machInst, 21) == 0) {
1264                ArmShiftType type =
1265                    (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1266                if (type == ROR)
1267                    return new Unknown64(machInst);
1268                uint8_t imm6 = bits(machInst, 15, 10);
1269                if (!bits(machInst, 31) && bits(imm6, 5))
1270                    return new Unknown64(machInst);
1271                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1272                IntRegIndex rdzr = makeZero(rd);
1273                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1274                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1275                switch (switchVal) {
1276                  case 0x0:
1277                    return new AddXSReg(machInst, rdzr, rn, rm, imm6, type);
1278                  case 0x1:
1279                    return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1280                  case 0x2:
1281                    return new SubXSReg(machInst, rdzr, rn, rm, imm6, type);
1282                  case 0x3:
1283                    return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1284                  default:
1285                    M5_UNREACHABLE;
1286                }
1287            } else {
1288                if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1289                   return new Unknown64(machInst);
1290                ArmExtendType type =
1291                    (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1292                uint8_t imm3 = bits(machInst, 12, 10);
1293                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1294                IntRegIndex rdsp = makeSP(rd);
1295                IntRegIndex rdzr = makeZero(rd);
1296                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1297                IntRegIndex rnsp = makeSP(rn);
1298                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1299
1300                switch (switchVal) {
1301                  case 0x0:
1302                    return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1303                  case 0x1:
1304                    return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1305                  case 0x2:
1306                    return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1307                  case 0x3:
1308                    return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1309                  default:
1310                    M5_UNREACHABLE;
1311                }
1312            }
1313          }
1314          case 0x2:
1315          {
1316            if (bits(machInst, 21) == 1)
1317                return new Unknown64(machInst);
1318            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1319            IntRegIndex rdzr = makeZero(rd);
1320            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1321            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1322            switch (bits(machInst, 23, 22)) {
1323              case 0x0:
1324              {
1325                if (bits(machInst, 15, 10))
1326                    return new Unknown64(machInst);
1327                uint8_t switchVal = bits(machInst, 30, 29);
1328                switch (switchVal) {
1329                  case 0x0:
1330                    return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1331                  case 0x1:
1332                    return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1333                  case 0x2:
1334                    return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1335                  case 0x3:
1336                    return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1337                  default:
1338                    M5_UNREACHABLE;
1339                }
1340              }
1341              case 0x1:
1342              {
1343                if ((bits(machInst, 4) == 1) ||
1344                        (bits(machInst, 10) == 1) ||
1345                        (bits(machInst, 29) == 0)) {
1346                    return new Unknown64(machInst);
1347                }
1348                ConditionCode cond =
1349                    (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1350                uint8_t flags = bits(machInst, 3, 0);
1351                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1352                if (bits(machInst, 11) == 0) {
1353                    IntRegIndex rm =
1354                        (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1355                    if (bits(machInst, 30) == 0) {
1356                        return new CcmnReg64(machInst, rn, rm, cond, flags);
1357                    } else {
1358                        return new CcmpReg64(machInst, rn, rm, cond, flags);
1359                    }
1360                } else {
1361                    uint8_t imm5 = bits(machInst, 20, 16);
1362                    if (bits(machInst, 30) == 0) {
1363                        return new CcmnImm64(machInst, rn, imm5, cond, flags);
1364                    } else {
1365                        return new CcmpImm64(machInst, rn, imm5, cond, flags);
1366                    }
1367                }
1368              }
1369              case 0x2:
1370              {
1371                if (bits(machInst, 29) == 1 ||
1372                        bits(machInst, 11) == 1) {
1373                    return new Unknown64(machInst);
1374                }
1375                uint8_t switchVal = (bits(machInst, 10) << 0) |
1376                                    (bits(machInst, 30) << 1);
1377                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1378                IntRegIndex rdzr = makeZero(rd);
1379                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1380                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1381                ConditionCode cond =
1382                    (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1383                switch (switchVal) {
1384                  case 0x0:
1385                    return new Csel64(machInst, rdzr, rn, rm, cond);
1386                  case 0x1:
1387                    return new Csinc64(machInst, rdzr, rn, rm, cond);
1388                  case 0x2:
1389                    return new Csinv64(machInst, rdzr, rn, rm, cond);
1390                  case 0x3:
1391                    return new Csneg64(machInst, rdzr, rn, rm, cond);
1392                  default:
1393                    M5_UNREACHABLE;
1394                }
1395              }
1396              case 0x3:
1397                if (bits(machInst, 30) == 0) {
1398                    if (bits(machInst, 29) != 0)
1399                        return new Unknown64(machInst);
1400                    uint8_t switchVal = bits(machInst, 15, 10);
1401                    switch (switchVal) {
1402                      case 0x2:
1403                        return new Udiv64(machInst, rdzr, rn, rm);
1404                      case 0x3:
1405                        return new Sdiv64(machInst, rdzr, rn, rm);
1406                      case 0x8:
1407                        return new Lslv64(machInst, rdzr, rn, rm);
1408                      case 0x9:
1409                        return new Lsrv64(machInst, rdzr, rn, rm);
1410                      case 0xa:
1411                        return new Asrv64(machInst, rdzr, rn, rm);
1412                      case 0xb:
1413                        return new Rorv64(machInst, rdzr, rn, rm);
1414                      case 0x10:
1415                        return new Crc32b64(machInst, rdzr, rn, rm);
1416                      case 0x11:
1417                        return new Crc32h64(machInst, rdzr, rn, rm);
1418                      case 0x12:
1419                        return new Crc32w64(machInst, rdzr, rn, rm);
1420                      case 0x13:
1421                        return new Crc32x64(machInst, rdzr, rn, rm);
1422                      case 0x14:
1423                        return new Crc32cb64(machInst, rdzr, rn, rm);
1424                      case 0x15:
1425                        return new Crc32ch64(machInst, rdzr, rn, rm);
1426                      case 0x16:
1427                        return new Crc32cw64(machInst, rdzr, rn, rm);
1428                      case 0x17:
1429                        return new Crc32cx64(machInst, rdzr, rn, rm);
1430                      default:
1431                        return new Unknown64(machInst);
1432                    }
1433                } else {
1434                    if (bits(machInst, 20, 16) != 0 ||
1435                            bits(machInst, 29) != 0) {
1436                        return new Unknown64(machInst);
1437                    }
1438                    uint8_t switchVal = bits(machInst, 15, 10);
1439                    switch (switchVal) {
1440                      case 0x0:
1441                        return new Rbit64(machInst, rdzr, rn);
1442                      case 0x1:
1443                        return new Rev1664(machInst, rdzr, rn);
1444                      case 0x2:
1445                        if (bits(machInst, 31) == 0)
1446                            return new Rev64(machInst, rdzr, rn);
1447                        else
1448                            return new Rev3264(machInst, rdzr, rn);
1449                      case 0x3:
1450                        if (bits(machInst, 31) != 1)
1451                            return new Unknown64(machInst);
1452                        return new Rev64(machInst, rdzr, rn);
1453                      case 0x4:
1454                        return new Clz64(machInst, rdzr, rn);
1455                      case 0x5:
1456                        return new Cls64(machInst, rdzr, rn);
1457                      default:
1458                        return new Unknown64(machInst);
1459                    }
1460                }
1461              default:
1462                M5_UNREACHABLE;
1463            }
1464          }
1465          case 0x3:
1466          {
1467            if (bits(machInst, 30, 29) != 0x0 ||
1468                    (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
1469                return new Unknown64(machInst);
1470            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1471            IntRegIndex rdzr = makeZero(rd);
1472            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1473            IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1474            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1475            switch (bits(machInst, 23, 21)) {
1476              case 0x0:
1477                if (bits(machInst, 15) == 0)
1478                    return new Madd64(machInst, rdzr, ra, rn, rm);
1479                else
1480                    return new Msub64(machInst, rdzr, ra, rn, rm);
1481              case 0x1:
1482                if (bits(machInst, 15) == 0)
1483                    return new Smaddl64(machInst, rdzr, ra, rn, rm);
1484                else
1485                    return new Smsubl64(machInst, rdzr, ra, rn, rm);
1486              case 0x2:
1487                if (bits(machInst, 15) != 0)
1488                    return new Unknown64(machInst);
1489                return new Smulh64(machInst, rdzr, rn, rm);
1490              case 0x5:
1491                if (bits(machInst, 15) == 0)
1492                    return new Umaddl64(machInst, rdzr, ra, rn, rm);
1493                else
1494                    return new Umsubl64(machInst, rdzr, ra, rn, rm);
1495              case 0x6:
1496                if (bits(machInst, 15) != 0)
1497                    return new Unknown64(machInst);
1498                return new Umulh64(machInst, rdzr, rn, rm);
1499              default:
1500                return new Unknown64(machInst);
1501            }
1502          }
1503          default:
1504            M5_UNREACHABLE;
1505        }
1506        return new FailUnimplemented("Unhandled Case2", machInst);
1507    }
1508}
1509}};
1510
1511output decoder {{
1512namespace Aarch64
1513{
1514    template <typename DecoderFeatures>
1515    StaticInstPtr
1516    decodeAdvSIMD(ExtMachInst machInst)
1517    {
1518        if (bits(machInst, 24) == 1) {
1519            if (bits(machInst, 10) == 0) {
1520                return decodeNeonIndexedElem<DecoderFeatures>(machInst);
1521            } else if (bits(machInst, 23) == 1) {
1522                return new Unknown64(machInst);
1523            } else {
1524                if (bits(machInst, 22, 19)) {
1525                    return decodeNeonShiftByImm(machInst);
1526                } else {
1527                    return decodeNeonModImm(machInst);
1528                }
1529            }
1530        } else if (bits(machInst, 21) == 1) {
1531            if (bits(machInst, 10) == 1) {
1532                return decodeNeon3Same<DecoderFeatures>(machInst);
1533            } else if (bits(machInst, 11) == 0) {
1534                return decodeNeon3Diff(machInst);
1535            } else if (bits(machInst, 20, 17) == 0x0) {
1536                return decodeNeon2RegMisc(machInst);
1537            } else if (bits(machInst, 20, 17) == 0x4) {
1538                return decodeCryptoAES(machInst);
1539            } else if (bits(machInst, 20, 17) == 0x8) {
1540                return decodeNeonAcrossLanes(machInst);
1541            } else {
1542                return new Unknown64(machInst);
1543            }
1544        } else if (bits(machInst, 24) ||
1545                   bits(machInst, 21) ||
1546                   bits(machInst, 15)) {
1547            return new Unknown64(machInst);
1548        } else if (bits(machInst, 10) == 1) {
1549            if (bits(machInst, 23, 22))
1550                return new Unknown64(machInst);
1551            return decodeNeonCopy(machInst);
1552        } else if (bits(machInst, 29) == 1) {
1553            return decodeNeonExt(machInst);
1554        } else if (bits(machInst, 11) == 1) {
1555            return decodeNeonZipUzpTrn(machInst);
1556        } else if (bits(machInst, 23, 22) == 0x0) {
1557            return decodeNeonTblTbx(machInst);
1558        } else {
1559            return new Unknown64(machInst);
1560        }
1561        return new FailUnimplemented("Unhandled Case3", machInst);
1562    }
1563}
1564}};
1565
1566
1567output decoder {{
1568namespace Aarch64
1569{
1570    StaticInstPtr
1571    // bit 30=0, 28:25=1111
1572    decodeFp(ExtMachInst machInst)
1573    {
1574        if (bits(machInst, 24) == 1) {
1575            if (bits(machInst, 31) || bits(machInst, 29))
1576                return new Unknown64(machInst);
1577            IntRegIndex rd    = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1578            IntRegIndex rn    = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1579            IntRegIndex rm    = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1580            IntRegIndex ra    = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
1581            uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
1582                                (bits(machInst, 15)     << 0);
1583            switch (switchVal) {
1584              case 0x0: // FMADD Sd = Sa + Sn*Sm
1585                return new FMAddS(machInst, rd, rn, rm, ra);
1586              case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
1587                return new FMSubS(machInst, rd, rn, rm, ra);
1588              case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
1589                return new FNMAddS(machInst, rd, rn, rm, ra);
1590              case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
1591                return new FNMSubS(machInst, rd, rn, rm, ra);
1592              case 0x4: // FMADD Dd = Da + Dn*Dm
1593                return new FMAddD(machInst, rd, rn, rm, ra);
1594              case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
1595                return new FMSubD(machInst, rd, rn, rm, ra);
1596              case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
1597                return new FNMAddD(machInst, rd, rn, rm, ra);
1598              case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
1599                return new FNMSubD(machInst, rd, rn, rm, ra);
1600              default:
1601                return new Unknown64(machInst);
1602            }
1603        } else if (bits(machInst, 21) == 0) {
1604            bool s = bits(machInst, 29);
1605            if (s)
1606                return new Unknown64(machInst);
1607            uint8_t switchVal = bits(machInst, 20, 16);
1608            uint8_t type      = bits(machInst, 23, 22);
1609            uint8_t scale     = bits(machInst, 15, 10);
1610            IntRegIndex rd    = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1611            IntRegIndex rn    = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1612            if (bits(machInst, 18, 17) == 3 && scale != 0)
1613                return new Unknown64(machInst);
1614            // 30:24=0011110, 21=0
1615            switch (switchVal) {
1616              case 0x00:
1617                return new FailUnimplemented("fcvtns", machInst);
1618              case 0x01:
1619                return new FailUnimplemented("fcvtnu", machInst);
1620              case 0x02:
1621                switch ( (bits(machInst, 31) << 2) | type ) {
1622                  case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
1623                    return new FcvtSFixedFpSW(machInst, rd, rn, scale);
1624                  case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
1625                    return new FcvtSFixedFpDW(machInst, rd, rn, scale);
1626                  case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
1627                    return new FcvtSFixedFpSX(machInst, rd, rn, scale);
1628                  case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
1629                    return new FcvtSFixedFpDX(machInst, rd, rn, scale);
1630                  default:
1631                    return new Unknown64(machInst);
1632                }
1633              case 0x03:
1634                switch ( (bits(machInst, 31) << 2) | type ) {
1635                  case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
1636                    return new FcvtUFixedFpSW(machInst, rd, rn, scale);
1637                  case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
1638                    return new FcvtUFixedFpDW(machInst, rd, rn, scale);
1639                  case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
1640                    return new FcvtUFixedFpSX(machInst, rd, rn, scale);
1641                  case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
1642                    return new FcvtUFixedFpDX(machInst, rd, rn, scale);
1643                  default:
1644                    return new Unknown64(machInst);
1645                }
1646              case 0x04:
1647                return new FailUnimplemented("fcvtas", machInst);
1648              case 0x05:
1649                return new FailUnimplemented("fcvtau", machInst);
1650              case 0x08:
1651                return new FailUnimplemented("fcvtps", machInst);
1652              case 0x09:
1653                return new FailUnimplemented("fcvtpu", machInst);
1654              case 0x0e:
1655                return new FailUnimplemented("fmov elem. to 64", machInst);
1656              case 0x0f:
1657                return new FailUnimplemented("fmov 64 bit", machInst);
1658              case 0x10:
1659                return new FailUnimplemented("fcvtms", machInst);
1660              case 0x11:
1661                return new FailUnimplemented("fcvtmu", machInst);
1662              case 0x18:
1663                switch ( (bits(machInst, 31) << 2) | type ) {
1664                  case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1665                    return new FcvtFpSFixedSW(machInst, rd, rn, scale);
1666                  case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1667                    return new FcvtFpSFixedDW(machInst, rd, rn, scale);
1668                  case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1669                    return new FcvtFpSFixedSX(machInst, rd, rn, scale);
1670                  case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1671                    return new FcvtFpSFixedDX(machInst, rd, rn, scale);
1672                  default:
1673                    return new Unknown64(machInst);
1674                }
1675              case 0x19:
1676                switch ( (bits(machInst, 31) << 2) | type ) {
1677                  case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1678                    return new FcvtFpUFixedSW(machInst, rd, rn, scale);
1679                  case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1680                    return new FcvtFpUFixedDW(machInst, rd, rn, scale);
1681                  case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1682                    return new FcvtFpUFixedSX(machInst, rd, rn, scale);
1683                  case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1684                    return new FcvtFpUFixedDX(machInst, rd, rn, scale);
1685                  default:
1686                    return new Unknown64(machInst);
1687                }
1688              default:
1689                return new Unknown64(machInst);
1690            }
1691        } else {
1692            // 30=0, 28:24=11110, 21=1
1693            uint8_t type   = bits(machInst, 23, 22);
1694            uint8_t imm8   = bits(machInst, 20, 13);
1695            IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1696            IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1697            switch (bits(machInst, 11, 10)) {
1698              case 0x0:
1699                if (bits(machInst, 12) == 1) {
1700                    if (bits(machInst, 31) ||
1701                            bits(machInst, 29) ||
1702                            bits(machInst, 9, 5)) {
1703                        return new Unknown64(machInst);
1704                    }
1705                    // 31:29=000, 28:24=11110, 21=1, 12:10=100
1706                    if (type == 0) {
1707                        // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
1708                        //             :imm8<5:0>:Zeros(19)
1709                        uint32_t imm = vfp_modified_imm(imm8,
1710                                                        FpDataType::Fp32);
1711                        return new FmovImmS(machInst, rd, imm);
1712                    } else if (type == 1) {
1713                        // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
1714                        //             :imm8<5:0>:Zeros(48)
1715                        uint64_t imm = vfp_modified_imm(imm8,
1716                                                        FpDataType::Fp64);
1717                        return new FmovImmD(machInst, rd, imm);
1718                    } else {
1719                        return new Unknown64(machInst);
1720                    }
1721                } else if (bits(machInst, 13) == 1) {
1722                    if (bits(machInst, 31) ||
1723                            bits(machInst, 29) ||
1724                            bits(machInst, 15, 14) ||
1725                            bits(machInst, 23) ||
1726                            bits(machInst, 2, 0)) {
1727                        return new Unknown64(machInst);
1728                    }
1729                    uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
1730                                        (bits(machInst, 22) << 2);
1731                    IntRegIndex rm = (IntRegIndex)(uint32_t)
1732                                        bits(machInst, 20, 16);
1733                    // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
1734                    switch (switchVal) {
1735                      case 0x0:
1736                        // FCMP flags = compareQuiet(Sn,Sm)
1737                        return new FCmpRegS(machInst, rn, rm);
1738                      case 0x1:
1739                        // FCMP flags = compareQuiet(Sn,0.0)
1740                        return new FCmpImmS(machInst, rn, 0);
1741                      case 0x2:
1742                        // FCMPE flags = compareSignaling(Sn,Sm)
1743                        return new FCmpERegS(machInst, rn, rm);
1744                      case 0x3:
1745                        // FCMPE flags = compareSignaling(Sn,0.0)
1746                        return new FCmpEImmS(machInst, rn, 0);
1747                      case 0x4:
1748                        // FCMP flags = compareQuiet(Dn,Dm)
1749                        return new FCmpRegD(machInst, rn, rm);
1750                      case 0x5:
1751                        // FCMP flags = compareQuiet(Dn,0.0)
1752                        return new FCmpImmD(machInst, rn, 0);
1753                      case 0x6:
1754                        // FCMPE flags = compareSignaling(Dn,Dm)
1755                        return new FCmpERegD(machInst, rn, rm);
1756                      case 0x7:
1757                        // FCMPE flags = compareSignaling(Dn,0.0)
1758                        return new FCmpEImmD(machInst, rn, 0);
1759                      default:
1760                        return new Unknown64(machInst);
1761                    }
1762                } else if (bits(machInst, 14) == 1) {
1763                    if (bits(machInst, 31) || bits(machInst, 29))
1764                        return new Unknown64(machInst);
1765                    uint8_t opcode = bits(machInst, 20, 15);
1766                    // Bits 31:24=00011110, 21=1, 14:10=10000
1767                    switch (opcode) {
1768                      case 0x0:
1769                        if (type == 0)
1770                            // FMOV Sd = Sn
1771                            return new FmovRegS(machInst, rd, rn);
1772                        else if (type == 1)
1773                            // FMOV Dd = Dn
1774                            return new FmovRegD(machInst, rd, rn);
1775                        break;
1776                      case 0x1:
1777                        if (type == 0)
1778                            // FABS Sd = abs(Sn)
1779                            return new FAbsS(machInst, rd, rn);
1780                        else if (type == 1)
1781                            // FABS Dd = abs(Dn)
1782                            return new FAbsD(machInst, rd, rn);
1783                        break;
1784                      case 0x2:
1785                        if (type == 0)
1786                            // FNEG Sd = -Sn
1787                            return new FNegS(machInst, rd, rn);
1788                        else if (type == 1)
1789                            // FNEG Dd = -Dn
1790                            return new FNegD(machInst, rd, rn);
1791                        break;
1792                      case 0x3:
1793                        if (type == 0)
1794                            // FSQRT Sd = sqrt(Sn)
1795                            return new FSqrtS(machInst, rd, rn);
1796                        else if (type == 1)
1797                            // FSQRT Dd = sqrt(Dn)
1798                            return new FSqrtD(machInst, rd, rn);
1799                        break;
1800                      case 0x4:
1801                        if (type == 1)
1802                            // FCVT Sd = convertFormat(Dn)
1803                            return new FcvtFpDFpS(machInst, rd, rn);
1804                        else if (type == 3)
1805                            // FCVT Sd = convertFormat(Hn)
1806                            return new FcvtFpHFpS(machInst, rd, rn);
1807                        break;
1808                      case 0x5:
1809                        if (type == 0)
1810                            // FCVT Dd = convertFormat(Sn)
1811                            return new FCvtFpSFpD(machInst, rd, rn);
1812                        else if (type == 3)
1813                            // FCVT Dd = convertFormat(Hn)
1814                            return new FcvtFpHFpD(machInst, rd, rn);
1815                        break;
1816                      case 0x7:
1817                        if (type == 0)
1818                            // FCVT Hd = convertFormat(Sn)
1819                            return new FcvtFpSFpH(machInst, rd, rn);
1820                        else if (type == 1)
1821                            // FCVT Hd = convertFormat(Dn)
1822                            return new FcvtFpDFpH(machInst, rd, rn);
1823                        break;
1824                      case 0x8:
1825                        if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
1826                            return new FRIntNS(machInst, rd, rn);
1827                        else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
1828                            return new FRIntND(machInst, rd, rn);
1829                        break;
1830                      case 0x9:
1831                        if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
1832                            return new FRIntPS(machInst, rd, rn);
1833                        else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
1834                            return new FRIntPD(machInst, rd, rn);
1835                        break;
1836                      case 0xa:
1837                        if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
1838                            return new FRIntMS(machInst, rd, rn);
1839                        else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
1840                            return new FRIntMD(machInst, rd, rn);
1841                        break;
1842                      case 0xb:
1843                        if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
1844                            return new FRIntZS(machInst, rd, rn);
1845                        else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
1846                            return new FRIntZD(machInst, rd, rn);
1847                        break;
1848                      case 0xc:
1849                        if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
1850                            return new FRIntAS(machInst, rd, rn);
1851                        else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
1852                            return new FRIntAD(machInst, rd, rn);
1853                        break;
1854                      case 0xe:
1855                        if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
1856                            return new FRIntXS(machInst, rd, rn);
1857                        else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
1858                            return new FRIntXD(machInst, rd, rn);
1859                        break;
1860                      case 0xf:
1861                        if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
1862                            return new FRIntIS(machInst, rd, rn);
1863                        else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
1864                            return new FRIntID(machInst, rd, rn);
1865                        break;
1866                      default:
1867                        return new Unknown64(machInst);
1868                    }
1869                    return new Unknown64(machInst);
1870                } else if (bits(machInst, 15) == 1) {
1871                    return new Unknown64(machInst);
1872                } else {
1873                    if (bits(machInst, 29))
1874                        return new Unknown64(machInst);
1875                    uint8_t rmode      = bits(machInst, 20, 19);
1876                    uint8_t switchVal1 = bits(machInst, 18, 16);
1877                    uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
1878                    // 30:24=0011110, 21=1, 15:10=000000
1879                    switch (switchVal1) {
1880                      case 0x0:
1881                        switch ((switchVal2 << 2) | rmode) {
1882                          case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
1883                            return new FcvtFpSIntWSN(machInst, rd, rn);
1884                          case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
1885                            return new FcvtFpSIntWSP(machInst, rd, rn);
1886                          case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
1887                            return new FcvtFpSIntWSM(machInst, rd, rn);
1888                          case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
1889                            return new FcvtFpSIntWSZ(machInst, rd, rn);
1890                          case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
1891                            return new FcvtFpSIntXSN(machInst, rd, rn);
1892                          case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
1893                            return new FcvtFpSIntXSP(machInst, rd, rn);
1894                          case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
1895                            return new FcvtFpSIntXSM(machInst, rd, rn);
1896                          case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
1897                            return new FcvtFpSIntXSZ(machInst, rd, rn);
1898                          case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
1899                            return new FcvtFpSIntWDN(machInst, rd, rn);
1900                          case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
1901                            return new FcvtFpSIntWDP(machInst, rd, rn);
1902                          case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
1903                            return new FcvtFpSIntWDM(machInst, rd, rn);
1904                          case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
1905                            return new FcvtFpSIntWDZ(machInst, rd, rn);
1906                          case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
1907                            return new FcvtFpSIntXDN(machInst, rd, rn);
1908                          case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
1909                            return new FcvtFpSIntXDP(machInst, rd, rn);
1910                          case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
1911                            return new FcvtFpSIntXDM(machInst, rd, rn);
1912                          case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
1913                            return new FcvtFpSIntXDZ(machInst, rd, rn);
1914                          default:
1915                            return new Unknown64(machInst);
1916                        }
1917                      case 0x1:
1918                        switch ((switchVal2 << 2) | rmode) {
1919                          case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
1920                            return new FcvtFpUIntWSN(machInst, rd, rn);
1921                          case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
1922                            return new FcvtFpUIntWSP(machInst, rd, rn);
1923                          case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
1924                            return new FcvtFpUIntWSM(machInst, rd, rn);
1925                          case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
1926                            return new FcvtFpUIntWSZ(machInst, rd, rn);
1927                          case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
1928                            return new FcvtFpUIntXSN(machInst, rd, rn);
1929                          case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
1930                            return new FcvtFpUIntXSP(machInst, rd, rn);
1931                          case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
1932                            return new FcvtFpUIntXSM(machInst, rd, rn);
1933                          case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
1934                            return new FcvtFpUIntXSZ(machInst, rd, rn);
1935                          case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
1936                            return new FcvtFpUIntWDN(machInst, rd, rn);
1937                          case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
1938                            return new FcvtFpUIntWDP(machInst, rd, rn);
1939                          case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
1940                            return new FcvtFpUIntWDM(machInst, rd, rn);
1941                          case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
1942                            return new FcvtFpUIntWDZ(machInst, rd, rn);
1943                          case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
1944                            return new FcvtFpUIntXDN(machInst, rd, rn);
1945                          case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
1946                            return new FcvtFpUIntXDP(machInst, rd, rn);
1947                          case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
1948                            return new FcvtFpUIntXDM(machInst, rd, rn);
1949                          case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
1950                            return new FcvtFpUIntXDZ(machInst, rd, rn);
1951                          default:
1952                            return new Unknown64(machInst);
1953                        }
1954                      case 0x2:
1955                        if (rmode != 0)
1956                            return new Unknown64(machInst);
1957                        switch (switchVal2) {
1958                          case 0: // SCVTF Sd = convertFromInt(Wn)
1959                            return new FcvtWSIntFpS(machInst, rd, rn);
1960                          case 1: // SCVTF Sd = convertFromInt(Xn)
1961                            return new FcvtXSIntFpS(machInst, rd, rn);
1962                          case 2: // SCVTF Dd = convertFromInt(Wn)
1963                            return new FcvtWSIntFpD(machInst, rd, rn);
1964                          case 3: // SCVTF Dd = convertFromInt(Xn)
1965                            return new FcvtXSIntFpD(machInst, rd, rn);
1966                          default:
1967                            return new Unknown64(machInst);
1968                        }
1969                      case 0x3:
1970                        switch (switchVal2) {
1971                          case 0: // UCVTF Sd = convertFromInt(Wn)
1972                            return new FcvtWUIntFpS(machInst, rd, rn);
1973                          case 1: // UCVTF Sd = convertFromInt(Xn)
1974                            return new FcvtXUIntFpS(machInst, rd, rn);
1975                          case 2: // UCVTF Dd = convertFromInt(Wn)
1976                            return new FcvtWUIntFpD(machInst, rd, rn);
1977                          case 3: // UCVTF Dd = convertFromInt(Xn)
1978                            return new FcvtXUIntFpD(machInst, rd, rn);
1979                          default:
1980                            return new Unknown64(machInst);
1981                        }
1982                      case 0x4:
1983                        if (rmode != 0)
1984                            return new Unknown64(machInst);
1985                        switch (switchVal2) {
1986                          case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
1987                            return new FcvtFpSIntWSA(machInst, rd, rn);
1988                          case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
1989                            return new FcvtFpSIntXSA(machInst, rd, rn);
1990                          case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1991                            return new FcvtFpSIntWDA(machInst, rd, rn);
1992                          case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1993                            return new FcvtFpSIntXDA(machInst, rd, rn);
1994                          default:
1995                            return new Unknown64(machInst);
1996                        }
1997                      case 0x5:
1998                        switch (switchVal2) {
1999                          case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
2000                            return new FcvtFpUIntWSA(machInst, rd, rn);
2001                          case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
2002                            return new FcvtFpUIntXSA(machInst, rd, rn);
2003                          case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
2004                            return new FcvtFpUIntWDA(machInst, rd, rn);
2005                          case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
2006                            return new FcvtFpUIntXDA(machInst, rd, rn);
2007                          default:
2008                            return new Unknown64(machInst);
2009                        }
2010                      case 0x06:
2011                        switch (switchVal2) {
2012                          case 0: // FMOV Wd = Sn
2013                            if (rmode != 0)
2014                                return new Unknown64(machInst);
2015                            return new FmovRegCoreW(machInst, rd, rn);
2016                          case 3: // FMOV Xd = Dn
2017                            if (rmode != 0)
2018                                return new Unknown64(machInst);
2019                            return new FmovRegCoreX(machInst, rd, rn);
2020                          case 5: // FMOV Xd = Vn<127:64>
2021                            if (rmode != 1)
2022                                return new Unknown64(machInst);
2023                            return new FmovURegCoreX(machInst, rd, rn);
2024                          default:
2025                            return new Unknown64(machInst);
2026                        }
2027                        break;
2028                      case 0x07:
2029                        switch (switchVal2) {
2030                          case 0: // FMOV Sd = Wn
2031                            if (rmode != 0)
2032                                return new Unknown64(machInst);
2033                            return new FmovCoreRegW(machInst, rd, rn);
2034                          case 3: // FMOV Xd = Dn
2035                            if (rmode != 0)
2036                                return new Unknown64(machInst);
2037                            return new FmovCoreRegX(machInst, rd, rn);
2038                          case 5: // FMOV Xd = Vn<127:64>
2039                            if (rmode != 1)
2040                                return new Unknown64(machInst);
2041                            return new FmovUCoreRegX(machInst, rd, rn);
2042                          default:
2043                            return new Unknown64(machInst);
2044                        }
2045                        break;
2046                      default: // Warning! missing cases in switch statement above, that still need to be added
2047                        return new Unknown64(machInst);
2048                    }
2049                }
2050                M5_UNREACHABLE;
2051              case 0x1:
2052              {
2053                if (bits(machInst, 31) ||
2054                    bits(machInst, 29) ||
2055                    bits(machInst, 23)) {
2056                    return new Unknown64(machInst);
2057                }
2058                IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
2059                IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
2060                uint8_t    imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
2061                ConditionCode cond =
2062                    (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2063                uint8_t switchVal = (bits(machInst, 4) << 0) |
2064                                    (bits(machInst, 22) << 1);
2065                // 31:23=000111100, 21=1, 11:10=01
2066                switch (switchVal) {
2067                  case 0x0:
2068                    // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
2069                    return new FCCmpRegS(machInst, rn, rm, cond, imm);
2070                  case 0x1:
2071                    // FCCMP flags = if cond then compareSignaling(Sn,Sm)
2072                    //               else #nzcv
2073                    return new FCCmpERegS(machInst, rn, rm, cond, imm);
2074                  case 0x2:
2075                    // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
2076                    return new FCCmpRegD(machInst, rn, rm, cond, imm);
2077                  case 0x3:
2078                    // FCCMP flags = if cond then compareSignaling(Dn,Dm)
2079                    //               else #nzcv
2080                    return new FCCmpERegD(machInst, rn, rm, cond, imm);
2081                  default:
2082                    return new Unknown64(machInst);
2083                }
2084              }
2085              case 0x2:
2086              {
2087                if (bits(machInst, 31) ||
2088                        bits(machInst, 29) ||
2089                        bits(machInst, 23)) {
2090                    return new Unknown64(machInst);
2091                }
2092                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst,  4,  0);
2093                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst,  9,  5);
2094                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2095                uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
2096                                    (bits(machInst, 22) << 4);
2097                switch (switchVal) {
2098                  case 0x00: // FMUL Sd = Sn * Sm
2099                    return new FMulS(machInst, rd, rn, rm);
2100                  case 0x10: // FMUL Dd = Dn * Dm
2101                    return new FMulD(machInst, rd, rn, rm);
2102                  case 0x01: // FDIV Sd = Sn / Sm
2103                    return new FDivS(machInst, rd, rn, rm);
2104                  case 0x11: // FDIV Dd = Dn / Dm
2105                    return new FDivD(machInst, rd, rn, rm);
2106                  case 0x02: // FADD Sd = Sn + Sm
2107                    return new FAddS(machInst, rd, rn, rm);
2108                  case 0x12: // FADD Dd = Dn + Dm
2109                    return new FAddD(machInst, rd, rn, rm);
2110                  case 0x03: // FSUB Sd = Sn - Sm
2111                    return new FSubS(machInst, rd, rn, rm);
2112                  case 0x13: // FSUB Dd = Dn - Dm
2113                    return new FSubD(machInst, rd, rn, rm);
2114                  case 0x04: // FMAX Sd = max(Sn, Sm)
2115                    return new FMaxS(machInst, rd, rn, rm);
2116                  case 0x14: // FMAX Dd = max(Dn, Dm)
2117                    return new FMaxD(machInst, rd, rn, rm);
2118                  case 0x05: // FMIN Sd = min(Sn, Sm)
2119                    return new FMinS(machInst, rd, rn, rm);
2120                  case 0x15: // FMIN Dd = min(Dn, Dm)
2121                    return new FMinD(machInst, rd, rn, rm);
2122                  case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
2123                    return new FMaxNMS(machInst, rd, rn, rm);
2124                  case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
2125                    return new FMaxNMD(machInst, rd, rn, rm);
2126                  case 0x07: // FMINNM Sd = minNum(Sn, Sm)
2127                    return new FMinNMS(machInst, rd, rn, rm);
2128                  case 0x17: // FMINNM Dd = minNum(Dn, Dm)
2129                    return new FMinNMD(machInst, rd, rn, rm);
2130                  case 0x08: // FNMUL Sd = -(Sn * Sm)
2131                    return new FNMulS(machInst, rd, rn, rm);
2132                  case 0x18: // FNMUL Dd = -(Dn * Dm)
2133                    return new FNMulD(machInst, rd, rn, rm);
2134                  default:
2135                    return new Unknown64(machInst);
2136                }
2137              }
2138              case 0x3:
2139              {
2140                if (bits(machInst, 31) || bits(machInst, 29))
2141                    return new Unknown64(machInst);
2142                uint8_t type = bits(machInst, 23, 22);
2143                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst,  4,  0);
2144                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst,  9,  5);
2145                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2146                ConditionCode cond =
2147                    (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2148                if (type == 0) // FCSEL Sd = if cond then Sn else Sm
2149                    return new FCSelS(machInst, rd, rn, rm, cond);
2150                else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
2151                    return new FCSelD(machInst, rd, rn, rm, cond);
2152                else
2153                    return new Unknown64(machInst);
2154              }
2155              default:
2156                M5_UNREACHABLE;
2157            }
2158        }
2159        M5_UNREACHABLE;
2160    }
2161}
2162}};
2163
2164output decoder {{
2165namespace Aarch64
2166{
2167    StaticInstPtr
2168    decodeAdvSIMDScalar(ExtMachInst machInst)
2169    {
2170        if (bits(machInst, 24) == 1) {
2171            if (bits(machInst, 10) == 0) {
2172                return decodeNeonScIndexedElem(machInst);
2173            } else if (bits(machInst, 23) == 0) {
2174                return decodeNeonScShiftByImm(machInst);
2175            }
2176        } else if (bits(machInst, 21) == 1) {
2177            if (bits(machInst, 10) == 1) {
2178                return decodeNeonSc3Same(machInst);
2179            } else if (bits(machInst, 11) == 0) {
2180                return decodeNeonSc3Diff(machInst);
2181            } else if (bits(machInst, 20, 17) == 0x0) {
2182                return decodeNeonSc2RegMisc(machInst);
2183            } else if (bits(machInst, 20, 17) == 0x4) {
2184                return decodeCryptoTwoRegSHA(machInst);
2185            } else if (bits(machInst, 20, 17) == 0x8) {
2186                return decodeNeonScPwise(machInst);
2187            } else {
2188                return new Unknown64(machInst);
2189            }
2190        } else if (bits(machInst, 23, 22) == 0 &&
2191                   bits(machInst, 15) == 0) {
2192            if (bits(machInst, 10) == 1) {
2193                return decodeNeonScCopy(machInst);
2194            } else {
2195                return decodeCryptoThreeRegSHA(machInst);
2196            }
2197        } else {
2198            return new Unknown64(machInst);
2199        }
2200        return new FailUnimplemented("Unhandled Case6", machInst);
2201    }
2202}
2203}};
2204
2205output decoder {{
2206namespace Aarch64
2207{
2208    template <typename DecoderFeatures>
2209    StaticInstPtr
2210    decodeFpAdvSIMD(ExtMachInst machInst)
2211    {
2212
2213        if (bits(machInst, 28) == 0) {
2214            if (bits(machInst, 31) == 0) {
2215                return decodeAdvSIMD<DecoderFeatures>(machInst);
2216            } else {
2217                return new Unknown64(machInst);
2218            }
2219        } else if (bits(machInst, 30) == 0) {
2220            return decodeFp(machInst);
2221        } else if (bits(machInst, 31) == 0) {
2222            return decodeAdvSIMDScalar(machInst);
2223        } else {
2224            return new Unknown64(machInst);
2225        }
2226    }
2227}
2228}};
2229
2230let {{
2231    decoder_output ='''
2232namespace Aarch64
2233{'''
2234    for decoderFlavour, type_dict in decoders.iteritems():
2235        decoder_output +='''
2236template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst);
2237''' % { "df" : decoderFlavour }
2238    decoder_output +='''
2239}'''
2240}};
2241
2242output decoder {{
2243namespace Aarch64
2244{
2245    StaticInstPtr
2246    decodeGem5Ops(ExtMachInst machInst)
2247    {
2248        const uint32_t m5func = bits(machInst, 23, 16);
2249        switch (m5func) {
2250          case M5OP_ARM: return new Arm(machInst);
2251          case M5OP_QUIESCE: return new Quiesce(machInst);
2252          case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst);
2253          case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst);
2254          case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst);
2255          case M5OP_RPNS: return new Rpns64(machInst);
2256          case M5OP_WAKE_CPU: return new WakeCPU64(machInst);
2257          case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst);
2258          case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst);
2259          case M5OP_DEPRECATED3: return new Deprecated_exit (machInst);
2260          case M5OP_EXIT: return new M5exit64(machInst);
2261          case M5OP_FAIL: return new M5fail64(machInst);
2262          case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst);
2263          case M5OP_INIT_PARAM: return new Initparam64(machInst);
2264          case M5OP_RESET_STATS: return new Resetstats64(machInst);
2265          case M5OP_DUMP_STATS: return new Dumpstats64(machInst);
2266          case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst);
2267          case M5OP_CHECKPOINT: return new M5checkpoint64(machInst);
2268          case M5OP_WRITE_FILE: return new M5writefile64(machInst);
2269          case M5OP_READ_FILE: return new M5readfile64(machInst);
2270          case M5OP_DEBUG_BREAK: return new M5break(machInst);
2271          case M5OP_SWITCH_CPU: return new M5switchcpu(machInst);
2272          case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst);
2273          case M5OP_PANIC: return new M5panic(machInst);
2274          case M5OP_WORK_BEGIN: return new M5workbegin64(machInst);
2275          case M5OP_WORK_END: return new M5workend64(machInst);
2276          default: return new Unknown64(machInst);
2277        }
2278    }
2279}
2280}};
2281
2282def format Aarch64() {{
2283    decode_block = '''
2284    {
2285        using namespace Aarch64;
2286        if (bits(machInst, 27) == 0x0) {
2287            if (bits(machInst, 28) == 0x0) {
2288                if (bits(machInst, 26, 25) != 0x2) {
2289                    return new Unknown64(machInst);
2290                }
2291                if (bits(machInst, 31) == 0x0) {
2292                    switch (bits(machInst, 30, 29)) {
2293                      case 0x0:
2294                      case 0x1:
2295                      case 0x2:
2296                        return decodeSveInt(machInst);
2297                      case 0x3:
2298                        return decodeSveFp(machInst);
2299                    }
2300                } else {
2301                    return decodeSveMem(machInst);
2302                }
2303            } else if (bits(machInst, 26) == 0)
2304                // bit 28:26=100
2305                return decodeDataProcImm(machInst);
2306            else
2307                // bit 28:26=101
2308                return decodeBranchExcSys(machInst);
2309        } else if (bits(machInst, 25) == 0) {
2310            // bit 27=1, 25=0
2311            return decodeLoadsStores(machInst);
2312        } else if (bits(machInst, 26) == 0) {
2313            // bit 27:25=101
2314            return decodeDataProcReg(machInst);
2315        } else if (bits(machInst, 24) == 1 &&
2316                   bits(machInst, 31, 28) == 0xF) {
2317            return decodeGem5Ops(machInst);
2318        } else {
2319            // bit 27:25=111
2320            switch(decoderFlavour){
2321            default:
2322                return decodeFpAdvSIMD<GenericDecoder>(machInst);
2323            }
2324        }
2325    }
2326    '''
2327}};
2328