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