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