fp.isa revision 13753
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011, 2016-2019 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48output header {{
49
50    template<template <typename T> class Base>
51    StaticInstPtr
52    newNeonMemInst(const unsigned size,
53                   const ExtMachInst &machInst,
54                   const RegIndex dest, const RegIndex ra,
55                   const uint32_t imm, const unsigned extraMemFlags)
56    {
57        switch (size) {
58          case 0:
59            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
60          case 1:
61            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
62          case 2:
63            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
64          case 3:
65            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
66          default:
67            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
68        }
69    }
70
71    template<template <typename T> class Base>
72    StaticInstPtr
73    newNeonMixInst(const unsigned size,
74                   const ExtMachInst &machInst,
75                   const RegIndex dest, const RegIndex op1,
76                   const uint32_t step)
77    {
78        switch (size) {
79          case 0:
80            return new Base<uint8_t>(machInst, dest, op1, step);
81          case 1:
82            return new Base<uint16_t>(machInst, dest, op1, step);
83          case 2:
84            return new Base<uint32_t>(machInst, dest, op1, step);
85          case 3:
86            return new Base<uint64_t>(machInst, dest, op1, step);
87          default:
88            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
89        }
90    }
91
92}};
93
94let {{
95    header_output = '''
96    StaticInstPtr
97    decodeNeonMem(ExtMachInst machInst);
98
99    StaticInstPtr
100    decodeNeonData(ExtMachInst machInst);
101    '''
102
103    decoder_output = '''
104    StaticInstPtr
105    decodeNeonMem(ExtMachInst machInst)
106    {
107        const uint32_t b = bits(machInst, 11, 8);
108        const bool single = bits(machInst, 23);
109        const bool singleAll = single && (bits(b, 3, 2) == 3);
110        const bool load = bits(machInst, 21);
111
112        unsigned width = 0;
113
114        if (single) {
115            width = bits(b, 1, 0) + 1;
116        } else {
117            switch (bits(b, 3, 1)) {
118              case 0x0: width = 4;
119                break;
120              case 0x1: width = (b & 0x1) ? 2 : 1;
121                break;
122              case 0x2: width = 3;
123                break;
124              case 0x3: width = 1;
125                break;
126              case 0x4: width = 2;
127                break;
128              case 0x5:
129                if ((b & 0x1) == 0) {
130                    width = 1;
131                    break;
132                }
133                M5_FALLTHROUGH;
134              default:
135                return new Unknown(machInst);
136            }
137        }
138        assert(width > 0 && width <= 4);
139
140        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
141        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
142        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
143                                                 bits(machInst, 22) << 4);
144        const uint32_t type = bits(machInst, 11, 8);
145        uint32_t size = 0;
146        uint32_t align = TLB::MustBeOne;
147        unsigned inc = 1;
148        unsigned regs = 1;
149        unsigned lane = 0;
150        if (single) {
151            if (singleAll) {
152                size = bits(machInst, 7, 6);
153                bool t = bits(machInst, 5);
154                align = size | TLB::AllowUnaligned;
155                if (width == 1) {
156                    regs = t ? 2 : 1;
157                    inc = 1;
158                } else {
159                    regs = width;
160                    inc = t ? 2 : 1;
161                }
162                switch (width) {
163                  case 1:
164                  case 2:
165                    if (bits(machInst, 4))
166                        align = size + width - 1;
167                    break;
168                  case 3:
169                    break;
170                  case 4:
171                    if (size == 3) {
172                        if (bits(machInst, 4) == 0)
173                            return new Unknown(machInst);
174                        size = 2;
175                        align = 0x4;
176                    } else if (size == 2) {
177                        if (bits(machInst, 4))
178                            align = 0x3;
179                    } else {
180                        if (bits(machInst, 4))
181                            align = size + 2;
182                    }
183                    break;
184                }
185            } else {
186                size = bits(machInst, 11, 10);
187                align = size | TLB::AllowUnaligned;
188                regs = width;
189                unsigned indexAlign = bits(machInst, 7, 4);
190                // If width is 1, inc is always 1. That's overridden later.
191                switch (size) {
192                  case 0:
193                    inc = 1;
194                    lane = bits(indexAlign, 3, 1);
195                    break;
196                  case 1:
197                    inc = bits(indexAlign, 1) ? 2 : 1;
198                    lane = bits(indexAlign, 3, 2);
199                    break;
200                  case 2:
201                    inc = bits(indexAlign, 2) ? 2 : 1;
202                    lane = bits(indexAlign, 3);
203                    break;
204                }
205                // Override inc for width of 1.
206                if (width == 1) {
207                    inc = 1;
208                }
209                switch (width) {
210                  case 1:
211                    switch (size) {
212                      case 0:
213                        break;
214                      case 1:
215                        if (bits(indexAlign, 0))
216                            align = 1;
217                        break;
218                      case 2:
219                        if (bits(indexAlign, 1, 0))
220                            align = 2;
221                        break;
222                    }
223                    break;
224                  case 2:
225                    if (bits(indexAlign, 0))
226                        align = size + 1;
227                    break;
228                  case 3:
229                    break;
230                  case 4:
231                    switch (size) {
232                      case 0:
233                      case 1:
234                        if (bits(indexAlign, 0))
235                            align = size + 2;
236                        break;
237                      case 2:
238                        if (bits(indexAlign, 0))
239                            align = bits(indexAlign, 1, 0) + 2;
240                        break;
241                    }
242                    break;
243                }
244            }
245            if (size == 0x3) {
246                return new Unknown(machInst);
247            }
248        } else {
249            size = bits(machInst, 7, 6);
250            align = bits(machInst, 5, 4);
251            if (align == 0) {
252                // @align wasn't specified, so alignment can be turned off.
253                align = size | TLB::AllowUnaligned;
254            } else {
255                align = align + 2;
256            }
257            switch (width) {
258              case 1:
259                switch (type) {
260                  case 0x7: regs = 1;
261                    break;
262                  case 0xa: regs = 2;
263                    break;
264                  case 0x6: regs = 3;
265                    break;
266                  case 0x2: regs = 4;
267                    break;
268                  default:
269                    return new Unknown(machInst);
270                }
271                break;
272              case 2:
273                // Regs doesn't behave exactly as it does in the manual
274                // because they loop over regs registers twice and we break
275                // it down in the macroop.
276                switch (type) {
277                  case 0x8: regs = 2; inc = 1;
278                    break;
279                  case 0x9: regs = 2; inc = 2;
280                    break;
281                  case 0x3: regs = 4; inc = 2;
282                    break;
283                  default:
284                    return new Unknown(machInst);
285                }
286                break;
287              case 3:
288                regs = 3;
289                switch (type) {
290                  case 0x4: inc = 1;
291                    break;
292                  case 0x5: inc = 2;;
293                    break;
294                  default:
295                    return new Unknown(machInst);
296                }
297                break;
298              case 4:
299                regs = 4;
300                switch (type) {
301                  case 0: inc = 1;
302                    break;
303                  case 1: inc = 2;
304                    break;
305                  default:
306                    return new Unknown(machInst);
307                }
308                break;
309            }
310        }
311
312        if (load) {
313            // Load instructions.
314            if (single) {
315                return new VldSingle(machInst, singleAll, width, rn, vd,
316                                     regs, inc, size, align, rm, lane);
317            } else {
318                return new VldMult(machInst, width, rn, vd,
319                                   regs, inc, size, align, rm);
320            }
321        } else {
322            // Store instructions.
323            if (single) {
324                if (singleAll) {
325                    return new Unknown(machInst);
326                } else {
327                    return new VstSingle(machInst, false, width, rn, vd,
328                                         regs, inc, size, align, rm, lane);
329                }
330            } else {
331                return new VstMult(machInst, width, rn, vd,
332                                   regs, inc, size, align, rm);
333            }
334        }
335        return new Unknown(machInst);
336    }
337    '''
338
339    decoder_output += '''
340    static StaticInstPtr
341    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
342    {
343        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
344        const uint32_t a = bits(machInst, 11, 8);
345        const bool b = bits(machInst, 4);
346        const uint32_t c = bits(machInst, 21, 20);
347        const IntRegIndex vd =
348            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
349                               (bits(machInst, 22) << 4)));
350        const IntRegIndex vn =
351            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
352                               (bits(machInst, 7) << 4)));
353        const IntRegIndex vm =
354            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
355                               (bits(machInst, 5) << 4)));
356        const unsigned size = bits(machInst, 21, 20);
357        const bool q = bits(machInst, 6);
358        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
359            return new Unknown(machInst);
360        switch (a) {
361          case 0x0:
362            if (b) {
363                if (u) {
364                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
365                            q, size, machInst, vd, vn, vm);
366                } else {
367                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
368                            q, size, machInst, vd, vn, vm);
369                }
370            } else {
371                if (size == 3)
372                    return new Unknown(machInst);
373                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
374                        q, u, size, machInst, vd, vn, vm);
375            }
376          case 0x1:
377            if (!b) {
378                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
379                        q, u, size, machInst, vd, vn, vm);
380            } else {
381                if (u) {
382                    switch (c) {
383                      case 0:
384                        if (q) {
385                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
386                        } else {
387                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
388                        }
389                      case 1:
390                        if (q) {
391                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
392                        } else {
393                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
394                        }
395                      case 2:
396                        if (q) {
397                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
398                        } else {
399                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
400                        }
401                      case 3:
402                        if (q) {
403                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
404                        } else {
405                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
406                        }
407                      default:
408                        M5_UNREACHABLE;
409                    }
410                } else {
411                    switch (c) {
412                      case 0:
413                        if (q) {
414                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
415                        } else {
416                            return new VandD<uint64_t>(machInst, vd, vn, vm);
417                        }
418                      case 1:
419                        if (q) {
420                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
421                        } else {
422                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
423                        }
424                      case 2:
425                        if (vn == vm) {
426                            if (q) {
427                                return new VmovQ<uint64_t>(
428                                        machInst, vd, vn, vm);
429                            } else {
430                                return new VmovD<uint64_t>(
431                                        machInst, vd, vn, vm);
432                            }
433                        } else {
434                            if (q) {
435                                return new VorrQ<uint64_t>(
436                                        machInst, vd, vn, vm);
437                            } else {
438                                return new VorrD<uint64_t>(
439                                        machInst, vd, vn, vm);
440                            }
441                        }
442                      case 3:
443                        if (q) {
444                            return new VornQ<uint64_t>(
445                                    machInst, vd, vn, vm);
446                        } else {
447                            return new VornD<uint64_t>(
448                                    machInst, vd, vn, vm);
449                        }
450                      default:
451                        M5_UNREACHABLE;
452                    }
453                }
454            }
455          case 0x2:
456            if (b) {
457                if (u) {
458                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
459                            q, size, machInst, vd, vn, vm);
460                } else {
461                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
462                            q, size, machInst, vd, vn, vm);
463                }
464            } else {
465                if (size == 3)
466                    return new Unknown(machInst);
467                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
468                        q, u, size, machInst, vd, vn, vm);
469            }
470          case 0x3:
471            if (b) {
472                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
473                        q, u, size, machInst, vd, vn, vm);
474            } else {
475                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
476                        q, u, size, machInst, vd, vn, vm);
477            }
478          case 0x4:
479            if (b) {
480                if (u) {
481                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
482                            q, size, machInst, vd, vm, vn);
483                } else {
484                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
485                            q, size, machInst, vd, vm, vn);
486                }
487            } else {
488                return decodeNeonUSThreeReg<VshlD, VshlQ>(
489                        q, u, size, machInst, vd, vm, vn);
490            }
491          case 0x5:
492            if (b) {
493                if (u) {
494                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
495                            q, size, machInst, vd, vm, vn);
496                } else {
497                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
498                            q, size, machInst, vd, vm, vn);
499                }
500            } else {
501                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
502                        q, u, size, machInst, vd, vm, vn);
503            }
504          case 0x6:
505            if (b) {
506                return decodeNeonUSThreeReg<VminD, VminQ>(
507                        q, u, size, machInst, vd, vn, vm);
508            } else {
509                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
510                        q, u, size, machInst, vd, vn, vm);
511            }
512          case 0x7:
513            if (b) {
514                return decodeNeonUSThreeReg<VabaD, VabaQ>(
515                        q, u, size, machInst, vd, vn, vm);
516            } else {
517                if (bits(machInst, 23) == 1) {
518                    if (q) {
519                        return new Unknown(machInst);
520                    } else {
521                        return decodeNeonUSThreeUSReg<Vabdl>(
522                                u, size, machInst, vd, vn, vm);
523                    }
524                } else {
525                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
526                            q, u, size, machInst, vd, vn, vm);
527                }
528            }
529          case 0x8:
530            if (b) {
531                if (u) {
532                    return decodeNeonUThreeReg<VceqD, VceqQ>(
533                            q, size, machInst, vd, vn, vm);
534                } else {
535                    return decodeNeonUThreeReg<VtstD, VtstQ>(
536                            q, size, machInst, vd, vn, vm);
537                }
538            } else {
539                if (u) {
540                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
541                            q, size, machInst, vd, vn, vm);
542                } else {
543                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
544                            q, size, machInst, vd, vn, vm);
545                }
546            }
547          case 0x9:
548            if (b) {
549                if (u) {
550                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
551                            q, size, machInst, vd, vn, vm);
552                } else {
553                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
554                            q, size, machInst, vd, vn, vm);
555                }
556            } else {
557                if (u) {
558                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
559                            q, u, size, machInst, vd, vn, vm);
560                } else {
561                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
562                            q, u, size, machInst, vd, vn, vm);
563                }
564            }
565          case 0xa:
566            if (q)
567                return new Unknown(machInst);
568            if (b) {
569                return decodeNeonUSThreeUSReg<VpminD>(
570                        u, size, machInst, vd, vn, vm);
571            } else {
572                return decodeNeonUSThreeUSReg<VpmaxD>(
573                        u, size, machInst, vd, vn, vm);
574            }
575          case 0xb:
576            if (b) {
577                if (u || q) {
578                    return new Unknown(machInst);
579                } else {
580                    return decodeNeonUThreeUSReg<NVpaddD>(
581                            size, machInst, vd, vn, vm);
582                }
583            } else {
584                if (u) {
585                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
586                            q, size, machInst, vd, vn, vm);
587                } else {
588                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
589                            q, size, machInst, vd, vn, vm);
590                }
591            }
592          case 0xc:
593            if (b) {
594                if (!u) {
595                    if (bits(c, 1) == 0) {
596                        if (q) {
597                            return new NVfmaQFp<float>(machInst, vd, vn, vm);
598                        } else {
599                            return new NVfmaDFp<float>(machInst, vd, vn, vm);
600                        }
601                    } else {
602                        if (q) {
603                            return new NVfmsQFp<float>(machInst, vd, vn, vm);
604                        } else {
605                            return new NVfmsDFp<float>(machInst, vd, vn, vm);
606                        }
607                    }
608                }
609            } else {
610                if (u) {
611                    switch (c) {
612                      case 0x0:
613                        return new SHA256H(machInst, vd, vn, vm);
614                      case 0x1:
615                        return new SHA256H2(machInst, vd, vn, vm);
616                      case 0x2:
617                        return new SHA256SU1(machInst, vd, vn, vm);
618                      case 0x3:
619                        return new Unknown(machInst);
620                      default:
621                        M5_UNREACHABLE;
622                    }
623                } else {
624                    switch (c) {
625                      case 0x0:
626                        return new SHA1C(machInst, vd, vn, vm);
627                      case 0x1:
628                        return new SHA1P(machInst, vd, vn, vm);
629                      case 0x2:
630                        return new SHA1M(machInst, vd, vn, vm);
631                      case 0x3:
632                        return new SHA1SU0(machInst, vd, vn, vm);
633                      default:
634                        M5_UNREACHABLE;
635                    }
636                }
637            }
638            return new Unknown(machInst);
639          case 0xd:
640            if (b) {
641                if (u) {
642                    if (bits(c, 1) == 0) {
643                        if (q) {
644                            return new NVmulQFp<float>(machInst, vd, vn, vm);
645                        } else {
646                            return new NVmulDFp<float>(machInst, vd, vn, vm);
647                        }
648                    } else {
649                        return new Unknown(machInst);
650                    }
651                } else {
652                    if (bits(c, 1) == 0) {
653                        if (q) {
654                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
655                        } else {
656                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
657                        }
658                    } else {
659                        if (q) {
660                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
661                        } else {
662                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
663                        }
664                    }
665                }
666            } else {
667                if (u) {
668                    if (bits(c, 1) == 0) {
669                        if (q) {
670                            return new VpaddQFp<float>(machInst, vd, vn, vm);
671                        } else {
672                            return new VpaddDFp<float>(machInst, vd, vn, vm);
673                        }
674                    } else {
675                        if (q) {
676                            return new VabdQFp<float>(machInst, vd, vn, vm);
677                        } else {
678                            return new VabdDFp<float>(machInst, vd, vn, vm);
679                        }
680                    }
681                } else {
682                    if (bits(c, 1) == 0) {
683                        if (q) {
684                            return new VaddQFp<float>(machInst, vd, vn, vm);
685                        } else {
686                            return new VaddDFp<float>(machInst, vd, vn, vm);
687                        }
688                    } else {
689                        if (q) {
690                            return new VsubQFp<float>(machInst, vd, vn, vm);
691                        } else {
692                            return new VsubDFp<float>(machInst, vd, vn, vm);
693                        }
694                    }
695                }
696            }
697          case 0xe:
698            if (b) {
699                if (u) {
700                    if (bits(c, 1) == 0) {
701                        if (q) {
702                            return new VacgeQFp<float>(machInst, vd, vn, vm);
703                        } else {
704                            return new VacgeDFp<float>(machInst, vd, vn, vm);
705                        }
706                    } else {
707                        if (q) {
708                            return new VacgtQFp<float>(machInst, vd, vn, vm);
709                        } else {
710                            return new VacgtDFp<float>(machInst, vd, vn, vm);
711                        }
712                    }
713                } else {
714                    return new Unknown(machInst);
715                }
716            } else {
717                if (u) {
718                    if (bits(c, 1) == 0) {
719                        if (q) {
720                            return new VcgeQFp<float>(machInst, vd, vn, vm);
721                        } else {
722                            return new VcgeDFp<float>(machInst, vd, vn, vm);
723                        }
724                    } else {
725                        if (q) {
726                            return new VcgtQFp<float>(machInst, vd, vn, vm);
727                        } else {
728                            return new VcgtDFp<float>(machInst, vd, vn, vm);
729                        }
730                    }
731                } else {
732                    if (bits(c, 1) == 0) {
733                        if (q) {
734                            return new VceqQFp<float>(machInst, vd, vn, vm);
735                        } else {
736                            return new VceqDFp<float>(machInst, vd, vn, vm);
737                        }
738                    } else {
739                        return new Unknown(machInst);
740                    }
741                }
742            }
743          case 0xf:
744            if (b) {
745                if (u) {
746                    return new Unknown(machInst);
747                } else {
748                    if (bits(c, 1) == 0) {
749                        if (q) {
750                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
751                        } else {
752                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
753                        }
754                    } else {
755                        if (q) {
756                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
757                        } else {
758                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
759                        }
760                    }
761                }
762            } else {
763                if (u) {
764                    if (bits(c, 1) == 0) {
765                        if (q) {
766                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
767                        } else {
768                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
769                        }
770                    } else {
771                        if (q) {
772                            return new VpminQFp<float>(machInst, vd, vn, vm);
773                        } else {
774                            return new VpminDFp<float>(machInst, vd, vn, vm);
775                        }
776                    }
777                } else {
778                    if (bits(c, 1) == 0) {
779                        if (q) {
780                            return new VmaxQFp<float>(machInst, vd, vn, vm);
781                        } else {
782                            return new VmaxDFp<float>(machInst, vd, vn, vm);
783                        }
784                    } else {
785                        if (q) {
786                            return new VminQFp<float>(machInst, vd, vn, vm);
787                        } else {
788                            return new VminDFp<float>(machInst, vd, vn, vm);
789                        }
790                    }
791                }
792            }
793        }
794        return new Unknown(machInst);
795    }
796
797    static StaticInstPtr
798    decodeNeonOneRegModImm(ExtMachInst machInst)
799    {
800        const IntRegIndex vd =
801            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
802                               (bits(machInst, 22) << 4)));
803        const bool q = bits(machInst, 6);
804        const bool op = bits(machInst, 5);
805        const uint8_t cmode = bits(machInst, 11, 8);
806        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
807                                      bits(machInst, 24)) << 7) |
808                            (bits(machInst, 18, 16) << 4) |
809                            (bits(machInst, 3, 0) << 0);
810
811        // Check for invalid immediate encodings and return an unknown op
812        // if it happens
813        bool immValid = true;
814        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
815        if (!immValid) {
816            return new Unknown(machInst);
817        }
818
819        if (op) {
820            if (bits(cmode, 3) == 0) {
821                if (bits(cmode, 0) == 0) {
822                    if (q)
823                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
824                    else
825                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
826                } else {
827                    if (q)
828                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
829                    else
830                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
831                }
832            } else {
833                if (bits(cmode, 2) == 1) {
834                    switch (bits(cmode, 1, 0)) {
835                      case 0:
836                      case 1:
837                        if (q)
838                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
839                        else
840                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
841                      case 2:
842                        if (q)
843                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
844                        else
845                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
846                      case 3:
847                        if (q)
848                            return new Unknown(machInst);
849                        else
850                            return new Unknown(machInst);
851                    }
852                } else {
853                    if (bits(cmode, 0) == 0) {
854                        if (q)
855                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
856                        else
857                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
858                    } else {
859                        if (q)
860                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
861                        else
862                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
863                    }
864                }
865            }
866        } else {
867            if (bits(cmode, 3) == 0) {
868                if (bits(cmode, 0) == 0) {
869                    if (q)
870                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
871                    else
872                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
873                } else {
874                    if (q)
875                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
876                    else
877                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
878                }
879            } else {
880                if (bits(cmode, 2) == 1) {
881                    if (q)
882                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
883                    else
884                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
885                } else {
886                    if (bits(cmode, 0) == 0) {
887                        if (q)
888                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
889                        else
890                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
891                    } else {
892                        if (q)
893                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
894                        else
895                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
896                    }
897                }
898            }
899        }
900        return new Unknown(machInst);
901    }
902
903    static StaticInstPtr
904    decodeNeonTwoRegAndShift(ExtMachInst machInst)
905    {
906        const uint32_t a = bits(machInst, 11, 8);
907        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
908        const bool b = bits(machInst, 6);
909        const bool l = bits(machInst, 7);
910        const IntRegIndex vd =
911            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
912                               (bits(machInst, 22) << 4)));
913        const IntRegIndex vm =
914            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
915                               (bits(machInst, 5) << 4)));
916        unsigned imm6 = bits(machInst, 21, 16);
917        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
918        unsigned size = 3;
919        unsigned lShiftAmt = 0;
920        unsigned bitSel;
921        for (bitSel = 1 << 6; true; bitSel >>= 1) {
922            if (bitSel & imm)
923                break;
924            else if (!size)
925                return new Unknown(machInst);
926            size--;
927        }
928        lShiftAmt = imm6 & ~bitSel;
929        unsigned rShiftAmt = 0;
930        if (a != 0xe && a != 0xf) {
931            if (size > 2)
932                rShiftAmt = 64 - imm6;
933            else
934                rShiftAmt = 2 * (8 << size) - imm6;
935        }
936
937        switch (a) {
938          case 0x0:
939            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
940                    b, u, size, machInst, vd, vm, rShiftAmt);
941          case 0x1:
942            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
943                    b, u, size, machInst, vd, vm, rShiftAmt);
944          case 0x2:
945            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
946                    b, u, size, machInst, vd, vm, rShiftAmt);
947          case 0x3:
948            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
949                    b, u, size, machInst, vd, vm, rShiftAmt);
950          case 0x4:
951            if (u) {
952                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
953                        b, size, machInst, vd, vm, rShiftAmt);
954            } else {
955                return new Unknown(machInst);
956            }
957          case 0x5:
958            if (u) {
959                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
960                        b, size, machInst, vd, vm, lShiftAmt);
961            } else {
962                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
963                        b, size, machInst, vd, vm, lShiftAmt);
964            }
965          case 0x6:
966          case 0x7:
967            if (u) {
968                if (a == 0x6) {
969                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
970                            b, size, machInst, vd, vm, lShiftAmt);
971                } else {
972                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
973                            b, size, machInst, vd, vm, lShiftAmt);
974                }
975            } else {
976                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
977                        b, size, machInst, vd, vm, lShiftAmt);
978            }
979          case 0x8:
980            if (l) {
981                return new Unknown(machInst);
982            } else if (u) {
983                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
984                        b, size, machInst, vd, vm, rShiftAmt);
985            } else {
986                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
987                        b, size, machInst, vd, vm, rShiftAmt);
988            }
989          case 0x9:
990            if (l) {
991                return new Unknown(machInst);
992            } else if (u) {
993                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
994                        b, size, machInst, vd, vm, rShiftAmt);
995            } else {
996                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
997                        b, size, machInst, vd, vm, rShiftAmt);
998            }
999          case 0xa:
1000            if (l || b) {
1001                return new Unknown(machInst);
1002            } else {
1003                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
1004                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
1005            }
1006          case 0xe:
1007            if (l) {
1008                return new Unknown(machInst);
1009            } else {
1010                if (bits(imm6, 5) == 0)
1011                    return new Unknown(machInst);
1012                if (u) {
1013                    if (b) {
1014                        return new NVcvtu2fpQ<float>(
1015                                machInst, vd, vm, 64 - imm6);
1016                    } else {
1017                        return new NVcvtu2fpD<float>(
1018                                machInst, vd, vm, 64 - imm6);
1019                    }
1020                } else {
1021                    if (b) {
1022                        return new NVcvts2fpQ<float>(
1023                                machInst, vd, vm, 64 - imm6);
1024                    } else {
1025                        return new NVcvts2fpD<float>(
1026                                machInst, vd, vm, 64 - imm6);
1027                    }
1028                }
1029            }
1030          case 0xf:
1031            if (l) {
1032                return new Unknown(machInst);
1033            } else {
1034                if (bits(imm6, 5) == 0)
1035                    return new Unknown(machInst);
1036                if (u) {
1037                    if (b) {
1038                        return new NVcvt2ufxQ<float>(
1039                                machInst, vd, vm, 64 - imm6);
1040                    } else {
1041                        return new NVcvt2ufxD<float>(
1042                                machInst, vd, vm, 64 - imm6);
1043                    }
1044                } else {
1045                    if (b) {
1046                        return new NVcvt2sfxQ<float>(
1047                                machInst, vd, vm, 64 - imm6);
1048                    } else {
1049                        return new NVcvt2sfxD<float>(
1050                                machInst, vd, vm, 64 - imm6);
1051                    }
1052                }
1053            }
1054        }
1055        return new Unknown(machInst);
1056    }
1057
1058    static StaticInstPtr
1059    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1060    {
1061        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1062        const uint32_t a = bits(machInst, 11, 8);
1063        const IntRegIndex vd =
1064            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1065                               (bits(machInst, 22) << 4)));
1066        const IntRegIndex vn =
1067            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1068                               (bits(machInst, 7) << 4)));
1069        const IntRegIndex vm =
1070            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1071                               (bits(machInst, 5) << 4)));
1072        const unsigned size = bits(machInst, 21, 20);
1073        switch (a) {
1074          case 0x0:
1075            return decodeNeonUSThreeUSReg<Vaddl>(
1076                    u, size, machInst, vd, vn, vm);
1077          case 0x1:
1078            return decodeNeonUSThreeUSReg<Vaddw>(
1079                    u, size, machInst, vd, vn, vm);
1080          case 0x2:
1081            return decodeNeonUSThreeUSReg<Vsubl>(
1082                    u, size, machInst, vd, vn, vm);
1083          case 0x3:
1084            return decodeNeonUSThreeUSReg<Vsubw>(
1085                    u, size, machInst, vd, vn, vm);
1086          case 0x4:
1087            if (u) {
1088                return decodeNeonUThreeUSReg<Vraddhn>(
1089                        size, machInst, vd, vn, vm);
1090            } else {
1091                return decodeNeonUThreeUSReg<Vaddhn>(
1092                        size, machInst, vd, vn, vm);
1093            }
1094          case 0x5:
1095            return decodeNeonUSThreeUSReg<Vabal>(
1096                    u, size, machInst, vd, vn, vm);
1097          case 0x6:
1098            if (u) {
1099                return decodeNeonUThreeUSReg<Vrsubhn>(
1100                        size, machInst, vd, vn, vm);
1101            } else {
1102                return decodeNeonUThreeUSReg<Vsubhn>(
1103                        size, machInst, vd, vn, vm);
1104            }
1105          case 0x7:
1106            if (bits(machInst, 23)) {
1107                return decodeNeonUSThreeUSReg<Vabdl>(
1108                        u, size, machInst, vd, vn, vm);
1109            } else {
1110                return decodeNeonUSThreeReg<VabdD, VabdQ>(
1111                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
1112            }
1113          case 0x8:
1114            return decodeNeonUSThreeUSReg<Vmlal>(
1115                    u, size, machInst, vd, vn, vm);
1116          case 0xa:
1117            return decodeNeonUSThreeUSReg<Vmlsl>(
1118                    u, size, machInst, vd, vn, vm);
1119          case 0x9:
1120            if (u) {
1121                return new Unknown(machInst);
1122            } else {
1123                return decodeNeonSThreeUSReg<Vqdmlal>(
1124                        size, machInst, vd, vn, vm);
1125            }
1126          case 0xb:
1127            if (u) {
1128                return new Unknown(machInst);
1129            } else {
1130                return decodeNeonSThreeUSReg<Vqdmlsl>(
1131                        size, machInst, vd, vn, vm);
1132            }
1133          case 0xc:
1134            return decodeNeonUSThreeUSReg<Vmull>(
1135                    u, size, machInst, vd, vn, vm);
1136          case 0xd:
1137            if (u) {
1138                return new Unknown(machInst);
1139            } else {
1140                return decodeNeonSThreeUSReg<Vqdmull>(
1141                        size, machInst, vd, vn, vm);
1142            }
1143          case 0xe:
1144            return decodeNeonUThreeUSReg<Vmullp>(
1145                    size, machInst, vd, vn, vm);
1146        }
1147        return new Unknown(machInst);
1148    }
1149
1150    static StaticInstPtr
1151    decodeNeonTwoRegScalar(ExtMachInst machInst)
1152    {
1153        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1154        const uint32_t a = bits(machInst, 11, 8);
1155        const unsigned size = bits(machInst, 21, 20);
1156        const IntRegIndex vd =
1157            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1158                               (bits(machInst, 22) << 4)));
1159        const IntRegIndex vn =
1160            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1161                               (bits(machInst, 7) << 4)));
1162        const IntRegIndex vm = (size == 2) ?
1163            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1164            (IntRegIndex)(2 * bits(machInst, 2, 0));
1165        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1166            (bits(machInst, 3) | (bits(machInst, 5) << 1));
1167        switch (a) {
1168          case 0x0:
1169            if (u) {
1170                switch (size) {
1171                  case 1:
1172                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1173                  case 2:
1174                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1175                  default:
1176                    return new Unknown(machInst);
1177                }
1178            } else {
1179                switch (size) {
1180                  case 1:
1181                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1182                  case 2:
1183                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1184                  default:
1185                    return new Unknown(machInst);
1186                }
1187            }
1188          case 0x1:
1189            if (u)
1190                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1191            else
1192                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1193          case 0x4:
1194            if (u) {
1195                switch (size) {
1196                  case 1:
1197                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1198                  case 2:
1199                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1200                  default:
1201                    return new Unknown(machInst);
1202                }
1203            } else {
1204                switch (size) {
1205                  case 1:
1206                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1207                  case 2:
1208                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1209                  default:
1210                    return new Unknown(machInst);
1211                }
1212            }
1213          case 0x5:
1214            if (u)
1215                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1216            else
1217                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1218          case 0x2:
1219            if (u) {
1220                switch (size) {
1221                  case 1:
1222                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1223                  case 2:
1224                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1225                  default:
1226                    return new Unknown(machInst);
1227                }
1228            } else {
1229                switch (size) {
1230                  case 1:
1231                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1232                  case 2:
1233                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1234                  default:
1235                    return new Unknown(machInst);
1236                }
1237            }
1238          case 0x6:
1239            if (u) {
1240                switch (size) {
1241                  case 1:
1242                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1243                  case 2:
1244                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1245                  default:
1246                    return new Unknown(machInst);
1247                }
1248            } else {
1249                switch (size) {
1250                  case 1:
1251                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1252                  case 2:
1253                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1254                  default:
1255                    return new Unknown(machInst);
1256                }
1257            }
1258          case 0x3:
1259            if (u) {
1260                return new Unknown(machInst);
1261            } else {
1262                switch (size) {
1263                  case 1:
1264                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1265                  case 2:
1266                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1267                  default:
1268                    return new Unknown(machInst);
1269                }
1270            }
1271          case 0x7:
1272            if (u) {
1273                return new Unknown(machInst);
1274            } else {
1275                switch (size) {
1276                  case 1:
1277                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1278                  case 2:
1279                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1280                  default:
1281                    return new Unknown(machInst);
1282                }
1283            }
1284          case 0x8:
1285            if (u) {
1286                switch (size) {
1287                  case 1:
1288                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1289                  case 2:
1290                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1291                  default:
1292                    return new Unknown(machInst);
1293                }
1294            } else {
1295                switch (size) {
1296                  case 1:
1297                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1298                  case 2:
1299                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1300                  default:
1301                    return new Unknown(machInst);
1302                }
1303            }
1304          case 0x9:
1305            if (u)
1306                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1307            else
1308                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1309          case 0xa:
1310            if (u) {
1311                switch (size) {
1312                  case 1:
1313                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1314                  case 2:
1315                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1316                  default:
1317                    return new Unknown(machInst);
1318                }
1319            } else {
1320                switch (size) {
1321                  case 1:
1322                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1323                  case 2:
1324                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1325                  default:
1326                    return new Unknown(machInst);
1327                }
1328            }
1329          case 0xb:
1330            if (u) {
1331                return new Unknown(machInst);
1332            } else {
1333                if (u) {
1334                    switch (size) {
1335                      case 1:
1336                        return new Vqdmulls<uint16_t>(
1337                                machInst, vd, vn, vm, index);
1338                      case 2:
1339                        return new Vqdmulls<uint32_t>(
1340                                machInst, vd, vn, vm, index);
1341                      default:
1342                        return new Unknown(machInst);
1343                    }
1344                } else {
1345                    switch (size) {
1346                      case 1:
1347                        return new Vqdmulls<int16_t>(
1348                                machInst, vd, vn, vm, index);
1349                      case 2:
1350                        return new Vqdmulls<int32_t>(
1351                                machInst, vd, vn, vm, index);
1352                      default:
1353                        return new Unknown(machInst);
1354                    }
1355                }
1356            }
1357          case 0xc:
1358            if (u) {
1359                switch (size) {
1360                  case 1:
1361                    return new VqdmulhsQ<int16_t>(
1362                            machInst, vd, vn, vm, index);
1363                  case 2:
1364                    return new VqdmulhsQ<int32_t>(
1365                            machInst, vd, vn, vm, index);
1366                  default:
1367                    return new Unknown(machInst);
1368                }
1369            } else {
1370                switch (size) {
1371                  case 1:
1372                    return new VqdmulhsD<int16_t>(
1373                            machInst, vd, vn, vm, index);
1374                  case 2:
1375                    return new VqdmulhsD<int32_t>(
1376                            machInst, vd, vn, vm, index);
1377                  default:
1378                    return new Unknown(machInst);
1379                }
1380            }
1381          case 0xd:
1382            if (u) {
1383                switch (size) {
1384                  case 1:
1385                    return new VqrdmulhsQ<int16_t>(
1386                            machInst, vd, vn, vm, index);
1387                  case 2:
1388                    return new VqrdmulhsQ<int32_t>(
1389                            machInst, vd, vn, vm, index);
1390                  default:
1391                    return new Unknown(machInst);
1392                }
1393            } else {
1394                switch (size) {
1395                  case 1:
1396                    return new VqrdmulhsD<int16_t>(
1397                            machInst, vd, vn, vm, index);
1398                  case 2:
1399                    return new VqrdmulhsD<int32_t>(
1400                            machInst, vd, vn, vm, index);
1401                  default:
1402                    return new Unknown(machInst);
1403                }
1404            }
1405        }
1406        return new Unknown(machInst);
1407    }
1408
1409    static StaticInstPtr
1410    decodeNeonTwoRegMisc(ExtMachInst machInst)
1411    {
1412        const uint32_t a = bits(machInst, 17, 16);
1413        const uint32_t b = bits(machInst, 10, 6);
1414        const bool q = bits(machInst, 6);
1415        const IntRegIndex vd =
1416            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1417                               (bits(machInst, 22) << 4)));
1418        const IntRegIndex vm =
1419            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1420                               (bits(machInst, 5) << 4)));
1421        const unsigned size = bits(machInst, 19, 18);
1422        switch (a) {
1423          case 0x0:
1424            switch (bits(b, 4, 1)) {
1425              case 0x0:
1426                switch (size) {
1427                  case 0:
1428                    if (q) {
1429                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
1430                    } else {
1431                        return new NVrev64D<uint8_t>(machInst, vd, vm);
1432                    }
1433                  case 1:
1434                    if (q) {
1435                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
1436                    } else {
1437                        return new NVrev64D<uint16_t>(machInst, vd, vm);
1438                    }
1439                  case 2:
1440                    if (q) {
1441                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
1442                    } else {
1443                        return new NVrev64D<uint32_t>(machInst, vd, vm);
1444                    }
1445                  default:
1446                    return new Unknown(machInst);
1447                }
1448              case 0x1:
1449                switch (size) {
1450                  case 0:
1451                    if (q) {
1452                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
1453                    } else {
1454                        return new NVrev32D<uint8_t>(machInst, vd, vm);
1455                    }
1456                  case 1:
1457                    if (q) {
1458                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1459                    } else {
1460                        return new NVrev32D<uint16_t>(machInst, vd, vm);
1461                    }
1462                  default:
1463                    return new Unknown(machInst);
1464                }
1465              case 0x2:
1466                if (size != 0) {
1467                    return new Unknown(machInst);
1468                } else if (q) {
1469                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
1470                } else {
1471                    return new NVrev16D<uint8_t>(machInst, vd, vm);
1472                }
1473              case 0x4:
1474                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1475                        q, size, machInst, vd, vm);
1476              case 0x5:
1477                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1478                        q, size, machInst, vd, vm);
1479              case 0x6:
1480                if (q == 0) {
1481                    return new AESE(machInst, vd, vd, vm);
1482                } else {
1483                    return new AESD(machInst, vd, vd, vm);
1484                }
1485              case 0x7:
1486                if (q == 0) {
1487                    return new AESMC(machInst, vd, vm);
1488                } else {
1489                    return new AESIMC(machInst, vd, vm);
1490                }
1491              case 0x8:
1492                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1493                        q, size, machInst, vd, vm);
1494              case 0x9:
1495                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1496                        q, size, machInst, vd, vm);
1497              case 0xa:
1498                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1499                        q, size, machInst, vd, vm);
1500              case 0xb:
1501                if (q)
1502                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
1503                else
1504                    return new NVmvnD<uint64_t>(machInst, vd, vm);
1505              case 0xc:
1506                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1507                        q, size, machInst, vd, vm);
1508              case 0xd:
1509                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1510                        q, size, machInst, vd, vm);
1511              case 0xe:
1512                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1513                        q, size, machInst, vd, vm);
1514              case 0xf:
1515                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1516                        q, size, machInst, vd, vm);
1517              default:
1518                return new Unknown(machInst);
1519            }
1520          case 0x1:
1521            switch (bits(b, 3, 1)) {
1522              case 0x0:
1523                if (bits(b, 4)) {
1524                    if (q) {
1525                        return new NVcgtQFp<float>(machInst, vd, vm);
1526                    } else {
1527                        return new NVcgtDFp<float>(machInst, vd, vm);
1528                    }
1529                } else {
1530                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1531                            q, size, machInst, vd, vm);
1532                }
1533              case 0x1:
1534                if (bits(b, 4)) {
1535                    if (q) {
1536                        return new NVcgeQFp<float>(machInst, vd, vm);
1537                    } else {
1538                        return new NVcgeDFp<float>(machInst, vd, vm);
1539                    }
1540                } else {
1541                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1542                            q, size, machInst, vd, vm);
1543                }
1544              case 0x2:
1545                if (bits(b, 4)) {
1546                    if (q) {
1547                        return new NVceqQFp<float>(machInst, vd, vm);
1548                    } else {
1549                        return new NVceqDFp<float>(machInst, vd, vm);
1550                    }
1551                } else {
1552                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1553                            q, size, machInst, vd, vm);
1554                }
1555              case 0x3:
1556                if (bits(b, 4)) {
1557                    if (q) {
1558                        return new NVcleQFp<float>(machInst, vd, vm);
1559                    } else {
1560                        return new NVcleDFp<float>(machInst, vd, vm);
1561                    }
1562                } else {
1563                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1564                            q, size, machInst, vd, vm);
1565                }
1566              case 0x4:
1567                if (bits(b, 4)) {
1568                    if (q) {
1569                        return new NVcltQFp<float>(machInst, vd, vm);
1570                    } else {
1571                        return new NVcltDFp<float>(machInst, vd, vm);
1572                    }
1573                } else {
1574                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1575                            q, size, machInst, vd, vm);
1576                }
1577              case 0x5:
1578                if (q) {
1579                    return new SHA1H(machInst, vd, vm);
1580                } else {
1581                    return new Unknown(machInst);
1582                }
1583              case 0x6:
1584                if (bits(machInst, 10)) {
1585                    if (q)
1586                        return new NVabsQFp<float>(machInst, vd, vm);
1587                    else
1588                        return new NVabsDFp<float>(machInst, vd, vm);
1589                } else {
1590                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1591                            q, size, machInst, vd, vm);
1592                }
1593              case 0x7:
1594                if (bits(machInst, 10)) {
1595                    if (q)
1596                        return new NVnegQFp<float>(machInst, vd, vm);
1597                    else
1598                        return new NVnegDFp<float>(machInst, vd, vm);
1599                } else {
1600                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1601                            q, size, machInst, vd, vm);
1602                }
1603              default:
1604                return new Unknown64(machInst);
1605            }
1606          case 0x2:
1607            switch (bits(b, 4, 1)) {
1608              case 0x0:
1609                if (q)
1610                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1611                else
1612                    return new NVswpD<uint64_t>(machInst, vd, vm);
1613              case 0x1:
1614                return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1615                        q, size, machInst, vd, vm);
1616              case 0x2:
1617                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1618                        q, size, machInst, vd, vm);
1619              case 0x3:
1620                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1621                        q, size, machInst, vd, vm);
1622              case 0x4:
1623                if (b == 0x8) {
1624                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1625                            size, machInst, vd, vm);
1626                } else {
1627                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1628                            size, machInst, vd, vm);
1629                }
1630              case 0x5:
1631                if (q) {
1632                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1633                            size, machInst, vd, vm);
1634                } else {
1635                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1636                            size, machInst, vd, vm);
1637                }
1638              case 0x6:
1639                if (b == 0xc) {
1640                    return decodeNeonSTwoShiftUSReg<NVshll>(
1641                            size, machInst, vd, vm, 8 << size);
1642                } else {
1643                    return new Unknown(machInst);
1644                }
1645              case 0x7:
1646                if (q) {
1647                    return new SHA256SU0(machInst, vd, vm);
1648                } else {
1649                    return new SHA1SU1(machInst, vd, vm);
1650                }
1651              case 0xc:
1652              case 0xe:
1653                if (b == 0x18) {
1654                    if (size != 1 || (vm % 2))
1655                        return new Unknown(machInst);
1656                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1657                } else if (b == 0x1c) {
1658                    if (size != 1 || (vd % 2))
1659                        return new Unknown(machInst);
1660                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1661                } else {
1662                    return new Unknown(machInst);
1663                }
1664              default:
1665                return new Unknown(machInst);
1666            }
1667          case 0x3:
1668            if (bits(b, 4, 3) == 0x3) {
1669                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1670                    return new Unknown(machInst);
1671                } else {
1672                    if (bits(b, 2)) {
1673                        if (bits(b, 1)) {
1674                            if (q) {
1675                                return new NVcvt2ufxQ<float>(
1676                                        machInst, vd, vm, 0);
1677                            } else {
1678                                return new NVcvt2ufxD<float>(
1679                                        machInst, vd, vm, 0);
1680                            }
1681                        } else {
1682                            if (q) {
1683                                return new NVcvt2sfxQ<float>(
1684                                        machInst, vd, vm, 0);
1685                            } else {
1686                                return new NVcvt2sfxD<float>(
1687                                        machInst, vd, vm, 0);
1688                            }
1689                        }
1690                    } else {
1691                        if (bits(b, 1)) {
1692                            if (q) {
1693                                return new NVcvtu2fpQ<float>(
1694                                        machInst, vd, vm, 0);
1695                            } else {
1696                                return new NVcvtu2fpD<float>(
1697                                        machInst, vd, vm, 0);
1698                            }
1699                        } else {
1700                            if (q) {
1701                                return new NVcvts2fpQ<float>(
1702                                        machInst, vd, vm, 0);
1703                            } else {
1704                                return new NVcvts2fpD<float>(
1705                                        machInst, vd, vm, 0);
1706                            }
1707                        }
1708                    }
1709                }
1710            } else if ((b & 0x1a) == 0x10) {
1711                if (bits(b, 2)) {
1712                    if (q) {
1713                        return new NVrecpeQFp<float>(machInst, vd, vm);
1714                    } else {
1715                        return new NVrecpeDFp<float>(machInst, vd, vm);
1716                    }
1717                } else {
1718                    if (q) {
1719                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1720                    } else {
1721                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1722                    }
1723                }
1724            } else if ((b & 0x1a) == 0x12) {
1725                if (bits(b, 2)) {
1726                    if (q) {
1727                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1728                    } else {
1729                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1730                    }
1731                } else {
1732                    if (q) {
1733                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1734                    } else {
1735                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1736                    }
1737                }
1738            } else {
1739                return new Unknown(machInst);
1740            }
1741        }
1742        return new Unknown(machInst);
1743    }
1744
1745    StaticInstPtr
1746    decodeNeonData(ExtMachInst machInst)
1747    {
1748        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1749        const uint32_t a = bits(machInst, 23, 19);
1750        const uint32_t b = bits(machInst, 11, 8);
1751        const uint32_t c = bits(machInst, 7, 4);
1752        if (bits(a, 4) == 0) {
1753            return decodeNeonThreeRegistersSameLength(machInst);
1754        } else if ((c & 0x9) == 1) {
1755            if ((a & 0x7) == 0) {
1756                return decodeNeonOneRegModImm(machInst);
1757            } else {
1758                return decodeNeonTwoRegAndShift(machInst);
1759            }
1760        } else if ((c & 0x9) == 9) {
1761            return decodeNeonTwoRegAndShift(machInst);
1762        } else if (bits(a, 2, 1) != 0x3) {
1763            if ((c & 0x5) == 0) {
1764                return decodeNeonThreeRegDiffLengths(machInst);
1765            } else if ((c & 0x5) == 4) {
1766                return decodeNeonTwoRegScalar(machInst);
1767            }
1768        } else if ((a & 0x16) == 0x16) {
1769            const IntRegIndex vd =
1770                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1771                                   (bits(machInst, 22) << 4)));
1772            const IntRegIndex vn =
1773                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1774                                   (bits(machInst, 7) << 4)));
1775            const IntRegIndex vm =
1776                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1777                                   (bits(machInst, 5) << 4)));
1778            if (!u) {
1779                if (bits(c, 0) == 0) {
1780                    unsigned imm4 = bits(machInst, 11, 8);
1781                    bool q = bits(machInst, 6);
1782                    if (imm4 >= 16 && !q)
1783                        return new Unknown(machInst);
1784                    if (q) {
1785                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1786                    } else {
1787                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1788                    }
1789                }
1790            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1791                return decodeNeonTwoRegMisc(machInst);
1792            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1793                unsigned length = bits(machInst, 9, 8) + 1;
1794                if ((uint32_t)vn / 2 + length > 32)
1795                    return new Unknown(machInst);
1796                if (bits(machInst, 6) == 0) {
1797                    switch (length) {
1798                      case 1:
1799                        return new NVtbl1(machInst, vd, vn, vm);
1800                      case 2:
1801                        return new NVtbl2(machInst, vd, vn, vm);
1802                      case 3:
1803                        return new NVtbl3(machInst, vd, vn, vm);
1804                      case 4:
1805                        return new NVtbl4(machInst, vd, vn, vm);
1806                    }
1807                } else {
1808                    switch (length) {
1809                      case 1:
1810                        return new NVtbx1(machInst, vd, vn, vm);
1811                      case 2:
1812                        return new NVtbx2(machInst, vd, vn, vm);
1813                      case 3:
1814                        return new NVtbx3(machInst, vd, vn, vm);
1815                      case 4:
1816                        return new NVtbx4(machInst, vd, vn, vm);
1817                    }
1818                }
1819            } else if (b == 0xc && (c & 0x9) == 0) {
1820                unsigned imm4 = bits(machInst, 19, 16);
1821                if (bits(imm4, 2, 0) == 0)
1822                    return new Unknown(machInst);
1823                unsigned size = 0;
1824                while ((imm4 & 0x1) == 0) {
1825                    size++;
1826                    imm4 >>= 1;
1827                }
1828                unsigned index = imm4 >> 1;
1829                const bool q = bits(machInst, 6);
1830                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1831                        q, size, machInst, vd, vm, index);
1832            }
1833        }
1834        return new Unknown(machInst);
1835    }
1836    '''
1837}};
1838
1839def format ThumbNeonMem() {{
1840    decode_block = '''
1841    return decodeNeonMem(machInst);
1842    '''
1843}};
1844
1845def format ThumbNeonData() {{
1846    decode_block = '''
1847    return decodeNeonData(machInst);
1848    '''
1849}};
1850
1851let {{
1852    header_output = '''
1853    StaticInstPtr
1854    decodeExtensionRegLoadStore(ExtMachInst machInst);
1855    '''
1856    decoder_output = '''
1857    StaticInstPtr
1858    decodeExtensionRegLoadStore(ExtMachInst machInst)
1859    {
1860        const uint32_t opcode = bits(machInst, 24, 20);
1861        const uint32_t offset = bits(machInst, 7, 0);
1862        const bool single = (bits(machInst, 8) == 0);
1863        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1864        RegIndex vd;
1865        if (single) {
1866            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1867                                      bits(machInst, 22));
1868        } else {
1869            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1870                                      (bits(machInst, 22) << 5));
1871        }
1872        switch (bits(opcode, 4, 3)) {
1873          case 0x0:
1874            if (bits(opcode, 4, 1) == 0x2 &&
1875                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1876                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1877                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1878                    break;
1879                }
1880                const IntRegIndex rt =
1881                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1882                const IntRegIndex rt2 =
1883                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1884                const bool op = bits(machInst, 20);
1885                uint32_t vm;
1886                if (single) {
1887                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1888                } else {
1889                    vm = (bits(machInst, 3, 0) << 1) |
1890                         (bits(machInst, 5) << 5);
1891                }
1892                if (op) {
1893                    return new Vmov2Core2Reg(machInst, rt, rt2,
1894                                             (IntRegIndex)vm);
1895                } else {
1896                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1897                                             rt, rt2);
1898                }
1899            }
1900            break;
1901          case 0x1:
1902            {
1903                if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1904                    break;
1905                }
1906                switch (bits(opcode, 1, 0)) {
1907                  case 0x0:
1908                    return new VLdmStm(machInst, rn, vd, single,
1909                                       true, false, false, offset);
1910                  case 0x1:
1911                    return new VLdmStm(machInst, rn, vd, single,
1912                                       true, false, true, offset);
1913                  case 0x2:
1914                    return new VLdmStm(machInst, rn, vd, single,
1915                                       true, true, false, offset);
1916                  case 0x3:
1917                    // If rn == sp, then this is called vpop.
1918                    return new VLdmStm(machInst, rn, vd, single,
1919                                       true, true, true, offset);
1920                  default:
1921                    M5_UNREACHABLE;
1922                }
1923            }
1924          case 0x2:
1925            if (bits(opcode, 1, 0) == 0x2) {
1926                // If rn == sp, then this is called vpush.
1927                return new VLdmStm(machInst, rn, vd, single,
1928                                   false, true, false, offset);
1929            } else if (bits(opcode, 1, 0) == 0x3) {
1930                return new VLdmStm(machInst, rn, vd, single,
1931                                   false, true, true, offset);
1932            }
1933            M5_FALLTHROUGH;
1934          case 0x3:
1935            const bool up = (bits(machInst, 23) == 1);
1936            const uint32_t imm = bits(machInst, 7, 0) << 2;
1937            if (single) {
1938                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1939                                          (bits(machInst, 22)));
1940            } else {
1941                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1942                                          (bits(machInst, 22) << 5));
1943            }
1944            if (bits(opcode, 1, 0) == 0x0) {
1945                if (single) {
1946                    if (up) {
1947                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1948                    } else {
1949                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1950                    }
1951                } else {
1952                    if (up) {
1953                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1954                                               rn, up, imm);
1955                    } else {
1956                        return new %(vstr_d)s(machInst, vd, vd + 1,
1957                                              rn, up, imm);
1958                    }
1959                }
1960            } else if (bits(opcode, 1, 0) == 0x1) {
1961                if (single) {
1962                    if (up) {
1963                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1964                    } else {
1965                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1966                    }
1967                } else {
1968                    if (up) {
1969                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1970                                               rn, up, imm);
1971                    } else {
1972                        return new %(vldr_d)s(machInst, vd, vd + 1,
1973                                              rn, up, imm);
1974                    }
1975                }
1976            }
1977        }
1978        return new Unknown(machInst);
1979    }
1980    ''' % {
1981        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1982        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1983        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1984        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1985        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1986        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1987        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1988        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1989    }
1990}};
1991
1992def format ExtensionRegLoadStore() {{
1993    decode_block = '''
1994    return decodeExtensionRegLoadStore(machInst);
1995    '''
1996}};
1997
1998let {{
1999    header_output = '''
2000    StaticInstPtr
2001    decodeShortFpTransfer(ExtMachInst machInst);
2002    '''
2003    decoder_output = '''
2004    IntRegIndex decodeFpVd(ExtMachInst machInst, uint32_t size, bool isInt)
2005    {
2006        if (!isInt and size == 3) {
2007            return (IntRegIndex)((bits(machInst, 22) << 5) |
2008                               (bits(machInst, 15, 12) << 1));
2009        } else {
2010            return (IntRegIndex)(bits(machInst, 22) |
2011                              (bits(machInst, 15, 12) << 1));
2012        }
2013    }
2014    IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2015    {
2016        if (!isInt and size == 3) {
2017            return (IntRegIndex)((bits(machInst, 5) << 5) |
2018                               (bits(machInst, 3, 0) << 1));
2019        } else {
2020            return (IntRegIndex)(bits(machInst, 5) |
2021                              (bits(machInst, 3, 0) << 1));
2022        }
2023    }
2024    StaticInstPtr
2025    decodeShortFpTransfer(ExtMachInst machInst)
2026    {
2027        const uint32_t l = bits(machInst, 20);
2028        const uint32_t c = bits(machInst, 8);
2029        const uint32_t a = bits(machInst, 23, 21);
2030        const uint32_t b = bits(machInst, 6, 5);
2031        const uint32_t o1 = bits(machInst, 18);
2032        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2033            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2034            // Determine if this is backported aarch64 FP instruction
2035            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
2036            const bool b23 = bits(machInst, 23);
2037            const bool b21_b19 = bits(machInst, 21, 19) == 0x7;
2038            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
2039            const uint32_t size = bits(machInst, 9, 8);
2040            const bool op3 = bits(machInst, 6);
2041            const bool b4 = bits(machInst, 4) == 0x0;
2042            const uint32_t rm = bits(machInst, 17, 16);
2043            IntRegIndex vd = decodeFpVd(machInst, size, false);
2044            IntRegIndex vm = decodeFpVm(machInst, size, false);
2045            IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2046            if (b31_b24 && b23 && b21_b19 && b11_b9 && op3 && b4) {
2047                if (o1 == 0) {
2048                    // VINT* Integer Rounding Instruction
2049                    if (size == 3) {
2050                        switch(rm) {
2051                            case 0x0:
2052                            return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2053                                                                true);
2054                            case 0x1:
2055                            return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2056                                                                true);
2057                            case 0x2:
2058                            return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
2059                                                                true);
2060                            case 0x3:
2061                            return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
2062                                                                true);
2063                            default: return new Unknown(machInst);
2064                        }
2065                    } else {
2066                        switch(rm) {
2067                            case 0x0:
2068                            return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
2069                                                                false);
2070                            case 0x1:
2071                            return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2072                                                                false);
2073                            case 0x2:
2074                            return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2075                                                                false);
2076                            case 0x3:
2077                            return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2078                                                                false);
2079                            default: return new Unknown(machInst);
2080                        }
2081                    }
2082                } else {
2083                    const bool op = bits(machInst, 7);
2084                    switch(rm) {
2085                      case 0x0:
2086                        switch(size) {
2087                          case 0x0:
2088                            return new Unknown(machInst);
2089                          case 0x1:
2090                            return new FailUnimplemented(
2091                                "vcvta.u32.f16", machInst);
2092                          case 0x2:
2093                            if (op) {
2094                                return new VcvtaFpSIntS(machInst, vdInt, vm);
2095                            } else {
2096                                return new VcvtaFpUIntS(machInst, vdInt, vm);
2097                            }
2098                          case 0x3:
2099                            if (op) {
2100                                return new VcvtaFpSIntD(machInst, vdInt, vm);
2101                            } else {
2102                                return new VcvtaFpUIntD(machInst, vdInt, vm);
2103                            }
2104                          default: return new Unknown(machInst);
2105                        }
2106                      case 0x1:
2107                        switch(size) {
2108                          case 0x0:
2109                            return new Unknown(machInst);
2110                          case 0x1:
2111                            return new FailUnimplemented(
2112                                "vcvtn.u32.f16", machInst);
2113                          case 0x2:
2114                            if (op) {
2115                                return new VcvtnFpSIntS(machInst, vdInt, vm);
2116                            } else {
2117                                return new VcvtnFpUIntS(machInst, vdInt, vm);
2118                            }
2119                          case 0x3:
2120                            if (op) {
2121                                return new VcvtnFpSIntD(machInst, vdInt, vm);
2122                            } else {
2123                                return new VcvtnFpUIntD(machInst, vdInt, vm);
2124                            }
2125                          default: return new Unknown(machInst);
2126                        }
2127                      case 0x2:
2128                        switch(size) {
2129                          case 0x0:
2130                            return new Unknown(machInst);
2131                          case 0x1:
2132                            return new FailUnimplemented(
2133                                "vcvtp.u32.f16", machInst);
2134                          case 0x2:
2135                            if (op) {
2136                                return new VcvtpFpSIntS(machInst, vdInt, vm);
2137                            } else {
2138                                return new VcvtpFpUIntS(machInst, vdInt, vm);
2139                            }
2140                          case 0x3:
2141                            if (op) {
2142                                return new VcvtpFpSIntD(machInst, vdInt, vm);
2143                            } else {
2144                                return new VcvtpFpUIntD(machInst, vdInt, vm);
2145                            }
2146                          default: return new Unknown(machInst);
2147                        }
2148                      case 0x3:
2149                        switch(size) {
2150                          case 0x0:
2151                            return new Unknown(machInst);
2152                          case 0x1:
2153                            return new FailUnimplemented(
2154                                "vcvtm.u32.f16", machInst);
2155                          case 0x2:
2156                            if (op) {
2157                                return new VcvtmFpSIntS(machInst, vdInt, vm);
2158                            } else {
2159                                return new VcvtmFpUIntS(machInst, vdInt, vm);
2160                            }
2161                          case 0x3:
2162                            if (op) {
2163                                return new VcvtmFpSIntD(machInst, vdInt, vm);
2164                            } else {
2165                                return new VcvtmFpUIntD(machInst, vdInt, vm);
2166                            }
2167                          default: return new Unknown(machInst);
2168                        }
2169                      default: return new Unknown(machInst);
2170                    }
2171                }
2172            } else if (b31_b24 && !b23 && b11_b9 && !op3 && b4){
2173                // VSEL* floating point conditional select
2174
2175                ConditionCode cond;
2176                switch(bits(machInst, 21, 20)) {
2177                  case 0x0: cond = COND_EQ; break;
2178                  case 0x1: cond = COND_VS; break;
2179                  case 0x2: cond = COND_GE; break;
2180                  case 0x3: cond = COND_GT; break;
2181                }
2182
2183                if (size == 3) {
2184                      const IntRegIndex vn =
2185                          (IntRegIndex)((bits(machInst, 7) << 5) |
2186                                       (bits(machInst, 19, 16) << 1));
2187                    return new VselD(machInst, vd, vn, vm, cond);
2188                } else {
2189                      const IntRegIndex vn =
2190                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2191                                        bits(machInst, 7));
2192                      return new VselS(machInst, vd, vn, vm, cond);
2193                }
2194            } else {
2195                return new Unknown(machInst);
2196            }
2197        }
2198        if (l == 0 && c == 0) {
2199            if (a == 0) {
2200                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2201                                    bits(machInst, 7);
2202                const IntRegIndex rt =
2203                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2204                if (bits(machInst, 20) == 1) {
2205                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2206                } else {
2207                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2208                }
2209            } else if (a == 0x7) {
2210                const IntRegIndex rt =
2211                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2212                uint32_t reg = bits(machInst, 19, 16);
2213                uint32_t specReg;
2214                switch (reg) {
2215                  case 0:
2216                    specReg = MISCREG_FPSID;
2217                    break;
2218                  case 1:
2219                    specReg = MISCREG_FPSCR;
2220                    break;
2221                  case 6:
2222                    specReg = MISCREG_MVFR1;
2223                    break;
2224                  case 7:
2225                    specReg = MISCREG_MVFR0;
2226                    break;
2227                  case 8:
2228                    specReg = MISCREG_FPEXC;
2229                    break;
2230                  default:
2231                    return new Unknown(machInst);
2232                }
2233                if (specReg == MISCREG_FPSCR) {
2234                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2235                } else {
2236                    uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2237                        reg, a, bits(machInst, 7, 5));
2238                    return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2239                }
2240            }
2241        } else if (l == 0 && c == 1) {
2242            if (bits(a, 2) == 0) {
2243                uint32_t vd = (bits(machInst, 7) << 5) |
2244                              (bits(machInst, 19, 16) << 1);
2245                // Handle accessing each single precision half of the vector.
2246                vd += bits(machInst, 21);
2247                const IntRegIndex rt =
2248                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2249                if (bits(machInst, 22) == 1) {
2250                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2251                                            rt, bits(machInst, 6, 5));
2252                } else if (bits(machInst, 5) == 1) {
2253                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2254                                            rt, bits(machInst, 6));
2255                } else if (bits(machInst, 6) == 0) {
2256                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2257                } else {
2258                    return new Unknown(machInst);
2259                }
2260            } else if (bits(b, 1) == 0) {
2261                bool q = bits(machInst, 21);
2262                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2263                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2264                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2265                IntRegIndex rt = (IntRegIndex)(uint32_t)
2266                    bits(machInst, 15, 12);
2267                if (q) {
2268                    switch (be) {
2269                      case 0:
2270                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2271                      case 1:
2272                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2273                      case 2:
2274                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2275                      case 3:
2276                        return new Unknown(machInst);
2277                    }
2278                } else {
2279                    switch (be) {
2280                      case 0:
2281                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2282                      case 1:
2283                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2284                      case 2:
2285                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2286                      case 3:
2287                        return new Unknown(machInst);
2288                    }
2289                }
2290            }
2291        } else if (l == 1 && c == 0) {
2292            if (a == 0) {
2293                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2294                                    bits(machInst, 7);
2295                const IntRegIndex rt =
2296                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2297                if (bits(machInst, 20) == 1) {
2298                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2299                } else {
2300                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2301                }
2302            } else if (a == 7) {
2303                const IntRegIndex rt =
2304                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2305                uint32_t reg = bits(machInst, 19, 16);
2306                uint32_t specReg;
2307                switch (reg) {
2308                  case 0:
2309                    specReg = MISCREG_FPSID;
2310                    break;
2311                  case 1:
2312                    specReg = MISCREG_FPSCR;
2313                    break;
2314                  case 6:
2315                    specReg = MISCREG_MVFR1;
2316                    break;
2317                  case 7:
2318                    specReg = MISCREG_MVFR0;
2319                    break;
2320                  case 8:
2321                    specReg = MISCREG_FPEXC;
2322                    break;
2323                  default:
2324                    return new Unknown(machInst);
2325                }
2326                if (rt == 0xf) {
2327                    if (specReg == MISCREG_FPSCR) {
2328                        return new VmrsApsrFpscr(machInst);
2329                    } else {
2330                        return new Unknown(machInst);
2331                    }
2332                } else if (specReg == MISCREG_FPSCR) {
2333                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2334                } else {
2335                    uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2336                        reg, a, bits(machInst, 7, 5));
2337                    return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2338                }
2339            }
2340        } else {
2341            uint32_t vd = (bits(machInst, 7) << 5) |
2342                          (bits(machInst, 19, 16) << 1);
2343            // Handle indexing into each single precision half of the vector.
2344            vd += bits(machInst, 21);
2345            uint32_t index;
2346            const IntRegIndex rt =
2347                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2348            const bool u = (bits(machInst, 23) == 1);
2349            if (bits(machInst, 22) == 1) {
2350                index = bits(machInst, 6, 5);
2351                if (u) {
2352                    return new VmovRegCoreUB(machInst, rt,
2353                                             (IntRegIndex)vd, index);
2354                } else {
2355                    return new VmovRegCoreSB(machInst, rt,
2356                                             (IntRegIndex)vd, index);
2357                }
2358            } else if (bits(machInst, 5) == 1) {
2359                index = bits(machInst, 6);
2360                if (u) {
2361                    return new VmovRegCoreUH(machInst, rt,
2362                                             (IntRegIndex)vd, index);
2363                } else {
2364                    return new VmovRegCoreSH(machInst, rt,
2365                                             (IntRegIndex)vd, index);
2366                }
2367            } else if (bits(machInst, 6) == 0 && !u) {
2368                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2369            } else {
2370                return new Unknown(machInst);
2371            }
2372        }
2373        return new Unknown(machInst);
2374    }
2375    '''
2376}};
2377
2378def format ShortFpTransfer() {{
2379    decode_block = '''
2380    return decodeShortFpTransfer(machInst);
2381    '''
2382}};
2383
2384let {{
2385    header_output = '''
2386    StaticInstPtr
2387    decodeVfpData(ExtMachInst machInst);
2388    '''
2389    decoder_output = '''
2390    StaticInstPtr
2391    decodeVfpData(ExtMachInst machInst)
2392    {
2393        const uint32_t opc1 = bits(machInst, 23, 20);
2394        const uint32_t opc2 = bits(machInst, 19, 16);
2395        const uint32_t opc3 = bits(machInst, 7, 6);
2396        //const uint32_t opc4 = bits(machInst, 3, 0);
2397        const bool single = (bits(machInst, 8) == 0);
2398        // Used to select between vcmp and vcmpe.
2399        const bool e = (bits(machInst, 7) == 1);
2400        IntRegIndex vd;
2401        IntRegIndex vm;
2402        IntRegIndex vn;
2403        if (single) {
2404            vd = (IntRegIndex)(bits(machInst, 22) |
2405                    (bits(machInst, 15, 12) << 1));
2406            vm = (IntRegIndex)(bits(machInst, 5) |
2407                    (bits(machInst, 3, 0) << 1));
2408            vn = (IntRegIndex)(bits(machInst, 7) |
2409                    (bits(machInst, 19, 16) << 1));
2410        } else {
2411            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2412                    (bits(machInst, 15, 12) << 1));
2413            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2414                    (bits(machInst, 3, 0) << 1));
2415            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2416                    (bits(machInst, 19, 16) << 1));
2417        }
2418        switch (opc1 & 0xb /* 1011 */) {
2419          case 0x0:
2420            if (bits(machInst, 6) == 0) {
2421                if (single) {
2422                    return decodeVfpRegRegRegOp<VmlaS>(
2423                            machInst, vd, vn, vm, false);
2424                } else {
2425                    return decodeVfpRegRegRegOp<VmlaD>(
2426                            machInst, vd, vn, vm, true);
2427                }
2428            } else {
2429                if (single) {
2430                    return decodeVfpRegRegRegOp<VmlsS>(
2431                            machInst, vd, vn, vm, false);
2432                } else {
2433                    return decodeVfpRegRegRegOp<VmlsD>(
2434                            machInst, vd, vn, vm, true);
2435                }
2436            }
2437          case 0x1:
2438            if (bits(machInst, 6) == 1) {
2439                if (single) {
2440                    return decodeVfpRegRegRegOp<VnmlaS>(
2441                            machInst, vd, vn, vm, false);
2442                } else {
2443                    return decodeVfpRegRegRegOp<VnmlaD>(
2444                            machInst, vd, vn, vm, true);
2445                }
2446            } else {
2447                if (single) {
2448                    return decodeVfpRegRegRegOp<VnmlsS>(
2449                            machInst, vd, vn, vm, false);
2450                } else {
2451                    return decodeVfpRegRegRegOp<VnmlsD>(
2452                            machInst, vd, vn, vm, true);
2453                }
2454            }
2455          case 0x2:
2456            if ((opc3 & 0x1) == 0) {
2457                if (single) {
2458                    return decodeVfpRegRegRegOp<VmulS>(
2459                            machInst, vd, vn, vm, false);
2460                } else {
2461                    return decodeVfpRegRegRegOp<VmulD>(
2462                            machInst, vd, vn, vm, true);
2463                }
2464            } else {
2465                if (single) {
2466                    return decodeVfpRegRegRegOp<VnmulS>(
2467                            machInst, vd, vn, vm, false);
2468                } else {
2469                    return decodeVfpRegRegRegOp<VnmulD>(
2470                            machInst, vd, vn, vm, true);
2471                }
2472            }
2473          case 0x3:
2474            if ((opc3 & 0x1) == 0) {
2475                if (single) {
2476                    return decodeVfpRegRegRegOp<VaddS>(
2477                            machInst, vd, vn, vm, false);
2478                } else {
2479                    return decodeVfpRegRegRegOp<VaddD>(
2480                            machInst, vd, vn, vm, true);
2481                }
2482            } else {
2483                if (single) {
2484                    return decodeVfpRegRegRegOp<VsubS>(
2485                            machInst, vd, vn, vm, false);
2486                } else {
2487                    return decodeVfpRegRegRegOp<VsubD>(
2488                            machInst, vd, vn, vm, true);
2489                }
2490            }
2491          case 0x8:
2492            if ((opc3 & 0x1) == 0) {
2493                if (single) {
2494                    return decodeVfpRegRegRegOp<VdivS>(
2495                            machInst, vd, vn, vm, false);
2496                } else {
2497                    return decodeVfpRegRegRegOp<VdivD>(
2498                            machInst, vd, vn, vm, true);
2499                }
2500            }
2501            break;
2502          case 0x9:
2503            if ((opc3 & 0x1) == 0) {
2504                if (single) {
2505                    return decodeVfpRegRegRegOp<VfnmaS>(
2506                            machInst, vd, vn, vm, false);
2507                } else {
2508                    return decodeVfpRegRegRegOp<VfnmaD>(
2509                            machInst, vd, vn, vm, true);
2510                }
2511            } else {
2512                if (single) {
2513                    return decodeVfpRegRegRegOp<VfnmsS>(
2514                            machInst, vd, vn, vm, false);
2515                } else {
2516                    return decodeVfpRegRegRegOp<VfnmsD>(
2517                            machInst, vd, vn, vm, true);
2518                }
2519            }
2520            break;
2521          case 0xa:
2522            if ((opc3 & 0x1) == 0) {
2523                if (single) {
2524                    return decodeVfpRegRegRegOp<VfmaS>(
2525                            machInst, vd, vn, vm, false);
2526                } else {
2527                    return decodeVfpRegRegRegOp<VfmaD>(
2528                            machInst, vd, vn, vm, true);
2529                }
2530            } else {
2531                if (single) {
2532                    return decodeVfpRegRegRegOp<VfmsS>(
2533                            machInst, vd, vn, vm, false);
2534                } else {
2535                    return decodeVfpRegRegRegOp<VfmsD>(
2536                            machInst, vd, vn, vm, true);
2537                }
2538            }
2539            break;
2540          case 0xb:
2541            if ((opc3 & 0x1) == 0) {
2542                const uint32_t baseImm =
2543                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2544                if (single) {
2545                    uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32);
2546                    return decodeVfpRegImmOp<VmovImmS>(
2547                            machInst, vd, imm, false);
2548                } else {
2549                    uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64);
2550                    return decodeVfpRegImmOp<VmovImmD>(
2551                            machInst, vd, imm, true);
2552                }
2553            }
2554            switch (opc2) {
2555              case 0x0:
2556                if (opc3 == 1) {
2557                    if (single) {
2558                        return decodeVfpRegRegOp<VmovRegS>(
2559                                machInst, vd, vm, false);
2560                    } else {
2561                        return decodeVfpRegRegOp<VmovRegD>(
2562                                machInst, vd, vm, true);
2563                    }
2564                } else {
2565                    if (single) {
2566                        return decodeVfpRegRegOp<VabsS>(
2567                                machInst, vd, vm, false);
2568                    } else {
2569                        return decodeVfpRegRegOp<VabsD>(
2570                                machInst, vd, vm, true);
2571                    }
2572                }
2573              case 0x1:
2574                if (opc3 == 1) {
2575                    if (single) {
2576                        return decodeVfpRegRegOp<VnegS>(
2577                                machInst, vd, vm, false);
2578                    } else {
2579                        return decodeVfpRegRegOp<VnegD>(
2580                                machInst, vd, vm, true);
2581                    }
2582                } else {
2583                    if (single) {
2584                        return decodeVfpRegRegOp<VsqrtS>(
2585                                machInst, vd, vm, false);
2586                    } else {
2587                        return decodeVfpRegRegOp<VsqrtD>(
2588                                machInst, vd, vm, true);
2589                    }
2590                }
2591              case 0x2:
2592              case 0x3:
2593                {
2594                    const bool toHalf = bits(machInst, 16);
2595                    const bool top = bits(machInst, 7);
2596                    if (top) {
2597                        if (toHalf) {
2598                            return new VcvtFpSFpHT(machInst, vd, vm);
2599                        } else {
2600                            return new VcvtFpHTFpS(machInst, vd, vm);
2601                        }
2602                    } else {
2603                        if (toHalf) {
2604                            return new VcvtFpSFpHB(machInst, vd, vm);
2605                        } else {
2606                            return new VcvtFpHBFpS(machInst, vd, vm);
2607                        }
2608                    }
2609                }
2610              case 0x4:
2611                if (single) {
2612                    if (e) {
2613                        return new VcmpeS(machInst, vd, vm);
2614                    } else {
2615                        return new VcmpS(machInst, vd, vm);
2616                    }
2617                } else {
2618                    if (e) {
2619                        return new VcmpeD(machInst, vd, vm);
2620                    } else {
2621                        return new VcmpD(machInst, vd, vm);
2622                    }
2623                }
2624              case 0x5:
2625                if (single) {
2626                    if (e) {
2627                        return new VcmpeZeroS(machInst, vd, 0);
2628                    } else {
2629                        return new VcmpZeroS(machInst, vd, 0);
2630                    }
2631                } else {
2632                    if (e) {
2633                        return new VcmpeZeroD(machInst, vd, 0);
2634                    } else {
2635                        return new VcmpZeroD(machInst, vd, 0);
2636                    }
2637                }
2638              case 0x7:
2639                if (opc3 == 0x3) {
2640                    if (single) {
2641                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2642                                (bits(machInst, 15, 12) << 1));
2643                        return new VcvtFpSFpD(machInst, vd, vm);
2644                    } else {
2645                        vd = (IntRegIndex)(bits(machInst, 22) |
2646                                (bits(machInst, 15, 12) << 1));
2647                        return new VcvtFpDFpS(machInst, vd, vm);
2648                    }
2649                }
2650                break;
2651              case 0x8:
2652                if (bits(machInst, 7) == 0) {
2653                    if (single) {
2654                        return new VcvtUIntFpS(machInst, vd, vm);
2655                    } else {
2656                        vm = (IntRegIndex)(bits(machInst, 5) |
2657                                (bits(machInst, 3, 0) << 1));
2658                        return new VcvtUIntFpD(machInst, vd, vm);
2659                    }
2660                } else {
2661                    if (single) {
2662                        return new VcvtSIntFpS(machInst, vd, vm);
2663                    } else {
2664                        vm = (IntRegIndex)(bits(machInst, 5) |
2665                                (bits(machInst, 3, 0) << 1));
2666                        return new VcvtSIntFpD(machInst, vd, vm);
2667                    }
2668                }
2669              case 0xa:
2670                {
2671                    const bool half = (bits(machInst, 7) == 0);
2672                    const uint32_t imm = bits(machInst, 5) |
2673                                         (bits(machInst, 3, 0) << 1);
2674                    const uint32_t size =
2675                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2676                    if (single) {
2677                        if (half) {
2678                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2679                        } else {
2680                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2681                        }
2682                    } else {
2683                        if (half) {
2684                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2685                        } else {
2686                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2687                        }
2688                    }
2689                }
2690              case 0xb:
2691                {
2692                    const bool half = (bits(machInst, 7) == 0);
2693                    const uint32_t imm = bits(machInst, 5) |
2694                                         (bits(machInst, 3, 0) << 1);
2695                    const uint32_t size =
2696                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2697                    if (single) {
2698                        if (half) {
2699                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2700                        } else {
2701                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2702                        }
2703                    } else {
2704                        if (half) {
2705                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2706                        } else {
2707                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2708                        }
2709                    }
2710                }
2711              case 0xc:
2712                if (bits(machInst, 7) == 0) {
2713                    if (single) {
2714                        return new VcvtFpUIntSR(machInst, vd, vm);
2715                    } else {
2716                        vd = (IntRegIndex)(bits(machInst, 22) |
2717                                (bits(machInst, 15, 12) << 1));
2718                        return new VcvtFpUIntDR(machInst, vd, vm);
2719                    }
2720                } else {
2721                    if (single) {
2722                        return new VcvtFpUIntS(machInst, vd, vm);
2723                    } else {
2724                        vd = (IntRegIndex)(bits(machInst, 22) |
2725                                (bits(machInst, 15, 12) << 1));
2726                        return new VcvtFpUIntD(machInst, vd, vm);
2727                    }
2728                }
2729              case 0xd:
2730                if (bits(machInst, 7) == 0) {
2731                    if (single) {
2732                        return new VcvtFpSIntSR(machInst, vd, vm);
2733                    } else {
2734                        vd = (IntRegIndex)(bits(machInst, 22) |
2735                                (bits(machInst, 15, 12) << 1));
2736                        return new VcvtFpSIntDR(machInst, vd, vm);
2737                    }
2738                } else {
2739                    if (single) {
2740                        return new VcvtFpSIntS(machInst, vd, vm);
2741                    } else {
2742                        vd = (IntRegIndex)(bits(machInst, 22) |
2743                                (bits(machInst, 15, 12) << 1));
2744                        return new VcvtFpSIntD(machInst, vd, vm);
2745                    }
2746                }
2747              case 0xe:
2748                {
2749                    const bool half = (bits(machInst, 7) == 0);
2750                    const uint32_t imm = bits(machInst, 5) |
2751                                         (bits(machInst, 3, 0) << 1);
2752                    const uint32_t size =
2753                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2754                    if (single) {
2755                        if (half) {
2756                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2757                        } else {
2758                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2759                        }
2760                    } else {
2761                        if (half) {
2762                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2763                        } else {
2764                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2765                        }
2766                    }
2767                }
2768              case 0xf:
2769                {
2770                    const bool half = (bits(machInst, 7) == 0);
2771                    const uint32_t imm = bits(machInst, 5) |
2772                                         (bits(machInst, 3, 0) << 1);
2773                    const uint32_t size =
2774                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2775                    if (single) {
2776                        if (half) {
2777                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2778                        } else {
2779                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2780                        }
2781                    } else {
2782                        if (half) {
2783                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2784                        } else {
2785                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2786                        }
2787                    }
2788                }
2789            }
2790            break;
2791        }
2792        return new Unknown(machInst);
2793    }
2794    '''
2795}};
2796
2797def format VfpData() {{
2798    decode_block = '''
2799    return decodeVfpData(machInst);
2800    '''
2801}};
2802