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