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    decodeAtomicArithOp(ExtMachInst machInst)
545    {
546        uint8_t opc  = bits(machInst, 14, 12);
547        uint8_t o3  = bits(machInst, 15);
548        uint8_t size_ar = bits(machInst, 23, 22)<<0 | bits(machInst, 31, 30)<<2;
549        IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
550        IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
551        IntRegIndex rnsp = makeSP(rn);
552        IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
553        uint8_t  A_rt = bits(machInst, 4, 0)<<0 | bits(machInst, 23)<<5;
554
555        switch(opc) {
556            case 0x0:
557                switch(size_ar){
558                    case 0x0:
559                        if (o3 == 1)
560                            return new SWPB(machInst, rt, rnsp, rs);
561                        else if (A_rt == 0x1f)
562                            return new STADDB(machInst, rt, rnsp, rs);
563                        else
564                            return new LDADDB(machInst, rt, rnsp, rs);
565                    case 0x1 :
566                        if (o3 == 1)
567                            return new SWPLB(machInst, rt, rnsp, rs);
568                        else if (A_rt == 0x1f)
569                            return new STADDLB(machInst, rt, rnsp, rs);
570                        else
571                            return new LDADDLB(machInst, rt, rnsp, rs);
572                    case 0x2:
573                        if (o3 == 1)
574                            return new SWPAB(machInst, rt, rnsp, rs);
575                        else
576                            return new LDADDAB(machInst, rt, rnsp, rs);
577                    case 0x3:
578                        if (o3 == 1)
579                            return new SWPLAB(machInst, rt, rnsp, rs);
580                        else
581                            return new LDADDLAB(machInst, rt, rnsp, rs);
582                    case 0x4:
583                        if (o3 == 1)
584                            return new SWPH(machInst, rt, rnsp, rs);
585                        else if (A_rt == 0x1f)
586                            return new STADDH(machInst, rt, rnsp, rs);
587                        else
588                            return new LDADDH(machInst, rt, rnsp, rs);
589                    case 0x5 :
590                        if (o3 == 1)
591                            return new SWPLH(machInst, rt, rnsp, rs);
592                        else if (A_rt == 0x1f)
593                            return new STADDLH(machInst, rt, rnsp, rs);
594                        else
595                            return new LDADDLH(machInst, rt, rnsp, rs);
596                    case 0x6:
597                        if (o3 == 1)
598                            return new SWPAH(machInst, rt, rnsp, rs);
599                        else
600                            return new LDADDAH(machInst, rt, rnsp, rs);
601                    case 0x7:
602                        if (o3 == 1)
603                            return new SWPLAH(machInst, rt, rnsp, rs);
604                        else
605                            return new LDADDLAH(machInst, rt, rnsp, rs);
606                    case 0x8:
607                        if (o3 == 1)
608                            return new SWP(machInst, rt, rnsp, rs);
609                        else if (A_rt == 0x1f)
610                            return new STADD(machInst, rt, rnsp, rs);
611                        else
612                            return new LDADD(machInst, rt, rnsp, rs);
613                    case 0x9 :
614                        if (o3 == 1)
615                            return new SWPL(machInst, rt, rnsp, rs);
616                        else if (A_rt == 0x1f)
617                            return new STADDL(machInst, rt, rnsp, rs);
618                        else
619                            return new LDADDL(machInst, rt, rnsp, rs);
620                    case 0xa:
621                        if (o3 == 1)
622                            return new SWPA(machInst, rt, rnsp, rs);
623                        else
624                            return new LDADDA(machInst, rt, rnsp, rs);
625                    case 0xb:
626                        if (o3 == 1)
627                            return new SWPLA(machInst, rt, rnsp, rs);
628                        else
629                            return new LDADDLA(machInst, rt, rnsp, rs);
630                    case 0xc:
631                        if (o3 == 1)
632                            return new SWP64(machInst, rt, rnsp, rs);
633
634                        else if (A_rt == 0x1f)
635                            return new STADD64(machInst, rt, rnsp, rs);
636                        else
637                            return new LDADD64(machInst, rt, rnsp, rs);
638                    case 0xd :
639                        if (o3 == 1)
640                            return new SWPL64(machInst, rt, rnsp, rs);
641                        else if (A_rt == 0x1f)
642                            return new STADDL64(machInst, rt, rnsp, rs);
643                        else
644                            return new LDADDL64(machInst, rt, rnsp, rs);
645                    case 0xe:
646                        if (o3 == 1)
647                            return new SWPA64(machInst, rt, rnsp, rs);
648                        else
649                            return new LDADDA64(machInst, rt, rnsp, rs);
650                    case 0xf:
651                        if (o3 == 1)
652                            return new SWPLA64(machInst, rt, rnsp, rs);
653                        else
654                            return new LDADDLA64(machInst, rt, rnsp, rs);
655                    default:
656                        M5_UNREACHABLE;
657                }
658            case 0x1:
659                switch(size_ar){
660                    case 0x0:
661                        if (A_rt == 0x1f)
662                            return new STCLRB(machInst, rt, rnsp, rs);
663                        else
664                            return new LDCLRB(machInst, rt, rnsp, rs);
665                    case 0x1 :
666                        if (A_rt == 0x1f)
667                            return new STCLRLB(machInst, rt, rnsp, rs);
668                        else
669                            return new LDCLRLB(machInst, rt, rnsp, rs);
670                    case 0x2:
671                        return new LDCLRAB(machInst, rt, rnsp, rs);
672                    case 0x3:
673                        return new LDCLRLAB(machInst, rt, rnsp, rs);
674                    case 0x4:
675                        if (A_rt == 0x1f)
676                            return new STCLRH(machInst, rt, rnsp, rs);
677                        else
678                            return new LDCLRH(machInst, rt, rnsp, rs);
679                    case 0x5 :
680                        if (A_rt == 0x1f)
681                            return new STCLRLH(machInst, rt, rnsp, rs);
682                        else
683                            return new LDCLRLH(machInst, rt, rnsp, rs);
684                    case 0x6:
685                        return new LDCLRAH(machInst, rt, rnsp, rs);
686                    case 0x7:
687                        return new LDCLRLAH(machInst, rt, rnsp, rs);
688                    case 0x8:
689                        if (A_rt == 0x1f)
690                            return new STCLR(machInst, rt, rnsp, rs);
691                        else
692                            return new LDCLR(machInst, rt, rnsp, rs);
693                    case 0x9 :
694                        if (A_rt == 0x1f)
695                            return new STCLRL(machInst, rt, rnsp, rs);
696                        else
697                            return new LDCLRL(machInst, rt, rnsp, rs);
698                    case 0xa:
699                        return new LDCLRA(machInst, rt, rnsp, rs);
700                    case 0xb:
701                        return new LDCLRLA(machInst, rt, rnsp, rs);
702                    case 0xc:
703                        if (A_rt == 0x1f)
704                            return new STCLR64(machInst, rt, rnsp, rs);
705                        else
706                            return new LDCLR64(machInst, rt, rnsp, rs);
707                    case 0xd :
708                        if (A_rt == 0x1f)
709                            return new STCLRL64(machInst, rt, rnsp, rs);
710                        else
711                            return new LDCLRL64(machInst, rt, rnsp, rs);
712                    case 0xe:
713                        return new LDCLRA64(machInst, rt, rnsp, rs);
714                    case 0xf:
715                        return new LDCLRLA64(machInst, rt, rnsp, rs);
716                    default:
717                        M5_UNREACHABLE;
718                }
719            case 0x2:
720                switch(size_ar){
721                    case 0x0:
722                        if (A_rt == 0x1f)
723                            return new STEORB(machInst, rt, rnsp, rs);
724                        else
725                            return new LDEORB(machInst, rt, rnsp, rs);
726                    case 0x1 :
727                        if (A_rt == 0x1f)
728                            return new STEORLB(machInst, rt, rnsp, rs);
729                        else
730                            return new LDEORLB(machInst, rt, rnsp, rs);
731                    case 0x2:
732                        return new LDEORAB(machInst, rt, rnsp, rs);
733                    case 0x3:
734                        return new LDEORLAB(machInst, rt, rnsp, rs);
735                    case 0x4:
736                        if (A_rt == 0x1f)
737                            return new STEORH(machInst, rt, rnsp, rs);
738                        else
739                            return new LDEORH(machInst, rt, rnsp, rs);
740                    case 0x5 :
741                        if (A_rt == 0x1f)
742                            return new STEORLH(machInst, rt, rnsp, rs);
743                        else
744                            return new LDEORLH(machInst, rt, rnsp, rs);
745                    case 0x6:
746                        return new LDEORAH(machInst, rt, rnsp, rs);
747                    case 0x7:
748                        return new LDEORLAH(machInst, rt, rnsp, rs);
749                    case 0x8:
750                        if (A_rt == 0x1f)
751                            return new STEOR(machInst, rt, rnsp, rs);
752                        else
753                            return new LDEOR(machInst, rt, rnsp, rs);
754                    case 0x9 :
755                        if (A_rt == 0x1f)
756                            return new STEORL(machInst, rt, rnsp, rs);
757                        else
758                            return new LDEORL(machInst, rt, rnsp, rs);
759                    case 0xa:
760                        return new LDEORA(machInst, rt, rnsp, rs);
761                    case 0xb:
762                        return new LDEORLA(machInst, rt, rnsp, rs);
763                    case 0xc:
764                        if (A_rt == 0x1f)
765                            return new STEOR64(machInst, rt, rnsp, rs);
766                        else
767                            return new LDEOR64(machInst, rt, rnsp, rs);
768                    case 0xd :
769                        if (A_rt == 0x1f)
770                            return new STEORL64(machInst, rt, rnsp, rs);
771                        else
772                            return new LDEORL64(machInst, rt, rnsp, rs);
773                    case 0xe:
774                        return new LDEORA64(machInst, rt, rnsp, rs);
775                    case 0xf:
776                        return new LDEORLA64(machInst, rt, rnsp, rs);
777                    default:
778                        M5_UNREACHABLE;
779                }
780            case 0x3:
781                switch(size_ar){
782                    case 0x0:
783                        if (A_rt == 0x1f)
784                            return new STSETB(machInst, rt, rnsp, rs);
785                        else
786                            return new LDSETB(machInst, rt, rnsp, rs);
787                    case 0x1 :
788                        if (A_rt == 0x1f)
789                            return new STSETLB(machInst, rt, rnsp, rs);
790                        else
791                            return new LDSETLB(machInst, rt, rnsp, rs);
792                    case 0x2:
793                        return new LDSETAB(machInst, rt, rnsp, rs);
794                    case 0x3:
795                        return new LDSETLAB(machInst, rt, rnsp, rs);
796                    case 0x4:
797                        if (A_rt == 0x1f)
798                            return new STSETH(machInst, rt, rnsp, rs);
799                        else
800                            return new LDSETH(machInst, rt, rnsp, rs);
801                    case 0x5 :
802                        if (A_rt == 0x1f)
803                            return new STSETLH(machInst, rt, rnsp, rs);
804                        else
805                            return new LDSETLH(machInst, rt, rnsp, rs);
806                    case 0x6:
807                        return new LDSETAH(machInst, rt, rnsp, rs);
808                    case 0x7:
809                        return new LDSETLAH(machInst, rt, rnsp, rs);
810                    case 0x8:
811                        if (A_rt == 0x1f)
812                            return new STSET(machInst, rt, rnsp, rs);
813                        else
814                            return new LDSET(machInst, rt, rnsp, rs);
815                    case 0x9 :
816                        if (A_rt == 0x1f)
817                            return new STSETL(machInst, rt, rnsp, rs);
818                        else
819                            return new LDSETL(machInst, rt, rnsp, rs);
820                    case 0xa:
821                        return new LDSETA(machInst, rt, rnsp, rs);
822                    case 0xb:
823                        return new LDSETLA(machInst, rt, rnsp, rs);
824                    case 0xc:
825                        if (A_rt == 0x1f)
826                            return new STSET64(machInst, rt, rnsp, rs);
827                        else
828                            return new LDSET64(machInst, rt, rnsp, rs);
829                    case 0xd :
830                        if (A_rt == 0x1f)
831                            return new STSETL64(machInst, rt, rnsp, rs);
832                        else
833                            return new LDSETL64(machInst, rt, rnsp, rs);
834                    case 0xe:
835                        return new LDSETA64(machInst, rt, rnsp, rs);
836                    case 0xf:
837                        return new LDSETLA64(machInst, rt, rnsp, rs);
838                    default:
839                        M5_UNREACHABLE;
840                }
841            case 0x4:
842                switch(size_ar){
843                    case 0x0:
844                        if (A_rt == 0x1f)
845                            return new STSMAXB(machInst, rt, rnsp, rs);
846                        else
847                            return new LDSMAXB(machInst, rt, rnsp, rs);
848                    case 0x1 :
849                        if (A_rt == 0x1f)
850                            return new STSMAXLB(machInst, rt, rnsp, rs);
851                        else
852                            return new LDSMAXLB(machInst, rt, rnsp, rs);
853                    case 0x2:
854                        return new LDSMAXAB(machInst, rt, rnsp, rs);
855                    case 0x3:
856                        return new LDSMAXLAB(machInst, rt, rnsp, rs);
857                    case 0x4:
858                        if (A_rt == 0x1f)
859                            return new STSMAXH(machInst, rt, rnsp, rs);
860                        else
861                            return new LDSMAXH(machInst, rt, rnsp, rs);
862                    case 0x5 :
863                        if (A_rt == 0x1f)
864                            return new STSMAXLH(machInst, rt, rnsp, rs);
865                        else
866                            return new LDSMAXLH(machInst, rt, rnsp, rs);
867                    case 0x6:
868                        return new LDSMAXAH(machInst, rt, rnsp, rs);
869                    case 0x7:
870                        return new LDSMAXLAH(machInst, rt, rnsp, rs);
871                    case 0x8:
872                        if (A_rt == 0x1f)
873                            return new STSMAX(machInst, rt, rnsp, rs);
874                        else
875                            return new LDSMAX(machInst, rt, rnsp, rs);
876                    case 0x9 :
877                        if (A_rt == 0x1f)
878                            return new STSMAXL(machInst, rt, rnsp, rs);
879                        else
880                            return new LDSMAXL(machInst, rt, rnsp, rs);
881                    case 0xa:
882                        return new LDSMAXA(machInst, rt, rnsp, rs);
883                    case 0xb:
884                        return new LDSMAXLA(machInst, rt, rnsp, rs);
885                    case 0xc:
886                        if (A_rt == 0x1f)
887                            return new STSMAX64(machInst, rt, rnsp, rs);
888                        else
889                            return new LDSMAX64(machInst, rt, rnsp, rs);
890                    case 0xd :
891                        if (A_rt == 0x1f)
892                            return new STSMAXL64(machInst, rt, rnsp, rs);
893                        else
894                            return new LDSMAXL64(machInst, rt, rnsp, rs);
895                    case 0xe:
896                        return new LDSMAXA64(machInst, rt, rnsp, rs);
897                    case 0xf:
898                        return new LDSMAXLA64(machInst, rt, rnsp, rs);
899                    default:
900                        M5_UNREACHABLE;
901                }
902            case 0x5:
903                switch(size_ar){
904                    case 0x0:
905                        if (A_rt == 0x1f)
906                            return new STSMINB(machInst, rt, rnsp, rs);
907                        else
908                            return new LDSMINB(machInst, rt, rnsp, rs);
909                    case 0x1 :
910                        if (A_rt == 0x1f)
911                            return new STSMINLB(machInst, rt, rnsp, rs);
912                        else
913                            return new LDSMINLB(machInst, rt, rnsp, rs);
914                    case 0x2:
915                        return new LDSMINAB(machInst, rt, rnsp, rs);
916                    case 0x3:
917                        return new LDSMINLAB(machInst, rt, rnsp, rs);
918                    case 0x4:
919                        if (A_rt == 0x1f)
920                            return new STSMINH(machInst, rt, rnsp, rs);
921                        else
922                            return new LDSMINH(machInst, rt, rnsp, rs);
923                    case 0x5 :
924                        if (A_rt == 0x1f)
925                            return new STSMINLH(machInst, rt, rnsp, rs);
926                        else
927                            return new LDSMINLH(machInst, rt, rnsp, rs);
928                    case 0x6:
929                        return new LDSMINAH(machInst, rt, rnsp, rs);
930                    case 0x7:
931                        return new LDSMINLAH(machInst, rt, rnsp, rs);
932                    case 0x8:
933                        if (A_rt == 0x1f)
934                            return new STSMIN(machInst, rt, rnsp, rs);
935                        else
936                            return new LDSMIN(machInst, rt, rnsp, rs);
937                    case 0x9 :
938                        if (A_rt == 0x1f)
939                            return new STSMINL(machInst, rt, rnsp, rs);
940                        else
941                            return new LDSMINL(machInst, rt, rnsp, rs);
942                    case 0xa:
943                        return new LDSMINA(machInst, rt, rnsp, rs);
944                    case 0xb:
945                        return new LDSMINLA(machInst, rt, rnsp, rs);
946                    case 0xc:
947                        if (A_rt == 0x1f)
948                            return new STSMIN64(machInst, rt, rnsp, rs);
949                        else
950                            return new LDSMIN64(machInst, rt, rnsp, rs);
951                    case 0xd :
952                        if (A_rt == 0x1f)
953                            return new STSMINL64(machInst, rt, rnsp, rs);
954                        else
955                            return new LDSMINL64(machInst, rt, rnsp, rs);
956                    case 0xe:
957                        return new LDSMINA64(machInst, rt, rnsp, rs);
958                    case 0xf:
959                        return new LDSMINLA64(machInst, rt, rnsp, rs);
960                    default:
961                        M5_UNREACHABLE;
962                }
963            case 0x6:
964                switch(size_ar){
965                    case 0x0:
966                        if (A_rt == 0x1f)
967                            return new STUMAXB(machInst, rt, rnsp, rs);
968                        else
969                            return new LDUMAXB(machInst, rt, rnsp, rs);
970                    case 0x1 :
971                        if (A_rt == 0x1f)
972                            return new STUMAXLB(machInst, rt, rnsp, rs);
973                        else
974                            return new LDUMAXLB(machInst, rt, rnsp, rs);
975                    case 0x2:
976                        return new LDUMAXAB(machInst, rt, rnsp, rs);
977                    case 0x3:
978                        return new LDUMAXLAB(machInst, rt, rnsp, rs);
979                    case 0x4:
980                        if (A_rt == 0x1f)
981                            return new STUMAXH(machInst, rt, rnsp, rs);
982                        else
983                            return new LDUMAXH(machInst, rt, rnsp, rs);
984                    case 0x5 :
985                        if (A_rt == 0x1f)
986                            return new STUMAXLH(machInst, rt, rnsp, rs);
987                        else
988                            return new LDUMAXLH(machInst, rt, rnsp, rs);
989                    case 0x6:
990                        return new LDUMAXAH(machInst, rt, rnsp, rs);
991                    case 0x7:
992                        return new LDUMAXLAH(machInst, rt, rnsp, rs);
993                    case 0x8:
994                        if (A_rt == 0x1f)
995                            return new STUMAX(machInst, rt, rnsp, rs);
996                        else
997                            return new LDUMAX(machInst, rt, rnsp, rs);
998                    case 0x9 :
999                        if (A_rt == 0x1f)
1000                            return new STUMAXL(machInst, rt, rnsp, rs);
1001                        else
1002                            return new LDUMAXL(machInst, rt, rnsp, rs);
1003                    case 0xa:
1004                        return new LDUMAXA(machInst, rt, rnsp, rs);
1005                    case 0xb:
1006                        return new LDUMAXLA(machInst, rt, rnsp, rs);
1007                    case 0xc:
1008                        if (A_rt == 0x1f)
1009                            return new STUMAX64(machInst, rt, rnsp, rs);
1010                        else
1011                            return new LDUMAX64(machInst, rt, rnsp, rs);
1012                    case 0xd :
1013                        if (A_rt == 0x1f)
1014                            return new STUMAXL64(machInst, rt, rnsp, rs);
1015                        else
1016                            return new LDUMAXL64(machInst, rt, rnsp, rs);
1017                    case 0xe:
1018                        return new LDUMAXA64(machInst, rt, rnsp, rs);
1019                    case 0xf:
1020                        return new LDUMAXLA64(machInst, rt, rnsp, rs);
1021                    default:
1022                        M5_UNREACHABLE;
1023                }
1024            case 0x7:
1025                switch(size_ar){
1026                    case 0x0:
1027                        if (A_rt == 0x1f)
1028                            return new STUMINB(machInst, rt, rnsp, rs);
1029                        else
1030                            return new LDUMINB(machInst, rt, rnsp, rs);
1031                    case 0x1 :
1032                        if (A_rt == 0x1f)
1033                            return new STUMINLB(machInst, rt, rnsp, rs);
1034                        else
1035                            return new LDUMINLB(machInst, rt, rnsp, rs);
1036                    case 0x2:
1037                        return new LDUMINAB(machInst, rt, rnsp, rs);
1038                    case 0x3:
1039                        return new LDUMINLAB(machInst, rt, rnsp, rs);
1040                    case 0x4:
1041                        if (A_rt == 0x1f)
1042                            return new STUMINH(machInst, rt, rnsp, rs);
1043                        else
1044                            return new LDUMINH(machInst, rt, rnsp, rs);
1045                    case 0x5 :
1046                        if (A_rt == 0x1f)
1047                            return new STUMINLH(machInst, rt, rnsp, rs);
1048                        else
1049                            return new LDUMINLH(machInst, rt, rnsp, rs);
1050                    case 0x6:
1051                        return new LDUMINAH(machInst, rt, rnsp, rs);
1052                    case 0x7:
1053                        return new LDUMINLAH(machInst, rt, rnsp, rs);
1054                    case 0x8:
1055                        if (A_rt == 0x1f)
1056                            return new STUMIN(machInst, rt, rnsp, rs);
1057                        else
1058                            return new LDUMIN(machInst, rt, rnsp, rs);
1059                    case 0x9 :
1060                        if (A_rt == 0x1f)
1061                            return new STUMINL(machInst, rt, rnsp, rs);
1062                        else
1063                            return new LDUMINL(machInst, rt, rnsp, rs);
1064                    case 0xa:
1065                        return new LDUMINA(machInst, rt, rnsp, rs);
1066                    case 0xb:
1067                        return new LDUMINLA(machInst, rt, rnsp, rs);
1068                    case 0xc:
1069                        if (A_rt == 0x1f)
1070                            return new STUMIN64(machInst, rt, rnsp, rs);
1071                        else
1072                            return new LDUMIN64(machInst, rt, rnsp, rs);
1073                    case 0xd :
1074                        if (A_rt == 0x1f)
1075                            return new STUMINL64(machInst, rt, rnsp, rs);
1076                        else
1077                            return new LDUMINL64(machInst, rt, rnsp, rs);
1078                    case 0xe:
1079                        return new LDUMINA64(machInst, rt, rnsp, rs);
1080                    case 0xf:
1081                        return new LDUMINLA64(machInst, rt, rnsp, rs);
1082                    default:
1083                        M5_UNREACHABLE;
1084                }
1085            default:
1086                return new Unknown64(machInst);
1087        }
1088    }
1089}
1090}};
1091
1092
1093output decoder {{
1094namespace Aarch64
1095{
1096
1097    StaticInstPtr
1098    decodeLoadsStores(ExtMachInst machInst)
1099    {
1100        // bit 27,25=10
1101        switch (bits(machInst, 29, 28)) {
1102          case 0x0:
1103            if (bits(machInst, 26) == 0) {
1104                if (bits(machInst, 24) != 0)
1105                    return new Unknown64(machInst);
1106                IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1107                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1108                IntRegIndex rnsp = makeSP(rn);
1109                IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1110                IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1111                uint8_t opc = (bits(machInst, 15) << 0) |
1112                              (bits(machInst, 23, 21) << 1);
1113                uint8_t size = bits(machInst, 31, 30);
1114                switch (opc) {
1115                  case 0x0:
1116                    switch (size) {
1117                      case 0x0:
1118                        return new STXRB64(machInst, rt, rnsp, rs);
1119                      case 0x1:
1120                        return new STXRH64(machInst, rt, rnsp, rs);
1121                      case 0x2:
1122                        return new STXRW64(machInst, rt, rnsp, rs);
1123                      case 0x3:
1124                        return new STXRX64(machInst, rt, rnsp, rs);
1125                      default:
1126                        M5_UNREACHABLE;
1127                    }
1128                  case 0x1:
1129                    switch (size) {
1130                      case 0x0:
1131                        return new STLXRB64(machInst, rt, rnsp, rs);
1132                      case 0x1:
1133                        return new STLXRH64(machInst, rt, rnsp, rs);
1134                      case 0x2:
1135                        return new STLXRW64(machInst, rt, rnsp, rs);
1136                      case 0x3:
1137                        return new STLXRX64(machInst, rt, rnsp, rs);
1138                      default:
1139                        M5_UNREACHABLE;
1140                    }
1141                  case 0x2:
1142                    switch (size) {
1143                      case 0x0:
1144                        return new CASP32(machInst, rt, rnsp, rs);
1145                      case 0x1:
1146                        return new CASP64(machInst, rt, rnsp, rs);
1147                      case 0x2:
1148                        return new STXPW64(machInst, rs, rt, rt2, rnsp);
1149                      case 0x3:
1150                        return new STXPX64(machInst, rs, rt, rt2, rnsp);
1151                      default:
1152                        M5_UNREACHABLE;
1153                    }
1154
1155                  case 0x3:
1156                    switch (size) {
1157                      case 0x0:
1158                        return new CASPL32(machInst, rt, rnsp, rs);
1159                      case 0x1:
1160                        return new CASPL64(machInst, rt, rnsp, rs);
1161                      case 0x2:
1162                        return new STLXPW64(machInst, rs, rt, rt2, rnsp);
1163                      case 0x3:
1164                        return new STLXPX64(machInst, rs, rt, rt2, rnsp);
1165                      default:
1166                        M5_UNREACHABLE;
1167                    }
1168
1169                  case 0x4:
1170                    switch (size) {
1171                      case 0x0:
1172                        return new LDXRB64(machInst, rt, rnsp, rs);
1173                      case 0x1:
1174                        return new LDXRH64(machInst, rt, rnsp, rs);
1175                      case 0x2:
1176                        return new LDXRW64(machInst, rt, rnsp, rs);
1177                      case 0x3:
1178                        return new LDXRX64(machInst, rt, rnsp, rs);
1179                      default:
1180                        M5_UNREACHABLE;
1181                    }
1182                  case 0x5:
1183                    switch (size) {
1184                      case 0x0:
1185                        return new LDAXRB64(machInst, rt, rnsp, rs);
1186                      case 0x1:
1187                        return new LDAXRH64(machInst, rt, rnsp, rs);
1188                      case 0x2:
1189                        return new LDAXRW64(machInst, rt, rnsp, rs);
1190                      case 0x3:
1191                        return new LDAXRX64(machInst, rt, rnsp, rs);
1192                      default:
1193                        M5_UNREACHABLE;
1194                    }
1195                  case 0x6:
1196                    switch (size) {
1197                      case 0x0:
1198                        return new CASPA32(machInst, rt, rnsp, rs);
1199                      case 0x1:
1200                        return new CASPA64(machInst, rt, rnsp, rs);
1201                      case 0x2:
1202                        return new LDXPW64(machInst, rt, rt2, rnsp);
1203                      case 0x3:
1204                        return new LDXPX64(machInst, rt, rt2, rnsp);
1205                      default:
1206                        M5_UNREACHABLE;
1207                    }
1208                  case 0x7:
1209                    switch (size) {
1210                      case 0x0:
1211                        return new CASPAL32(machInst, rt, rnsp, rs);
1212                      case 0x1:
1213                        return new CASPAL64(machInst, rt, rnsp, rs);
1214                      case 0x2:
1215                        return new LDAXPW64(machInst, rt, rt2, rnsp);
1216                      case 0x3:
1217                        return new LDAXPX64(machInst, rt, rt2, rnsp);
1218                      default:
1219                        M5_UNREACHABLE;
1220                    }
1221                  case 0x9:
1222                    switch (size) {
1223                      case 0x0:
1224                        return new STLRB64(machInst, rt, rnsp);
1225                      case 0x1:
1226                        return new STLRH64(machInst, rt, rnsp);
1227                      case 0x2:
1228                        return new STLRW64(machInst, rt, rnsp);
1229                      case 0x3:
1230                        return new STLRX64(machInst, rt, rnsp);
1231                      default:
1232                        M5_UNREACHABLE;
1233                    }
1234                  case 0xa:
1235                    switch (size) {
1236                      case 0x0:
1237                        return new CASB(machInst, rt, rnsp, rs);
1238                      case 0x1:
1239                        return new CASH(machInst, rt, rnsp, rs);
1240                      case 0x2:
1241                        return new CAS32(machInst, rt, rnsp, rs);
1242                      case 0x3:
1243                        return new CAS64(machInst, rt, rnsp, rs);
1244                      default:
1245                        M5_UNREACHABLE;
1246                    }
1247                  case 0xb:
1248                    switch (size) {
1249                      case 0x0:
1250                        return new CASLB(machInst, rt, rnsp, rs);
1251                      case 0x1:
1252                        return new CASLH(machInst, rt, rnsp, rs);
1253                      case 0x2:
1254                        return new CASL32(machInst, rt, rnsp, rs);
1255                      case 0x3:
1256                        return new CASL64(machInst, rt, rnsp, rs);
1257                      default:
1258                        M5_UNREACHABLE;
1259                    }
1260                  case 0xd:
1261                    switch (size) {
1262                      case 0x0:
1263                        return new LDARB64(machInst, rt, rnsp);
1264                      case 0x1:
1265                        return new LDARH64(machInst, rt, rnsp);
1266                      case 0x2:
1267                        return new LDARW64(machInst, rt, rnsp);
1268                      case 0x3:
1269                        return new LDARX64(machInst, rt, rnsp);
1270                      default:
1271                        M5_UNREACHABLE;
1272                    }
1273                  case 0xe:
1274                    switch (size) {
1275                      case 0x0:
1276                        return new CASAB(machInst, rt, rnsp, rs);
1277                      case 0x1:
1278                        return new CASAH(machInst, rt, rnsp, rs);
1279                      case 0x2:
1280                        return new CASA32(machInst, rt, rnsp, rs);
1281                      case 0x3:
1282                        return new CASA64(machInst, rt, rnsp, rs);
1283                      default:
1284                        M5_UNREACHABLE;
1285                    }
1286                  case 0xf:
1287                    switch (size) {
1288                      case 0x0:
1289                        return new CASALB(machInst, rt, rnsp, rs);
1290                      case 0x1:
1291                        return new CASALH(machInst, rt, rnsp, rs);
1292                      case 0x2:
1293                        return new CASAL32(machInst, rt, rnsp, rs);
1294                      case 0x3:
1295                        return new CASAL64(machInst, rt, rnsp, rs);
1296                      default:
1297                        M5_UNREACHABLE;
1298                    }
1299                  default:
1300                    return new Unknown64(machInst);
1301                }
1302            } else if (bits(machInst, 31)) {
1303                return new Unknown64(machInst);
1304            } else {
1305                return decodeNeonMem(machInst);
1306            }
1307          case 0x1:
1308          {
1309            if (bits(machInst, 24) != 0)
1310                return new Unknown64(machInst);
1311            uint8_t switchVal = (bits(machInst, 26) << 0) |
1312                                (bits(machInst, 31, 30) << 1);
1313            int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
1314            IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1315            switch (switchVal) {
1316              case 0x0:
1317                return new LDRWL64_LIT(machInst, rt, imm);
1318              case 0x1:
1319                return new LDRSFP64_LIT(machInst, rt, imm);
1320              case 0x2:
1321                return new LDRXL64_LIT(machInst, rt, imm);
1322              case 0x3:
1323                return new LDRDFP64_LIT(machInst, rt, imm);
1324              case 0x4:
1325                return new LDRSWL64_LIT(machInst, rt, imm);
1326              case 0x5:
1327                return new BigFpMemLit("ldr", machInst, rt, imm);
1328              case 0x6:
1329                return new PRFM64_LIT(machInst, rt, imm);
1330              default:
1331                return new Unknown64(machInst);
1332            }
1333          }
1334          case 0x2:
1335          {
1336            uint8_t opc = bits(machInst, 31, 30);
1337            if (opc >= 3)
1338                return new Unknown64(machInst);
1339            uint32_t size = 0;
1340            bool fp = bits(machInst, 26);
1341            bool load = bits(machInst, 22);
1342            if (fp) {
1343                size = 4 << opc;
1344            } else {
1345                if ((opc == 1) && !load)
1346                    return new Unknown64(machInst);
1347                size = (opc == 0 || opc == 1) ? 4 : 8;
1348            }
1349            uint8_t type = bits(machInst, 24, 23);
1350            int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
1351
1352            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1353            IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1354            IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1355
1356            bool noAlloc = (type == 0);
1357            bool signExt = !noAlloc && !fp && opc == 1;
1358            PairMemOp::AddrMode mode;
1359            const char *mnemonic = NULL;
1360            switch (type) {
1361              case 0x0:
1362              case 0x2:
1363                mode = PairMemOp::AddrMd_Offset;
1364                break;
1365              case 0x1:
1366                mode = PairMemOp::AddrMd_PostIndex;
1367                break;
1368              case 0x3:
1369                mode = PairMemOp::AddrMd_PreIndex;
1370                break;
1371              default:
1372                return new Unknown64(machInst);
1373            }
1374            if (load) {
1375                if (noAlloc)
1376                    mnemonic = "ldnp";
1377                else if (signExt)
1378                    mnemonic = "ldpsw";
1379                else
1380                    mnemonic = "ldp";
1381            } else {
1382                if (noAlloc)
1383                    mnemonic = "stnp";
1384                else
1385                    mnemonic = "stp";
1386            }
1387
1388            return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
1389                    signExt, false, false, imm, mode, rn, rt, rt2);
1390          }
1391          // bit 29:27=111, 25=0
1392          case 0x3:
1393          {
1394            uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
1395                                (bits(machInst, 26) << 2) |
1396                                (bits(machInst, 31, 30) << 3);
1397            if (bits(machInst, 24) == 1) {
1398                uint64_t imm12 = bits(machInst, 21, 10);
1399                IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1400                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1401                IntRegIndex rnsp = makeSP(rn);
1402                switch (switchVal) {
1403                  case 0x00:
1404                    return new STRB64_IMM(machInst, rt, rnsp, imm12);
1405                  case 0x01:
1406                    return new LDRB64_IMM(machInst, rt, rnsp, imm12);
1407                  case 0x02:
1408                    return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
1409                  case 0x03:
1410                    return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
1411                  case 0x04:
1412                    return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
1413                  case 0x05:
1414                    return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
1415                  case 0x06:
1416                    return new BigFpMemImm("str", machInst, false,
1417                                           rt, rnsp, imm12 << 4);
1418                  case 0x07:
1419                    return new BigFpMemImm("ldr", machInst, true,
1420                                           rt, rnsp, imm12 << 4);
1421                  case 0x08:
1422                    return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
1423                  case 0x09:
1424                    return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
1425                  case 0x0a:
1426                    return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
1427                  case 0x0b:
1428                    return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
1429                  case 0x0c:
1430                    return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
1431                  case 0x0d:
1432                    return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
1433                  case 0x10:
1434                    return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
1435                  case 0x11:
1436                    return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
1437                  case 0x12:
1438                    return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
1439                  case 0x14:
1440                    return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
1441                  case 0x15:
1442                    return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
1443                  case 0x18:
1444                    return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
1445                  case 0x19:
1446                    return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
1447                  case 0x1a:
1448                    return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
1449                  case 0x1c:
1450                    return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
1451                  case 0x1d:
1452                    return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
1453                  default:
1454                    return new Unknown64(machInst);
1455                }
1456            } else if (bits(machInst, 21) == 1) {
1457                uint8_t group = bits(machInst, 11, 10);
1458                switch (group) {
1459                  case 0x0:
1460                    {
1461                        if ((switchVal & 0x7) == 0x2 &&
1462                                bits(machInst, 20, 12) == 0x1fc) {
1463                            IntRegIndex rt = (IntRegIndex)(uint32_t)
1464                                bits(machInst, 4, 0);
1465                            IntRegIndex rn = (IntRegIndex)(uint32_t)
1466                                bits(machInst, 9, 5);
1467                            IntRegIndex rnsp = makeSP(rn);
1468                            uint8_t size = bits(machInst, 31, 30);
1469                            switch (size) {
1470                              case 0x0:
1471                                return new LDAPRB64(machInst, rt, rnsp);
1472                              case 0x1:
1473                                return new LDAPRH64(machInst, rt, rnsp);
1474                              case 0x2:
1475                                return new LDAPRW64(machInst, rt, rnsp);
1476                              case 0x3:
1477                                return new LDAPRX64(machInst, rt, rnsp);
1478                              default:
1479                                M5_UNREACHABLE;
1480                            }
1481                        } else {
1482                            return decodeAtomicArithOp(machInst);
1483                        }
1484                    }
1485                  case 0x2:
1486                    {
1487                        if (!bits(machInst, 14))
1488                            return new Unknown64(machInst);
1489                        IntRegIndex rt = (IntRegIndex)(uint32_t)
1490                            bits(machInst, 4, 0);
1491                        IntRegIndex rn = (IntRegIndex)(uint32_t)
1492                            bits(machInst, 9, 5);
1493                        IntRegIndex rnsp = makeSP(rn);
1494                        IntRegIndex rm = (IntRegIndex)(uint32_t)
1495                            bits(machInst, 20, 16);
1496                        ArmExtendType type =
1497                            (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
1498                        uint8_t s = bits(machInst, 12);
1499                        switch (switchVal) {
1500                          case 0x00:
1501                            return new STRB64_REG(machInst, rt, rnsp, rm,
1502                                                  type, 0);
1503                          case 0x01:
1504                            return new LDRB64_REG(machInst, rt, rnsp, rm,
1505                                                  type, 0);
1506                          case 0x02:
1507                            return new LDRSBX64_REG(machInst, rt, rnsp, rm,
1508                                                    type, 0);
1509                          case 0x03:
1510                            return new LDRSBW64_REG(machInst, rt, rnsp, rm,
1511                                                    type, 0);
1512                          case 0x04:
1513                            return new STRBFP64_REG(machInst, rt, rnsp, rm,
1514                                                    type, 0);
1515                          case 0x05:
1516                            return new LDRBFP64_REG(machInst, rt, rnsp, rm,
1517                                                    type, 0);
1518                          case 0x6:
1519                            return new BigFpMemReg("str", machInst, false,
1520                                                   rt, rnsp, rm, type, s * 4);
1521                          case 0x7:
1522                            return new BigFpMemReg("ldr", machInst, true,
1523                                                   rt, rnsp, rm, type, s * 4);
1524                          case 0x08:
1525                            return new STRH64_REG(machInst, rt, rnsp, rm,
1526                                                  type, s);
1527                          case 0x09:
1528                            return new LDRH64_REG(machInst, rt, rnsp, rm,
1529                                                  type, s);
1530                          case 0x0a:
1531                            return new LDRSHX64_REG(machInst, rt, rnsp, rm,
1532                                                    type, s);
1533                          case 0x0b:
1534                            return new LDRSHW64_REG(machInst, rt, rnsp, rm,
1535                                                    type, s);
1536                          case 0x0c:
1537                            return new STRHFP64_REG(machInst, rt, rnsp, rm,
1538                                                    type, s);
1539                          case 0x0d:
1540                            return new LDRHFP64_REG(machInst, rt, rnsp, rm,
1541                                                    type, s);
1542                          case 0x10:
1543                            return new STRW64_REG(machInst, rt, rnsp, rm,
1544                                                  type, s * 2);
1545                          case 0x11:
1546                            return new LDRW64_REG(machInst, rt, rnsp, rm,
1547                                                  type, s * 2);
1548                          case 0x12:
1549                            return new LDRSW64_REG(machInst, rt, rnsp, rm,
1550                                                   type, s * 2);
1551                          case 0x14:
1552                            return new STRSFP64_REG(machInst, rt, rnsp, rm,
1553                                                    type, s * 2);
1554                          case 0x15:
1555                            return new LDRSFP64_REG(machInst, rt, rnsp, rm,
1556                                                    type, s * 2);
1557                          case 0x18:
1558                            return new STRX64_REG(machInst, rt, rnsp, rm,
1559                                                  type, s * 3);
1560                          case 0x19:
1561                            return new LDRX64_REG(machInst, rt, rnsp, rm,
1562                                                  type, s * 3);
1563                          case 0x1a:
1564                            return new PRFM64_REG(machInst, rt, rnsp, rm,
1565                                                  type, s * 3);
1566                          case 0x1c:
1567                            return new STRDFP64_REG(machInst, rt, rnsp, rm,
1568                                                    type, s * 3);
1569                          case 0x1d:
1570                            return new LDRDFP64_REG(machInst, rt, rnsp, rm,
1571                                                    type, s * 3);
1572                          default:
1573                            return new Unknown64(machInst);
1574
1575                        }
1576                    }
1577                  default:
1578                    return new Unknown64(machInst);
1579                }
1580            } else {
1581                // bit 29:27=111, 25:24=00, 21=0
1582                switch (bits(machInst, 11, 10)) {
1583                  case 0x0:
1584                  {
1585                    IntRegIndex rt =
1586                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1587                    IntRegIndex rn =
1588                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1589                    IntRegIndex rnsp = makeSP(rn);
1590                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1591                    switch (switchVal) {
1592                      case 0x00:
1593                        return new STURB64_IMM(machInst, rt, rnsp, imm);
1594                      case 0x01:
1595                        return new LDURB64_IMM(machInst, rt, rnsp, imm);
1596                      case 0x02:
1597                        return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
1598                      case 0x03:
1599                        return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
1600                      case 0x04:
1601                        return new STURBFP64_IMM(machInst, rt, rnsp, imm);
1602                      case 0x05:
1603                        return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
1604                      case 0x06:
1605                        return new BigFpMemImm("stur", machInst, false,
1606                                               rt, rnsp, imm);
1607                      case 0x07:
1608                        return new BigFpMemImm("ldur", machInst, true,
1609                                               rt, rnsp, imm);
1610                      case 0x08:
1611                        return new STURH64_IMM(machInst, rt, rnsp, imm);
1612                      case 0x09:
1613                        return new LDURH64_IMM(machInst, rt, rnsp, imm);
1614                      case 0x0a:
1615                        return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
1616                      case 0x0b:
1617                        return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
1618                      case 0x0c:
1619                        return new STURHFP64_IMM(machInst, rt, rnsp, imm);
1620                      case 0x0d:
1621                        return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
1622                      case 0x10:
1623                        return new STURW64_IMM(machInst, rt, rnsp, imm);
1624                      case 0x11:
1625                        return new LDURW64_IMM(machInst, rt, rnsp, imm);
1626                      case 0x12:
1627                        return new LDURSW64_IMM(machInst, rt, rnsp, imm);
1628                      case 0x14:
1629                        return new STURSFP64_IMM(machInst, rt, rnsp, imm);
1630                      case 0x15:
1631                        return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
1632                      case 0x18:
1633                        return new STURX64_IMM(machInst, rt, rnsp, imm);
1634                      case 0x19:
1635                        return new LDURX64_IMM(machInst, rt, rnsp, imm);
1636                      case 0x1a:
1637                        return new PRFUM64_IMM(machInst, rt, rnsp, imm);
1638                      case 0x1c:
1639                        return new STURDFP64_IMM(machInst, rt, rnsp, imm);
1640                      case 0x1d:
1641                        return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
1642                      default:
1643                        return new Unknown64(machInst);
1644                    }
1645                  }
1646                  // bit 29:27=111, 25:24=00, 21=0, 11:10=01
1647                  case 0x1:
1648                  {
1649                    IntRegIndex rt =
1650                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1651                    IntRegIndex rn =
1652                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1653                    IntRegIndex rnsp = makeSP(rn);
1654                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1655                    switch (switchVal) {
1656                      case 0x00:
1657                        return new STRB64_POST(machInst, rt, rnsp, imm);
1658                      case 0x01:
1659                        return new LDRB64_POST(machInst, rt, rnsp, imm);
1660                      case 0x02:
1661                        return new LDRSBX64_POST(machInst, rt, rnsp, imm);
1662                      case 0x03:
1663                        return new LDRSBW64_POST(machInst, rt, rnsp, imm);
1664                      case 0x04:
1665                        return new STRBFP64_POST(machInst, rt, rnsp, imm);
1666                      case 0x05:
1667                        return new LDRBFP64_POST(machInst, rt, rnsp, imm);
1668                      case 0x06:
1669                        return new BigFpMemPost("str", machInst, false,
1670                                                rt, rnsp, imm);
1671                      case 0x07:
1672                        return new BigFpMemPost("ldr", machInst, true,
1673                                                rt, rnsp, imm);
1674                      case 0x08:
1675                        return new STRH64_POST(machInst, rt, rnsp, imm);
1676                      case 0x09:
1677                        return new LDRH64_POST(machInst, rt, rnsp, imm);
1678                      case 0x0a:
1679                        return new LDRSHX64_POST(machInst, rt, rnsp, imm);
1680                      case 0x0b:
1681                        return new LDRSHW64_POST(machInst, rt, rnsp, imm);
1682                      case 0x0c:
1683                        return new STRHFP64_POST(machInst, rt, rnsp, imm);
1684                      case 0x0d:
1685                        return new LDRHFP64_POST(machInst, rt, rnsp, imm);
1686                      case 0x10:
1687                        return new STRW64_POST(machInst, rt, rnsp, imm);
1688                      case 0x11:
1689                        return new LDRW64_POST(machInst, rt, rnsp, imm);
1690                      case 0x12:
1691                        return new LDRSW64_POST(machInst, rt, rnsp, imm);
1692                      case 0x14:
1693                        return new STRSFP64_POST(machInst, rt, rnsp, imm);
1694                      case 0x15:
1695                        return new LDRSFP64_POST(machInst, rt, rnsp, imm);
1696                      case 0x18:
1697                        return new STRX64_POST(machInst, rt, rnsp, imm);
1698                      case 0x19:
1699                        return new LDRX64_POST(machInst, rt, rnsp, imm);
1700                      case 0x1c:
1701                        return new STRDFP64_POST(machInst, rt, rnsp, imm);
1702                      case 0x1d:
1703                        return new LDRDFP64_POST(machInst, rt, rnsp, imm);
1704                      default:
1705                        return new Unknown64(machInst);
1706                    }
1707                  }
1708                  case 0x2:
1709                  {
1710                    IntRegIndex rt =
1711                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1712                    IntRegIndex rn =
1713                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1714                    IntRegIndex rnsp = makeSP(rn);
1715                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1716                    switch (switchVal) {
1717                      case 0x00:
1718                        return new STTRB64_IMM(machInst, rt, rnsp, imm);
1719                      case 0x01:
1720                        return new LDTRB64_IMM(machInst, rt, rnsp, imm);
1721                      case 0x02:
1722                        return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
1723                      case 0x03:
1724                        return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
1725                      case 0x08:
1726                        return new STTRH64_IMM(machInst, rt, rnsp, imm);
1727                      case 0x09:
1728                        return new LDTRH64_IMM(machInst, rt, rnsp, imm);
1729                      case 0x0a:
1730                        return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
1731                      case 0x0b:
1732                        return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
1733                      case 0x10:
1734                        return new STTRW64_IMM(machInst, rt, rnsp, imm);
1735                      case 0x11:
1736                        return new LDTRW64_IMM(machInst, rt, rnsp, imm);
1737                      case 0x12:
1738                        return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
1739                      case 0x18:
1740                        return new STTRX64_IMM(machInst, rt, rnsp, imm);
1741                      case 0x19:
1742                        return new LDTRX64_IMM(machInst, rt, rnsp, imm);
1743                      default:
1744                        return new Unknown64(machInst);
1745                    }
1746                  }
1747                  case 0x3:
1748                  {
1749                    IntRegIndex rt =
1750                        (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1751                    IntRegIndex rn =
1752                        (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1753                    IntRegIndex rnsp = makeSP(rn);
1754                    uint64_t imm = sext<9>(bits(machInst, 20, 12));
1755                    switch (switchVal) {
1756                      case 0x00:
1757                        return new STRB64_PRE(machInst, rt, rnsp, imm);
1758                      case 0x01:
1759                        return new LDRB64_PRE(machInst, rt, rnsp, imm);
1760                      case 0x02:
1761                        return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
1762                      case 0x03:
1763                        return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
1764                      case 0x04:
1765                        return new STRBFP64_PRE(machInst, rt, rnsp, imm);
1766                      case 0x05:
1767                        return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
1768                      case 0x06:
1769                        return new BigFpMemPre("str", machInst, false,
1770                                               rt, rnsp, imm);
1771                      case 0x07:
1772                        return new BigFpMemPre("ldr", machInst, true,
1773                                               rt, rnsp, imm);
1774                      case 0x08:
1775                        return new STRH64_PRE(machInst, rt, rnsp, imm);
1776                      case 0x09:
1777                        return new LDRH64_PRE(machInst, rt, rnsp, imm);
1778                      case 0x0a:
1779                        return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
1780                      case 0x0b:
1781                        return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
1782                      case 0x0c:
1783                        return new STRHFP64_PRE(machInst, rt, rnsp, imm);
1784                      case 0x0d:
1785                        return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
1786                      case 0x10:
1787                        return new STRW64_PRE(machInst, rt, rnsp, imm);
1788                      case 0x11:
1789                        return new LDRW64_PRE(machInst, rt, rnsp, imm);
1790                      case 0x12:
1791                        return new LDRSW64_PRE(machInst, rt, rnsp, imm);
1792                      case 0x14:
1793                        return new STRSFP64_PRE(machInst, rt, rnsp, imm);
1794                      case 0x15:
1795                        return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
1796                      case 0x18:
1797                        return new STRX64_PRE(machInst, rt, rnsp, imm);
1798                      case 0x19:
1799                        return new LDRX64_PRE(machInst, rt, rnsp, imm);
1800                      case 0x1c:
1801                        return new STRDFP64_PRE(machInst, rt, rnsp, imm);
1802                      case 0x1d:
1803                        return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
1804                      default:
1805                        return new Unknown64(machInst);
1806                    }
1807                  }
1808                  default:
1809                    M5_UNREACHABLE;
1810                }
1811            }
1812          }
1813          default:
1814            M5_UNREACHABLE;
1815        }
1816        return new FailUnimplemented("Unhandled Case1", machInst);
1817    }
1818}
1819}};
1820
1821output decoder {{
1822namespace Aarch64
1823{
1824    StaticInstPtr
1825    decodeDataProcReg(ExtMachInst machInst)
1826    {
1827        uint8_t switchVal = (bits(machInst, 28) << 1) |
1828                            (bits(machInst, 24) << 0);
1829        switch (switchVal) {
1830          case 0x0:
1831          {
1832            uint8_t switchVal = (bits(machInst, 21) << 0) |
1833                                (bits(machInst, 30, 29) << 1);
1834            ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1835            uint8_t imm6 = bits(machInst, 15, 10);
1836            bool sf = bits(machInst, 31);
1837            if (!sf && (imm6 & 0x20))
1838                return new Unknown64(machInst);
1839            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1840            IntRegIndex rdzr = makeZero(rd);
1841            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1842            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1843
1844            switch (switchVal) {
1845              case 0x0:
1846                return new AndXSReg(machInst, rdzr, rn, rm, imm6, type);
1847              case 0x1:
1848                return new BicXSReg(machInst, rdzr, rn, rm, imm6, type);
1849              case 0x2:
1850                return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type);
1851              case 0x3:
1852                return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type);
1853              case 0x4:
1854                return new EorXSReg(machInst, rdzr, rn, rm, imm6, type);
1855              case 0x5:
1856                return new EonXSReg(machInst, rdzr, rn, rm, imm6, type);
1857              case 0x6:
1858                return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1859              case 0x7:
1860                return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1861              default:
1862                M5_UNREACHABLE;
1863            }
1864          }
1865          case 0x1:
1866          {
1867            uint8_t switchVal = bits(machInst, 30, 29);
1868            if (bits(machInst, 21) == 0) {
1869                ArmShiftType type =
1870                    (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1871                if (type == ROR)
1872                    return new Unknown64(machInst);
1873                uint8_t imm6 = bits(machInst, 15, 10);
1874                if (!bits(machInst, 31) && bits(imm6, 5))
1875                    return new Unknown64(machInst);
1876                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1877                IntRegIndex rdzr = makeZero(rd);
1878                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1879                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1880                switch (switchVal) {
1881                  case 0x0:
1882                    return new AddXSReg(machInst, rdzr, rn, rm, imm6, type);
1883                  case 0x1:
1884                    return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1885                  case 0x2:
1886                    return new SubXSReg(machInst, rdzr, rn, rm, imm6, type);
1887                  case 0x3:
1888                    return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1889                  default:
1890                    M5_UNREACHABLE;
1891                }
1892            } else {
1893                if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1894                   return new Unknown64(machInst);
1895                ArmExtendType type =
1896                    (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1897                uint8_t imm3 = bits(machInst, 12, 10);
1898                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1899                IntRegIndex rdsp = makeSP(rd);
1900                IntRegIndex rdzr = makeZero(rd);
1901                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1902                IntRegIndex rnsp = makeSP(rn);
1903                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1904
1905                switch (switchVal) {
1906                  case 0x0:
1907                    return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1908                  case 0x1:
1909                    return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1910                  case 0x2:
1911                    return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1912                  case 0x3:
1913                    return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1914                  default:
1915                    M5_UNREACHABLE;
1916                }
1917            }
1918          }
1919          case 0x2:
1920          {
1921            if (bits(machInst, 21) == 1)
1922                return new Unknown64(machInst);
1923            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1924            IntRegIndex rdzr = makeZero(rd);
1925            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1926            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1927            switch (bits(machInst, 23, 22)) {
1928              case 0x0:
1929              {
1930                if (bits(machInst, 15, 10))
1931                    return new Unknown64(machInst);
1932                uint8_t switchVal = bits(machInst, 30, 29);
1933                switch (switchVal) {
1934                  case 0x0:
1935                    return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1936                  case 0x1:
1937                    return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1938                  case 0x2:
1939                    return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1940                  case 0x3:
1941                    return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1942                  default:
1943                    M5_UNREACHABLE;
1944                }
1945              }
1946              case 0x1:
1947              {
1948                if ((bits(machInst, 4) == 1) ||
1949                        (bits(machInst, 10) == 1) ||
1950                        (bits(machInst, 29) == 0)) {
1951                    return new Unknown64(machInst);
1952                }
1953                ConditionCode cond =
1954                    (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1955                uint8_t flags = bits(machInst, 3, 0);
1956                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1957                if (bits(machInst, 11) == 0) {
1958                    IntRegIndex rm =
1959                        (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1960                    if (bits(machInst, 30) == 0) {
1961                        return new CcmnReg64(machInst, rn, rm, cond, flags);
1962                    } else {
1963                        return new CcmpReg64(machInst, rn, rm, cond, flags);
1964                    }
1965                } else {
1966                    uint8_t imm5 = bits(machInst, 20, 16);
1967                    if (bits(machInst, 30) == 0) {
1968                        return new CcmnImm64(machInst, rn, imm5, cond, flags);
1969                    } else {
1970                        return new CcmpImm64(machInst, rn, imm5, cond, flags);
1971                    }
1972                }
1973              }
1974              case 0x2:
1975              {
1976                if (bits(machInst, 29) == 1 ||
1977                        bits(machInst, 11) == 1) {
1978                    return new Unknown64(machInst);
1979                }
1980                uint8_t switchVal = (bits(machInst, 10) << 0) |
1981                                    (bits(machInst, 30) << 1);
1982                IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1983                IntRegIndex rdzr = makeZero(rd);
1984                IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1985                IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1986                ConditionCode cond =
1987                    (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1988                switch (switchVal) {
1989                  case 0x0:
1990                    return new Csel64(machInst, rdzr, rn, rm, cond);
1991                  case 0x1:
1992                    return new Csinc64(machInst, rdzr, rn, rm, cond);
1993                  case 0x2:
1994                    return new Csinv64(machInst, rdzr, rn, rm, cond);
1995                  case 0x3:
1996                    return new Csneg64(machInst, rdzr, rn, rm, cond);
1997                  default:
1998                    M5_UNREACHABLE;
1999                }
2000              }
2001              case 0x3:
2002                if (bits(machInst, 30) == 0) {
2003                    if (bits(machInst, 29) != 0)
2004                        return new Unknown64(machInst);
2005                    uint8_t switchVal = bits(machInst, 15, 10);
2006                    switch (switchVal) {
2007                      case 0x2:
2008                        return new Udiv64(machInst, rdzr, rn, rm);
2009                      case 0x3:
2010                        return new Sdiv64(machInst, rdzr, rn, rm);
2011                      case 0x8:
2012                        return new Lslv64(machInst, rdzr, rn, rm);
2013                      case 0x9:
2014                        return new Lsrv64(machInst, rdzr, rn, rm);
2015                      case 0xa:
2016                        return new Asrv64(machInst, rdzr, rn, rm);
2017                      case 0xb:
2018                        return new Rorv64(machInst, rdzr, rn, rm);
2019                      case 0x10:
2020                        return new Crc32b64(machInst, rdzr, rn, rm);
2021                      case 0x11:
2022                        return new Crc32h64(machInst, rdzr, rn, rm);
2023                      case 0x12:
2024                        return new Crc32w64(machInst, rdzr, rn, rm);
2025                      case 0x13:
2026                        return new Crc32x64(machInst, rdzr, rn, rm);
2027                      case 0x14:
2028                        return new Crc32cb64(machInst, rdzr, rn, rm);
2029                      case 0x15:
2030                        return new Crc32ch64(machInst, rdzr, rn, rm);
2031                      case 0x16:
2032                        return new Crc32cw64(machInst, rdzr, rn, rm);
2033                      case 0x17:
2034                        return new Crc32cx64(machInst, rdzr, rn, rm);
2035                      default:
2036                        return new Unknown64(machInst);
2037                    }
2038                } else {
2039                    if (bits(machInst, 20, 16) != 0 ||
2040                            bits(machInst, 29) != 0) {
2041                        return new Unknown64(machInst);
2042                    }
2043                    uint8_t switchVal = bits(machInst, 15, 10);
2044                    switch (switchVal) {
2045                      case 0x0:
2046                        return new Rbit64(machInst, rdzr, rn);
2047                      case 0x1:
2048                        return new Rev1664(machInst, rdzr, rn);
2049                      case 0x2:
2050                        if (bits(machInst, 31) == 0)
2051                            return new Rev64(machInst, rdzr, rn);
2052                        else
2053                            return new Rev3264(machInst, rdzr, rn);
2054                      case 0x3:
2055                        if (bits(machInst, 31) != 1)
2056                            return new Unknown64(machInst);
2057                        return new Rev64(machInst, rdzr, rn);
2058                      case 0x4:
2059                        return new Clz64(machInst, rdzr, rn);
2060                      case 0x5:
2061                        return new Cls64(machInst, rdzr, rn);
2062                      default:
2063                        return new Unknown64(machInst);
2064                    }
2065                }
2066              default:
2067                M5_UNREACHABLE;
2068            }
2069          }
2070          case 0x3:
2071          {
2072            if (bits(machInst, 30, 29) != 0x0 ||
2073                    (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
2074                return new Unknown64(machInst);
2075            IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
2076            IntRegIndex rdzr = makeZero(rd);
2077            IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
2078            IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
2079            IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
2080            switch (bits(machInst, 23, 21)) {
2081              case 0x0:
2082                if (bits(machInst, 15) == 0)
2083                    return new Madd64(machInst, rdzr, ra, rn, rm);
2084                else
2085                    return new Msub64(machInst, rdzr, ra, rn, rm);
2086              case 0x1:
2087                if (bits(machInst, 15) == 0)
2088                    return new Smaddl64(machInst, rdzr, ra, rn, rm);
2089                else
2090                    return new Smsubl64(machInst, rdzr, ra, rn, rm);
2091              case 0x2:
2092                if (bits(machInst, 15) != 0)
2093                    return new Unknown64(machInst);
2094                return new Smulh64(machInst, rdzr, rn, rm);
2095              case 0x5:
2096                if (bits(machInst, 15) == 0)
2097                    return new Umaddl64(machInst, rdzr, ra, rn, rm);
2098                else
2099                    return new Umsubl64(machInst, rdzr, ra, rn, rm);
2100              case 0x6:
2101                if (bits(machInst, 15) != 0)
2102                    return new Unknown64(machInst);
2103                return new Umulh64(machInst, rdzr, rn, rm);
2104              default:
2105                return new Unknown64(machInst);
2106            }
2107          }
2108          default:
2109            M5_UNREACHABLE;
2110        }
2111        return new FailUnimplemented("Unhandled Case2", machInst);
2112    }
2113}
2114}};
2115
2116output decoder {{
2117namespace Aarch64
2118{
2119    template <typename DecoderFeatures>
2120    StaticInstPtr
2121    decodeAdvSIMD(ExtMachInst machInst)
2122    {
2123        if (bits(machInst, 24) == 1) {
2124            if (bits(machInst, 10) == 0) {
2125                return decodeNeonIndexedElem<DecoderFeatures>(machInst);
2126            } else if (bits(machInst, 23) == 1) {
2127                return new Unknown64(machInst);
2128            } else {
2129                if (bits(machInst, 22, 19)) {
2130                    return decodeNeonShiftByImm(machInst);
2131                } else {
2132                    return decodeNeonModImm(machInst);
2133                }
2134            }
2135        } else if (bits(machInst, 21) == 1) {
2136            if (bits(machInst, 10) == 1) {
2137                return decodeNeon3Same<DecoderFeatures>(machInst);
2138            } else if (bits(machInst, 11) == 0) {
2139                return decodeNeon3Diff(machInst);
2140            } else if (bits(machInst, 20, 17) == 0x0) {
2141                return decodeNeon2RegMisc(machInst);
2142            } else if (bits(machInst, 20, 17) == 0x4) {
2143                return decodeCryptoAES(machInst);
2144            } else if (bits(machInst, 20, 17) == 0x8) {
2145                return decodeNeonAcrossLanes(machInst);
2146            } else {
2147                return new Unknown64(machInst);
2148            }
2149        } else if (bits(machInst, 24) ||
2150                   bits(machInst, 21) ||
2151                   bits(machInst, 15)) {
2152            return new Unknown64(machInst);
2153        } else if (bits(machInst, 10) == 1) {
2154            if (bits(machInst, 23, 22))
2155                return new Unknown64(machInst);
2156            return decodeNeonCopy(machInst);
2157        } else if (bits(machInst, 29) == 1) {
2158            return decodeNeonExt(machInst);
2159        } else if (bits(machInst, 11) == 1) {
2160            return decodeNeonZipUzpTrn(machInst);
2161        } else if (bits(machInst, 23, 22) == 0x0) {
2162            return decodeNeonTblTbx(machInst);
2163        } else {
2164            return new Unknown64(machInst);
2165        }
2166        return new FailUnimplemented("Unhandled Case3", machInst);
2167    }
2168}
2169}};
2170
2171
2172output decoder {{
2173namespace Aarch64
2174{
2175    StaticInstPtr
2176    // bit 30=0, 28:25=1111
2177    decodeFp(ExtMachInst machInst)
2178    {
2179        if (bits(machInst, 24) == 1) {
2180            if (bits(machInst, 31) || bits(machInst, 29))
2181                return new Unknown64(machInst);
2182            IntRegIndex rd    = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2183            IntRegIndex rn    = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2184            IntRegIndex rm    = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2185            IntRegIndex ra    = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
2186            uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
2187                                (bits(machInst, 15)     << 0);
2188            switch (switchVal) {
2189              case 0x0: // FMADD Sd = Sa + Sn*Sm
2190                return new FMAddS(machInst, rd, rn, rm, ra);
2191              case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
2192                return new FMSubS(machInst, rd, rn, rm, ra);
2193              case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
2194                return new FNMAddS(machInst, rd, rn, rm, ra);
2195              case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
2196                return new FNMSubS(machInst, rd, rn, rm, ra);
2197              case 0x4: // FMADD Dd = Da + Dn*Dm
2198                return new FMAddD(machInst, rd, rn, rm, ra);
2199              case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
2200                return new FMSubD(machInst, rd, rn, rm, ra);
2201              case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
2202                return new FNMAddD(machInst, rd, rn, rm, ra);
2203              case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
2204                return new FNMSubD(machInst, rd, rn, rm, ra);
2205              default:
2206                return new Unknown64(machInst);
2207            }
2208        } else if (bits(machInst, 21) == 0) {
2209            bool s = bits(machInst, 29);
2210            if (s)
2211                return new Unknown64(machInst);
2212            uint8_t switchVal = bits(machInst, 20, 16);
2213            uint8_t type      = bits(machInst, 23, 22);
2214            uint8_t scale     = bits(machInst, 15, 10);
2215            IntRegIndex rd    = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2216            IntRegIndex rn    = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2217            if (bits(machInst, 18, 17) == 3 && scale != 0)
2218                return new Unknown64(machInst);
2219            // 30:24=0011110, 21=0
2220            switch (switchVal) {
2221              case 0x00:
2222                return new FailUnimplemented("fcvtns", machInst);
2223              case 0x01:
2224                return new FailUnimplemented("fcvtnu", machInst);
2225              case 0x02:
2226                switch ( (bits(machInst, 31) << 2) | type ) {
2227                  case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
2228                    return new FcvtSFixedFpSW(machInst, rd, rn, scale);
2229                  case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
2230                    return new FcvtSFixedFpDW(machInst, rd, rn, scale);
2231                  case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
2232                    return new FcvtSFixedFpSX(machInst, rd, rn, scale);
2233                  case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
2234                    return new FcvtSFixedFpDX(machInst, rd, rn, scale);
2235                  default:
2236                    return new Unknown64(machInst);
2237                }
2238              case 0x03:
2239                switch ( (bits(machInst, 31) << 2) | type ) {
2240                  case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
2241                    return new FcvtUFixedFpSW(machInst, rd, rn, scale);
2242                  case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
2243                    return new FcvtUFixedFpDW(machInst, rd, rn, scale);
2244                  case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
2245                    return new FcvtUFixedFpSX(machInst, rd, rn, scale);
2246                  case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
2247                    return new FcvtUFixedFpDX(machInst, rd, rn, scale);
2248                  default:
2249                    return new Unknown64(machInst);
2250                }
2251              case 0x04:
2252                return new FailUnimplemented("fcvtas", machInst);
2253              case 0x05:
2254                return new FailUnimplemented("fcvtau", machInst);
2255              case 0x08:
2256                return new FailUnimplemented("fcvtps", machInst);
2257              case 0x09:
2258                return new FailUnimplemented("fcvtpu", machInst);
2259              case 0x0e:
2260                return new FailUnimplemented("fmov elem. to 64", machInst);
2261              case 0x0f:
2262                return new FailUnimplemented("fmov 64 bit", machInst);
2263              case 0x10:
2264                return new FailUnimplemented("fcvtms", machInst);
2265              case 0x11:
2266                return new FailUnimplemented("fcvtmu", machInst);
2267              case 0x18:
2268                switch ( (bits(machInst, 31) << 2) | type ) {
2269                  case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
2270                    return new FcvtFpSFixedSW(machInst, rd, rn, scale);
2271                  case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
2272                    return new FcvtFpSFixedDW(machInst, rd, rn, scale);
2273                  case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
2274                    return new FcvtFpSFixedSX(machInst, rd, rn, scale);
2275                  case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
2276                    return new FcvtFpSFixedDX(machInst, rd, rn, scale);
2277                  default:
2278                    return new Unknown64(machInst);
2279                }
2280              case 0x19:
2281                switch ( (bits(machInst, 31) << 2) | type ) {
2282                  case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
2283                    return new FcvtFpUFixedSW(machInst, rd, rn, scale);
2284                  case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
2285                    return new FcvtFpUFixedDW(machInst, rd, rn, scale);
2286                  case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
2287                    return new FcvtFpUFixedSX(machInst, rd, rn, scale);
2288                  case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
2289                    return new FcvtFpUFixedDX(machInst, rd, rn, scale);
2290                  default:
2291                    return new Unknown64(machInst);
2292                }
2293              default:
2294                return new Unknown64(machInst);
2295            }
2296        } else {
2297            // 30=0, 28:24=11110, 21=1
2298            uint8_t type   = bits(machInst, 23, 22);
2299            uint8_t imm8   = bits(machInst, 20, 13);
2300            IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2301            IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2302            switch (bits(machInst, 11, 10)) {
2303              case 0x0:
2304                if (bits(machInst, 12) == 1) {
2305                    if (bits(machInst, 31) ||
2306                            bits(machInst, 29) ||
2307                            bits(machInst, 9, 5)) {
2308                        return new Unknown64(machInst);
2309                    }
2310                    // 31:29=000, 28:24=11110, 21=1, 12:10=100
2311                    if (type == 0) {
2312                        // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
2313                        //             :imm8<5:0>:Zeros(19)
2314                        uint32_t imm = vfp_modified_imm(imm8,
2315                                                        FpDataType::Fp32);
2316                        return new FmovImmS(machInst, rd, imm);
2317                    } else if (type == 1) {
2318                        // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
2319                        //             :imm8<5:0>:Zeros(48)
2320                        uint64_t imm = vfp_modified_imm(imm8,
2321                                                        FpDataType::Fp64);
2322                        return new FmovImmD(machInst, rd, imm);
2323                    } else {
2324                        return new Unknown64(machInst);
2325                    }
2326                } else if (bits(machInst, 13) == 1) {
2327                    if (bits(machInst, 31) ||
2328                            bits(machInst, 29) ||
2329                            bits(machInst, 15, 14) ||
2330                            bits(machInst, 23) ||
2331                            bits(machInst, 2, 0)) {
2332                        return new Unknown64(machInst);
2333                    }
2334                    uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
2335                                        (bits(machInst, 22) << 2);
2336                    IntRegIndex rm = (IntRegIndex)(uint32_t)
2337                                        bits(machInst, 20, 16);
2338                    // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
2339                    switch (switchVal) {
2340                      case 0x0:
2341                        // FCMP flags = compareQuiet(Sn,Sm)
2342                        return new FCmpRegS(machInst, rn, rm);
2343                      case 0x1:
2344                        // FCMP flags = compareQuiet(Sn,0.0)
2345                        return new FCmpImmS(machInst, rn, 0);
2346                      case 0x2:
2347                        // FCMPE flags = compareSignaling(Sn,Sm)
2348                        return new FCmpERegS(machInst, rn, rm);
2349                      case 0x3:
2350                        // FCMPE flags = compareSignaling(Sn,0.0)
2351                        return new FCmpEImmS(machInst, rn, 0);
2352                      case 0x4:
2353                        // FCMP flags = compareQuiet(Dn,Dm)
2354                        return new FCmpRegD(machInst, rn, rm);
2355                      case 0x5:
2356                        // FCMP flags = compareQuiet(Dn,0.0)
2357                        return new FCmpImmD(machInst, rn, 0);
2358                      case 0x6:
2359                        // FCMPE flags = compareSignaling(Dn,Dm)
2360                        return new FCmpERegD(machInst, rn, rm);
2361                      case 0x7:
2362                        // FCMPE flags = compareSignaling(Dn,0.0)
2363                        return new FCmpEImmD(machInst, rn, 0);
2364                      default:
2365                        return new Unknown64(machInst);
2366                    }
2367                } else if (bits(machInst, 14) == 1) {
2368                    if (bits(machInst, 31) || bits(machInst, 29))
2369                        return new Unknown64(machInst);
2370                    uint8_t opcode = bits(machInst, 20, 15);
2371                    // Bits 31:24=00011110, 21=1, 14:10=10000
2372                    switch (opcode) {
2373                      case 0x0:
2374                        if (type == 0)
2375                            // FMOV Sd = Sn
2376                            return new FmovRegS(machInst, rd, rn);
2377                        else if (type == 1)
2378                            // FMOV Dd = Dn
2379                            return new FmovRegD(machInst, rd, rn);
2380                        break;
2381                      case 0x1:
2382                        if (type == 0)
2383                            // FABS Sd = abs(Sn)
2384                            return new FAbsS(machInst, rd, rn);
2385                        else if (type == 1)
2386                            // FABS Dd = abs(Dn)
2387                            return new FAbsD(machInst, rd, rn);
2388                        break;
2389                      case 0x2:
2390                        if (type == 0)
2391                            // FNEG Sd = -Sn
2392                            return new FNegS(machInst, rd, rn);
2393                        else if (type == 1)
2394                            // FNEG Dd = -Dn
2395                            return new FNegD(machInst, rd, rn);
2396                        break;
2397                      case 0x3:
2398                        if (type == 0)
2399                            // FSQRT Sd = sqrt(Sn)
2400                            return new FSqrtS(machInst, rd, rn);
2401                        else if (type == 1)
2402                            // FSQRT Dd = sqrt(Dn)
2403                            return new FSqrtD(machInst, rd, rn);
2404                        break;
2405                      case 0x4:
2406                        if (type == 1)
2407                            // FCVT Sd = convertFormat(Dn)
2408                            return new FcvtFpDFpS(machInst, rd, rn);
2409                        else if (type == 3)
2410                            // FCVT Sd = convertFormat(Hn)
2411                            return new FcvtFpHFpS(machInst, rd, rn);
2412                        break;
2413                      case 0x5:
2414                        if (type == 0)
2415                            // FCVT Dd = convertFormat(Sn)
2416                            return new FCvtFpSFpD(machInst, rd, rn);
2417                        else if (type == 3)
2418                            // FCVT Dd = convertFormat(Hn)
2419                            return new FcvtFpHFpD(machInst, rd, rn);
2420                        break;
2421                      case 0x7:
2422                        if (type == 0)
2423                            // FCVT Hd = convertFormat(Sn)
2424                            return new FcvtFpSFpH(machInst, rd, rn);
2425                        else if (type == 1)
2426                            // FCVT Hd = convertFormat(Dn)
2427                            return new FcvtFpDFpH(machInst, rd, rn);
2428                        break;
2429                      case 0x8:
2430                        if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
2431                            return new FRIntNS(machInst, rd, rn);
2432                        else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
2433                            return new FRIntND(machInst, rd, rn);
2434                        break;
2435                      case 0x9:
2436                        if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
2437                            return new FRIntPS(machInst, rd, rn);
2438                        else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
2439                            return new FRIntPD(machInst, rd, rn);
2440                        break;
2441                      case 0xa:
2442                        if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
2443                            return new FRIntMS(machInst, rd, rn);
2444                        else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
2445                            return new FRIntMD(machInst, rd, rn);
2446                        break;
2447                      case 0xb:
2448                        if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
2449                            return new FRIntZS(machInst, rd, rn);
2450                        else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
2451                            return new FRIntZD(machInst, rd, rn);
2452                        break;
2453                      case 0xc:
2454                        if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
2455                            return new FRIntAS(machInst, rd, rn);
2456                        else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
2457                            return new FRIntAD(machInst, rd, rn);
2458                        break;
2459                      case 0xe:
2460                        if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
2461                            return new FRIntXS(machInst, rd, rn);
2462                        else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
2463                            return new FRIntXD(machInst, rd, rn);
2464                        break;
2465                      case 0xf:
2466                        if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
2467                            return new FRIntIS(machInst, rd, rn);
2468                        else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
2469                            return new FRIntID(machInst, rd, rn);
2470                        break;
2471                      default:
2472                        return new Unknown64(machInst);
2473                    }
2474                    return new Unknown64(machInst);
2475                } else if (bits(machInst, 15) == 1) {
2476                    return new Unknown64(machInst);
2477                } else {
2478                    if (bits(machInst, 29))
2479                        return new Unknown64(machInst);
2480                    uint8_t rmode      = bits(machInst, 20, 19);
2481                    uint8_t switchVal1 = bits(machInst, 18, 16);
2482                    uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
2483                    // 30:24=0011110, 21=1, 15:10=000000
2484                    switch (switchVal1) {
2485                      case 0x0:
2486                        switch ((switchVal2 << 2) | rmode) {
2487                          case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
2488                            return new FcvtFpSIntWSN(machInst, rd, rn);
2489                          case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
2490                            return new FcvtFpSIntWSP(machInst, rd, rn);
2491                          case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
2492                            return new FcvtFpSIntWSM(machInst, rd, rn);
2493                          case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
2494                            return new FcvtFpSIntWSZ(machInst, rd, rn);
2495                          case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
2496                            return new FcvtFpSIntXSN(machInst, rd, rn);
2497                          case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
2498                            return new FcvtFpSIntXSP(machInst, rd, rn);
2499                          case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
2500                            return new FcvtFpSIntXSM(machInst, rd, rn);
2501                          case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
2502                            return new FcvtFpSIntXSZ(machInst, rd, rn);
2503                          case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
2504                            return new FcvtFpSIntWDN(machInst, rd, rn);
2505                          case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
2506                            return new FcvtFpSIntWDP(machInst, rd, rn);
2507                          case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
2508                            return new FcvtFpSIntWDM(machInst, rd, rn);
2509                          case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
2510                            return new FcvtFpSIntWDZ(machInst, rd, rn);
2511                          case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
2512                            return new FcvtFpSIntXDN(machInst, rd, rn);
2513                          case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
2514                            return new FcvtFpSIntXDP(machInst, rd, rn);
2515                          case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
2516                            return new FcvtFpSIntXDM(machInst, rd, rn);
2517                          case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
2518                            return new FcvtFpSIntXDZ(machInst, rd, rn);
2519                          default:
2520                            return new Unknown64(machInst);
2521                        }
2522                      case 0x1:
2523                        switch ((switchVal2 << 2) | rmode) {
2524                          case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
2525                            return new FcvtFpUIntWSN(machInst, rd, rn);
2526                          case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
2527                            return new FcvtFpUIntWSP(machInst, rd, rn);
2528                          case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
2529                            return new FcvtFpUIntWSM(machInst, rd, rn);
2530                          case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
2531                            return new FcvtFpUIntWSZ(machInst, rd, rn);
2532                          case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
2533                            return new FcvtFpUIntXSN(machInst, rd, rn);
2534                          case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
2535                            return new FcvtFpUIntXSP(machInst, rd, rn);
2536                          case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
2537                            return new FcvtFpUIntXSM(machInst, rd, rn);
2538                          case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
2539                            return new FcvtFpUIntXSZ(machInst, rd, rn);
2540                          case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
2541                            return new FcvtFpUIntWDN(machInst, rd, rn);
2542                          case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
2543                            return new FcvtFpUIntWDP(machInst, rd, rn);
2544                          case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
2545                            return new FcvtFpUIntWDM(machInst, rd, rn);
2546                          case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
2547                            return new FcvtFpUIntWDZ(machInst, rd, rn);
2548                          case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
2549                            return new FcvtFpUIntXDN(machInst, rd, rn);
2550                          case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
2551                            return new FcvtFpUIntXDP(machInst, rd, rn);
2552                          case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
2553                            return new FcvtFpUIntXDM(machInst, rd, rn);
2554                          case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
2555                            return new FcvtFpUIntXDZ(machInst, rd, rn);
2556                          default:
2557                            return new Unknown64(machInst);
2558                        }
2559                      case 0x2:
2560                        if (rmode != 0)
2561                            return new Unknown64(machInst);
2562                        switch (switchVal2) {
2563                          case 0: // SCVTF Sd = convertFromInt(Wn)
2564                            return new FcvtWSIntFpS(machInst, rd, rn);
2565                          case 1: // SCVTF Sd = convertFromInt(Xn)
2566                            return new FcvtXSIntFpS(machInst, rd, rn);
2567                          case 2: // SCVTF Dd = convertFromInt(Wn)
2568                            return new FcvtWSIntFpD(machInst, rd, rn);
2569                          case 3: // SCVTF Dd = convertFromInt(Xn)
2570                            return new FcvtXSIntFpD(machInst, rd, rn);
2571                          default:
2572                            return new Unknown64(machInst);
2573                        }
2574                      case 0x3:
2575                        switch (switchVal2) {
2576                          case 0: // UCVTF Sd = convertFromInt(Wn)
2577                            return new FcvtWUIntFpS(machInst, rd, rn);
2578                          case 1: // UCVTF Sd = convertFromInt(Xn)
2579                            return new FcvtXUIntFpS(machInst, rd, rn);
2580                          case 2: // UCVTF Dd = convertFromInt(Wn)
2581                            return new FcvtWUIntFpD(machInst, rd, rn);
2582                          case 3: // UCVTF Dd = convertFromInt(Xn)
2583                            return new FcvtXUIntFpD(machInst, rd, rn);
2584                          default:
2585                            return new Unknown64(machInst);
2586                        }
2587                      case 0x4:
2588                        if (rmode != 0)
2589                            return new Unknown64(machInst);
2590                        switch (switchVal2) {
2591                          case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
2592                            return new FcvtFpSIntWSA(machInst, rd, rn);
2593                          case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
2594                            return new FcvtFpSIntXSA(machInst, rd, rn);
2595                          case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
2596                            return new FcvtFpSIntWDA(machInst, rd, rn);
2597                          case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
2598                            return new FcvtFpSIntXDA(machInst, rd, rn);
2599                          default:
2600                            return new Unknown64(machInst);
2601                        }
2602                      case 0x5:
2603                        switch (switchVal2) {
2604                          case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
2605                            return new FcvtFpUIntWSA(machInst, rd, rn);
2606                          case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
2607                            return new FcvtFpUIntXSA(machInst, rd, rn);
2608                          case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
2609                            return new FcvtFpUIntWDA(machInst, rd, rn);
2610                          case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
2611                            return new FcvtFpUIntXDA(machInst, rd, rn);
2612                          default:
2613                            return new Unknown64(machInst);
2614                        }
2615                      case 0x06:
2616                        switch (switchVal2) {
2617                          case 0: // FMOV Wd = Sn
2618                            if (rmode != 0)
2619                                return new Unknown64(machInst);
2620                            return new FmovRegCoreW(machInst, rd, rn);
2621                          case 3: // FMOV Xd = Dn
2622                            if (rmode != 0)
2623                                return new Unknown64(machInst);
2624                            return new FmovRegCoreX(machInst, rd, rn);
2625                          case 5: // FMOV Xd = Vn<127:64>
2626                            if (rmode != 1)
2627                                return new Unknown64(machInst);
2628                            return new FmovURegCoreX(machInst, rd, rn);
2629                          default:
2630                            return new Unknown64(machInst);
2631                        }
2632                        break;
2633                      case 0x07:
2634                        switch (switchVal2) {
2635                          case 0: // FMOV Sd = Wn
2636                            if (rmode != 0)
2637                                return new Unknown64(machInst);
2638                            return new FmovCoreRegW(machInst, rd, rn);
2639                          case 3: // FMOV Xd = Dn
2640                            if (rmode != 0)
2641                                return new Unknown64(machInst);
2642                            return new FmovCoreRegX(machInst, rd, rn);
2643                          case 5: // FMOV Xd = Vn<127:64>
2644                            if (rmode != 1)
2645                                return new Unknown64(machInst);
2646                            return new FmovUCoreRegX(machInst, rd, rn);
2647                          default:
2648                            return new Unknown64(machInst);
2649                        }
2650                        break;
2651                      default: // Warning! missing cases in switch statement above, that still need to be added
2652                        return new Unknown64(machInst);
2653                    }
2654                }
2655                M5_UNREACHABLE;
2656              case 0x1:
2657              {
2658                if (bits(machInst, 31) ||
2659                    bits(machInst, 29) ||
2660                    bits(machInst, 23)) {
2661                    return new Unknown64(machInst);
2662                }
2663                IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
2664                IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
2665                uint8_t    imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
2666                ConditionCode cond =
2667                    (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2668                uint8_t switchVal = (bits(machInst, 4) << 0) |
2669                                    (bits(machInst, 22) << 1);
2670                // 31:23=000111100, 21=1, 11:10=01
2671                switch (switchVal) {
2672                  case 0x0:
2673                    // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
2674                    return new FCCmpRegS(machInst, rn, rm, cond, imm);
2675                  case 0x1:
2676                    // FCCMP flags = if cond then compareSignaling(Sn,Sm)
2677                    //               else #nzcv
2678                    return new FCCmpERegS(machInst, rn, rm, cond, imm);
2679                  case 0x2:
2680                    // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
2681                    return new FCCmpRegD(machInst, rn, rm, cond, imm);
2682                  case 0x3:
2683                    // FCCMP flags = if cond then compareSignaling(Dn,Dm)
2684                    //               else #nzcv
2685                    return new FCCmpERegD(machInst, rn, rm, cond, imm);
2686                  default:
2687                    return new Unknown64(machInst);
2688                }
2689              }
2690              case 0x2:
2691              {
2692                if (bits(machInst, 31) ||
2693                        bits(machInst, 29) ||
2694                        bits(machInst, 23)) {
2695                    return new Unknown64(machInst);
2696                }
2697                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst,  4,  0);
2698                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst,  9,  5);
2699                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2700                uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
2701                                    (bits(machInst, 22) << 4);
2702                switch (switchVal) {
2703                  case 0x00: // FMUL Sd = Sn * Sm
2704                    return new FMulS(machInst, rd, rn, rm);
2705                  case 0x10: // FMUL Dd = Dn * Dm
2706                    return new FMulD(machInst, rd, rn, rm);
2707                  case 0x01: // FDIV Sd = Sn / Sm
2708                    return new FDivS(machInst, rd, rn, rm);
2709                  case 0x11: // FDIV Dd = Dn / Dm
2710                    return new FDivD(machInst, rd, rn, rm);
2711                  case 0x02: // FADD Sd = Sn + Sm
2712                    return new FAddS(machInst, rd, rn, rm);
2713                  case 0x12: // FADD Dd = Dn + Dm
2714                    return new FAddD(machInst, rd, rn, rm);
2715                  case 0x03: // FSUB Sd = Sn - Sm
2716                    return new FSubS(machInst, rd, rn, rm);
2717                  case 0x13: // FSUB Dd = Dn - Dm
2718                    return new FSubD(machInst, rd, rn, rm);
2719                  case 0x04: // FMAX Sd = max(Sn, Sm)
2720                    return new FMaxS(machInst, rd, rn, rm);
2721                  case 0x14: // FMAX Dd = max(Dn, Dm)
2722                    return new FMaxD(machInst, rd, rn, rm);
2723                  case 0x05: // FMIN Sd = min(Sn, Sm)
2724                    return new FMinS(machInst, rd, rn, rm);
2725                  case 0x15: // FMIN Dd = min(Dn, Dm)
2726                    return new FMinD(machInst, rd, rn, rm);
2727                  case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
2728                    return new FMaxNMS(machInst, rd, rn, rm);
2729                  case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
2730                    return new FMaxNMD(machInst, rd, rn, rm);
2731                  case 0x07: // FMINNM Sd = minNum(Sn, Sm)
2732                    return new FMinNMS(machInst, rd, rn, rm);
2733                  case 0x17: // FMINNM Dd = minNum(Dn, Dm)
2734                    return new FMinNMD(machInst, rd, rn, rm);
2735                  case 0x08: // FNMUL Sd = -(Sn * Sm)
2736                    return new FNMulS(machInst, rd, rn, rm);
2737                  case 0x18: // FNMUL Dd = -(Dn * Dm)
2738                    return new FNMulD(machInst, rd, rn, rm);
2739                  default:
2740                    return new Unknown64(machInst);
2741                }
2742              }
2743              case 0x3:
2744              {
2745                if (bits(machInst, 31) || bits(machInst, 29))
2746                    return new Unknown64(machInst);
2747                uint8_t type = bits(machInst, 23, 22);
2748                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst,  4,  0);
2749                IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst,  9,  5);
2750                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2751                ConditionCode cond =
2752                    (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2753                if (type == 0) // FCSEL Sd = if cond then Sn else Sm
2754                    return new FCSelS(machInst, rd, rn, rm, cond);
2755                else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
2756                    return new FCSelD(machInst, rd, rn, rm, cond);
2757                else
2758                    return new Unknown64(machInst);
2759              }
2760              default:
2761                M5_UNREACHABLE;
2762            }
2763        }
2764        M5_UNREACHABLE;
2765    }
2766}
2767}};
2768
2769output decoder {{
2770namespace Aarch64
2771{
2772    StaticInstPtr
2773    decodeAdvSIMDScalar(ExtMachInst machInst)
2774    {
2775        if (bits(machInst, 24) == 1) {
2776            if (bits(machInst, 10) == 0) {
2777                return decodeNeonScIndexedElem(machInst);
2778            } else if (bits(machInst, 23) == 0) {
2779                return decodeNeonScShiftByImm(machInst);
2780            }
2781        } else if (bits(machInst, 21) == 1) {
2782            if (bits(machInst, 10) == 1) {
2783                return decodeNeonSc3Same(machInst);
2784            } else if (bits(machInst, 11) == 0) {
2785                return decodeNeonSc3Diff(machInst);
2786            } else if (bits(machInst, 20, 17) == 0x0) {
2787                return decodeNeonSc2RegMisc(machInst);
2788            } else if (bits(machInst, 20, 17) == 0x4) {
2789                return decodeCryptoTwoRegSHA(machInst);
2790            } else if (bits(machInst, 20, 17) == 0x8) {
2791                return decodeNeonScPwise(machInst);
2792            } else {
2793                return new Unknown64(machInst);
2794            }
2795        } else if (bits(machInst, 23, 22) == 0 &&
2796                   bits(machInst, 15) == 0) {
2797            if (bits(machInst, 10) == 1) {
2798                return decodeNeonScCopy(machInst);
2799            } else {
2800                return decodeCryptoThreeRegSHA(machInst);
2801            }
2802        } else {
2803            return new Unknown64(machInst);
2804        }
2805        return new FailUnimplemented("Unhandled Case6", machInst);
2806    }
2807}
2808}};
2809
2810output decoder {{
2811namespace Aarch64
2812{
2813    template <typename DecoderFeatures>
2814    StaticInstPtr
2815    decodeFpAdvSIMD(ExtMachInst machInst)
2816    {
2817
2818        if (bits(machInst, 28) == 0) {
2819            if (bits(machInst, 31) == 0) {
2820                return decodeAdvSIMD<DecoderFeatures>(machInst);
2821            } else {
2822                return new Unknown64(machInst);
2823            }
2824        } else if (bits(machInst, 30) == 0) {
2825            return decodeFp(machInst);
2826        } else if (bits(machInst, 31) == 0) {
2827            return decodeAdvSIMDScalar(machInst);
2828        } else {
2829            return new Unknown64(machInst);
2830        }
2831    }
2832}
2833}};
2834
2835let {{
2836    decoder_output ='''
2837namespace Aarch64
2838{'''
2839    for decoderFlavour, type_dict in decoders.iteritems():
2840        decoder_output +='''
2841template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst);
2842''' % { "df" : decoderFlavour }
2843    decoder_output +='''
2844}'''
2845}};
2846
2847output decoder {{
2848namespace Aarch64
2849{
2850    StaticInstPtr
2851    decodeGem5Ops(ExtMachInst machInst)
2852    {
2853        const uint32_t m5func = bits(machInst, 23, 16);
2854        switch (m5func) {
2855          case M5OP_ARM: return new Arm(machInst);
2856          case M5OP_QUIESCE: return new Quiesce(machInst);
2857          case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst);
2858          case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst);
2859          case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst);
2860          case M5OP_RPNS: return new Rpns64(machInst);
2861          case M5OP_WAKE_CPU: return new WakeCPU64(machInst);
2862          case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst);
2863          case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst);
2864          case M5OP_DEPRECATED3: return new Deprecated_exit (machInst);
2865          case M5OP_EXIT: return new M5exit64(machInst);
2866          case M5OP_FAIL: return new M5fail64(machInst);
2867          case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst);
2868          case M5OP_INIT_PARAM: return new Initparam64(machInst);
2869          case M5OP_RESET_STATS: return new Resetstats64(machInst);
2870          case M5OP_DUMP_STATS: return new Dumpstats64(machInst);
2871          case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst);
2872          case M5OP_CHECKPOINT: return new M5checkpoint64(machInst);
2873          case M5OP_WRITE_FILE: return new M5writefile64(machInst);
2874          case M5OP_READ_FILE: return new M5readfile64(machInst);
2875          case M5OP_DEBUG_BREAK: return new M5break(machInst);
2876          case M5OP_SWITCH_CPU: return new M5switchcpu(machInst);
2877          case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst);
2878          case M5OP_PANIC: return new M5panic(machInst);
2879          case M5OP_WORK_BEGIN: return new M5workbegin64(machInst);
2880          case M5OP_WORK_END: return new M5workend64(machInst);
2881          default: return new Unknown64(machInst);
2882        }
2883    }
2884}
2885}};
2886
2887def format Aarch64() {{
2888    decode_block = '''
2889    {
2890        using namespace Aarch64;
2891        if (bits(machInst, 27) == 0x0) {
2892            if (bits(machInst, 28) == 0x0) {
2893                if (bits(machInst, 26, 25) != 0x2) {
2894                    return new Unknown64(machInst);
2895                }
2896                if (bits(machInst, 31) == 0x0) {
2897                    switch (bits(machInst, 30, 29)) {
2898                      case 0x0:
2899                      case 0x1:
2900                      case 0x2:
2901                        return decodeSveInt(machInst);
2902                      case 0x3:
2903                        return decodeSveFp(machInst);
2904                    }
2905                } else {
2906                    return decodeSveMem(machInst);
2907                }
2908            } else if (bits(machInst, 26) == 0)
2909                // bit 28:26=100
2910                return decodeDataProcImm(machInst);
2911            else
2912                // bit 28:26=101
2913                return decodeBranchExcSys(machInst);
2914        } else if (bits(machInst, 25) == 0) {
2915            // bit 27=1, 25=0
2916            return decodeLoadsStores(machInst);
2917        } else if (bits(machInst, 26) == 0) {
2918            // bit 27:25=101
2919            return decodeDataProcReg(machInst);
2920        } else if (bits(machInst, 24) == 1 &&
2921                   bits(machInst, 31, 28) == 0xF) {
2922            return decodeGem5Ops(machInst);
2923        } else {
2924            // bit 27:25=111
2925            switch(decoderFlavour){
2926            default:
2927                return decodeFpAdvSIMD<GenericDecoder>(machInst);
2928            }
2929        }
2930    }
2931    '''
2932}};
2933