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