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