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