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