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