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