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