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