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