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