fp.isa revision 11671:520509f3e66c
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011,2016 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                // Fall through on purpose.
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                    }
408                } else {
409                    switch (c) {
410                      case 0:
411                        if (q) {
412                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
413                        } else {
414                            return new VandD<uint64_t>(machInst, vd, vn, vm);
415                        }
416                      case 1:
417                        if (q) {
418                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
419                        } else {
420                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
421                        }
422                      case 2:
423                        if (vn == vm) {
424                            if (q) {
425                                return new VmovQ<uint64_t>(
426                                        machInst, vd, vn, vm);
427                            } else {
428                                return new VmovD<uint64_t>(
429                                        machInst, vd, vn, vm);
430                            }
431                        } else {
432                            if (q) {
433                                return new VorrQ<uint64_t>(
434                                        machInst, vd, vn, vm);
435                            } else {
436                                return new VorrD<uint64_t>(
437                                        machInst, vd, vn, vm);
438                            }
439                        }
440                      case 3:
441                        if (q) {
442                            return new VornQ<uint64_t>(
443                                    machInst, vd, vn, vm);
444                        } else {
445                            return new VornD<uint64_t>(
446                                    machInst, vd, vn, vm);
447                        }
448                    }
449                }
450            }
451          case 0x2:
452            if (b) {
453                if (u) {
454                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
455                            q, size, machInst, vd, vn, vm);
456                } else {
457                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
458                            q, size, machInst, vd, vn, vm);
459                }
460            } else {
461                if (size == 3)
462                    return new Unknown(machInst);
463                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
464                        q, u, size, machInst, vd, vn, vm);
465            }
466          case 0x3:
467            if (b) {
468                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
469                        q, u, size, machInst, vd, vn, vm);
470            } else {
471                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
472                        q, u, size, machInst, vd, vn, vm);
473            }
474          case 0x4:
475            if (b) {
476                if (u) {
477                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
478                            q, size, machInst, vd, vm, vn);
479                } else {
480                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
481                            q, size, machInst, vd, vm, vn);
482                }
483            } else {
484                return decodeNeonUSThreeReg<VshlD, VshlQ>(
485                        q, u, size, machInst, vd, vm, vn);
486            }
487          case 0x5:
488            if (b) {
489                if (u) {
490                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
491                            q, size, machInst, vd, vm, vn);
492                } else {
493                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
494                            q, size, machInst, vd, vm, vn);
495                }
496            } else {
497                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
498                        q, u, size, machInst, vd, vm, vn);
499            }
500          case 0x6:
501            if (b) {
502                return decodeNeonUSThreeReg<VminD, VminQ>(
503                        q, u, size, machInst, vd, vn, vm);
504            } else {
505                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
506                        q, u, size, machInst, vd, vn, vm);
507            }
508          case 0x7:
509            if (b) {
510                return decodeNeonUSThreeReg<VabaD, VabaQ>(
511                        q, u, size, machInst, vd, vn, vm);
512            } else {
513                if (bits(machInst, 23) == 1) {
514                    if (q) {
515                        return new Unknown(machInst);
516                    } else {
517                        return decodeNeonUSThreeUSReg<Vabdl>(
518                                u, size, machInst, vd, vn, vm);
519                    }
520                } else {
521                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
522                            q, u, size, machInst, vd, vn, vm);
523                }
524            }
525          case 0x8:
526            if (b) {
527                if (u) {
528                    return decodeNeonUThreeReg<VceqD, VceqQ>(
529                            q, size, machInst, vd, vn, vm);
530                } else {
531                    return decodeNeonUThreeReg<VtstD, VtstQ>(
532                            q, size, machInst, vd, vn, vm);
533                }
534            } else {
535                if (u) {
536                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
537                            q, size, machInst, vd, vn, vm);
538                } else {
539                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
540                            q, size, machInst, vd, vn, vm);
541                }
542            }
543          case 0x9:
544            if (b) {
545                if (u) {
546                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
547                            q, size, machInst, vd, vn, vm);
548                } else {
549                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
550                            q, size, machInst, vd, vn, vm);
551                }
552            } else {
553                if (u) {
554                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
555                            q, u, size, machInst, vd, vn, vm);
556                } else {
557                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
558                            q, u, size, machInst, vd, vn, vm);
559                }
560            }
561          case 0xa:
562            if (q)
563                return new Unknown(machInst);
564            if (b) {
565                return decodeNeonUSThreeUSReg<VpminD>(
566                        u, size, machInst, vd, vn, vm);
567            } else {
568                return decodeNeonUSThreeUSReg<VpmaxD>(
569                        u, size, machInst, vd, vn, vm);
570            }
571          case 0xb:
572            if (b) {
573                if (u || q) {
574                    return new Unknown(machInst);
575                } else {
576                    return decodeNeonUThreeUSReg<NVpaddD>(
577                            size, machInst, vd, vn, vm);
578                }
579            } else {
580                if (u) {
581                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582                            q, size, machInst, vd, vn, vm);
583                } else {
584                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585                            q, size, machInst, vd, vn, vm);
586                }
587            }
588          case 0xc:
589            if (b) {
590                if (!u) {
591                    if (bits(c, 1) == 0) {
592                        if (q) {
593                            return new NVfmaQFp<float>(machInst, vd, vn, vm);
594                        } else {
595                            return new NVfmaDFp<float>(machInst, vd, vn, vm);
596                        }
597                    } else {
598                        if (q) {
599                            return new NVfmsQFp<float>(machInst, vd, vn, vm);
600                        } else {
601                            return new NVfmsDFp<float>(machInst, vd, vn, vm);
602                        }
603                    }
604                }
605            }
606            return new Unknown(machInst);
607          case 0xd:
608            if (b) {
609                if (u) {
610                    if (bits(c, 1) == 0) {
611                        if (q) {
612                            return new NVmulQFp<float>(machInst, vd, vn, vm);
613                        } else {
614                            return new NVmulDFp<float>(machInst, vd, vn, vm);
615                        }
616                    } else {
617                        return new Unknown(machInst);
618                    }
619                } else {
620                    if (bits(c, 1) == 0) {
621                        if (q) {
622                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
623                        } else {
624                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
625                        }
626                    } else {
627                        if (q) {
628                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
629                        } else {
630                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
631                        }
632                    }
633                }
634            } else {
635                if (u) {
636                    if (bits(c, 1) == 0) {
637                        if (q) {
638                            return new VpaddQFp<float>(machInst, vd, vn, vm);
639                        } else {
640                            return new VpaddDFp<float>(machInst, vd, vn, vm);
641                        }
642                    } else {
643                        if (q) {
644                            return new VabdQFp<float>(machInst, vd, vn, vm);
645                        } else {
646                            return new VabdDFp<float>(machInst, vd, vn, vm);
647                        }
648                    }
649                } else {
650                    if (bits(c, 1) == 0) {
651                        if (q) {
652                            return new VaddQFp<float>(machInst, vd, vn, vm);
653                        } else {
654                            return new VaddDFp<float>(machInst, vd, vn, vm);
655                        }
656                    } else {
657                        if (q) {
658                            return new VsubQFp<float>(machInst, vd, vn, vm);
659                        } else {
660                            return new VsubDFp<float>(machInst, vd, vn, vm);
661                        }
662                    }
663                }
664            }
665          case 0xe:
666            if (b) {
667                if (u) {
668                    if (bits(c, 1) == 0) {
669                        if (q) {
670                            return new VacgeQFp<float>(machInst, vd, vn, vm);
671                        } else {
672                            return new VacgeDFp<float>(machInst, vd, vn, vm);
673                        }
674                    } else {
675                        if (q) {
676                            return new VacgtQFp<float>(machInst, vd, vn, vm);
677                        } else {
678                            return new VacgtDFp<float>(machInst, vd, vn, vm);
679                        }
680                    }
681                } else {
682                    return new Unknown(machInst);
683                }
684            } else {
685                if (u) {
686                    if (bits(c, 1) == 0) {
687                        if (q) {
688                            return new VcgeQFp<float>(machInst, vd, vn, vm);
689                        } else {
690                            return new VcgeDFp<float>(machInst, vd, vn, vm);
691                        }
692                    } else {
693                        if (q) {
694                            return new VcgtQFp<float>(machInst, vd, vn, vm);
695                        } else {
696                            return new VcgtDFp<float>(machInst, vd, vn, vm);
697                        }
698                    }
699                } else {
700                    if (bits(c, 1) == 0) {
701                        if (q) {
702                            return new VceqQFp<float>(machInst, vd, vn, vm);
703                        } else {
704                            return new VceqDFp<float>(machInst, vd, vn, vm);
705                        }
706                    } else {
707                        return new Unknown(machInst);
708                    }
709                }
710            }
711          case 0xf:
712            if (b) {
713                if (u) {
714                    return new Unknown(machInst);
715                } else {
716                    if (bits(c, 1) == 0) {
717                        if (q) {
718                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
719                        } else {
720                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
721                        }
722                    } else {
723                        if (q) {
724                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
725                        } else {
726                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
727                        }
728                    }
729                }
730            } else {
731                if (u) {
732                    if (bits(c, 1) == 0) {
733                        if (q) {
734                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
735                        } else {
736                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
737                        }
738                    } else {
739                        if (q) {
740                            return new VpminQFp<float>(machInst, vd, vn, vm);
741                        } else {
742                            return new VpminDFp<float>(machInst, vd, vn, vm);
743                        }
744                    }
745                } else {
746                    if (bits(c, 1) == 0) {
747                        if (q) {
748                            return new VmaxQFp<float>(machInst, vd, vn, vm);
749                        } else {
750                            return new VmaxDFp<float>(machInst, vd, vn, vm);
751                        }
752                    } else {
753                        if (q) {
754                            return new VminQFp<float>(machInst, vd, vn, vm);
755                        } else {
756                            return new VminDFp<float>(machInst, vd, vn, vm);
757                        }
758                    }
759                }
760            }
761        }
762        return new Unknown(machInst);
763    }
764
765    static StaticInstPtr
766    decodeNeonOneRegModImm(ExtMachInst machInst)
767    {
768        const IntRegIndex vd =
769            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
770                               (bits(machInst, 22) << 4)));
771        const bool q = bits(machInst, 6);
772        const bool op = bits(machInst, 5);
773        const uint8_t cmode = bits(machInst, 11, 8);
774        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
775                                      bits(machInst, 24)) << 7) |
776                            (bits(machInst, 18, 16) << 4) |
777                            (bits(machInst, 3, 0) << 0);
778
779        // Check for invalid immediate encodings and return an unknown op
780        // if it happens
781        bool immValid = true;
782        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
783        if (!immValid) {
784            return new Unknown(machInst);
785        }
786
787        if (op) {
788            if (bits(cmode, 3) == 0) {
789                if (bits(cmode, 0) == 0) {
790                    if (q)
791                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
792                    else
793                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794                } else {
795                    if (q)
796                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
797                    else
798                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
799                }
800            } else {
801                if (bits(cmode, 2) == 1) {
802                    switch (bits(cmode, 1, 0)) {
803                      case 0:
804                      case 1:
805                        if (q)
806                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
807                        else
808                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
809                      case 2:
810                        if (q)
811                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
812                        else
813                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
814                      case 3:
815                        if (q)
816                            return new Unknown(machInst);
817                        else
818                            return new Unknown(machInst);
819                    }
820                } else {
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                }
833            }
834        } else {
835            if (bits(cmode, 3) == 0) {
836                if (bits(cmode, 0) == 0) {
837                    if (q)
838                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
839                    else
840                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
841                } else {
842                    if (q)
843                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
844                    else
845                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
846                }
847            } else {
848                if (bits(cmode, 2) == 1) {
849                    if (q)
850                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
851                    else
852                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
853                } else {
854                    if (bits(cmode, 0) == 0) {
855                        if (q)
856                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
857                        else
858                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
859                    } else {
860                        if (q)
861                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
862                        else
863                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
864                    }
865                }
866            }
867        }
868        return new Unknown(machInst);
869    }
870
871    static StaticInstPtr
872    decodeNeonTwoRegAndShift(ExtMachInst machInst)
873    {
874        const uint32_t a = bits(machInst, 11, 8);
875        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
876        const bool b = bits(machInst, 6);
877        const bool l = bits(machInst, 7);
878        const IntRegIndex vd =
879            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
880                               (bits(machInst, 22) << 4)));
881        const IntRegIndex vm =
882            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
883                               (bits(machInst, 5) << 4)));
884        unsigned imm6 = bits(machInst, 21, 16);
885        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
886        unsigned size = 3;
887        unsigned lShiftAmt = 0;
888        unsigned bitSel;
889        for (bitSel = 1 << 6; true; bitSel >>= 1) {
890            if (bitSel & imm)
891                break;
892            else if (!size)
893                return new Unknown(machInst);
894            size--;
895        }
896        lShiftAmt = imm6 & ~bitSel;
897        unsigned rShiftAmt = 0;
898        if (a != 0xe && a != 0xf) {
899            if (size > 2)
900                rShiftAmt = 64 - imm6;
901            else
902                rShiftAmt = 2 * (8 << size) - imm6;
903        }
904
905        switch (a) {
906          case 0x0:
907            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
908                    b, u, size, machInst, vd, vm, rShiftAmt);
909          case 0x1:
910            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
911                    b, u, size, machInst, vd, vm, rShiftAmt);
912          case 0x2:
913            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
914                    b, u, size, machInst, vd, vm, rShiftAmt);
915          case 0x3:
916            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
917                    b, u, size, machInst, vd, vm, rShiftAmt);
918          case 0x4:
919            if (u) {
920                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
921                        b, size, machInst, vd, vm, rShiftAmt);
922            } else {
923                return new Unknown(machInst);
924            }
925          case 0x5:
926            if (u) {
927                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
928                        b, size, machInst, vd, vm, lShiftAmt);
929            } else {
930                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
931                        b, size, machInst, vd, vm, lShiftAmt);
932            }
933          case 0x6:
934          case 0x7:
935            if (u) {
936                if (a == 0x6) {
937                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
938                            b, size, machInst, vd, vm, lShiftAmt);
939                } else {
940                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
941                            b, size, machInst, vd, vm, lShiftAmt);
942                }
943            } else {
944                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
945                        b, size, machInst, vd, vm, lShiftAmt);
946            }
947          case 0x8:
948            if (l) {
949                return new Unknown(machInst);
950            } else if (u) {
951                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
952                        b, size, machInst, vd, vm, rShiftAmt);
953            } else {
954                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
955                        b, size, machInst, vd, vm, rShiftAmt);
956            }
957          case 0x9:
958            if (l) {
959                return new Unknown(machInst);
960            } else if (u) {
961                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
962                        b, size, machInst, vd, vm, rShiftAmt);
963            } else {
964                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
965                        b, size, machInst, vd, vm, rShiftAmt);
966            }
967          case 0xa:
968            if (l || b) {
969                return new Unknown(machInst);
970            } else {
971                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
972                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
973            }
974          case 0xe:
975            if (l) {
976                return new Unknown(machInst);
977            } else {
978                if (bits(imm6, 5) == 0)
979                    return new Unknown(machInst);
980                if (u) {
981                    if (b) {
982                        return new NVcvtu2fpQ<float>(
983                                machInst, vd, vm, 64 - imm6);
984                    } else {
985                        return new NVcvtu2fpD<float>(
986                                machInst, vd, vm, 64 - imm6);
987                    }
988                } else {
989                    if (b) {
990                        return new NVcvts2fpQ<float>(
991                                machInst, vd, vm, 64 - imm6);
992                    } else {
993                        return new NVcvts2fpD<float>(
994                                machInst, vd, vm, 64 - imm6);
995                    }
996                }
997            }
998          case 0xf:
999            if (l) {
1000                return new Unknown(machInst);
1001            } else {
1002                if (bits(imm6, 5) == 0)
1003                    return new Unknown(machInst);
1004                if (u) {
1005                    if (b) {
1006                        return new NVcvt2ufxQ<float>(
1007                                machInst, vd, vm, 64 - imm6);
1008                    } else {
1009                        return new NVcvt2ufxD<float>(
1010                                machInst, vd, vm, 64 - imm6);
1011                    }
1012                } else {
1013                    if (b) {
1014                        return new NVcvt2sfxQ<float>(
1015                                machInst, vd, vm, 64 - imm6);
1016                    } else {
1017                        return new NVcvt2sfxD<float>(
1018                                machInst, vd, vm, 64 - imm6);
1019                    }
1020                }
1021            }
1022        }
1023        return new Unknown(machInst);
1024    }
1025
1026    static StaticInstPtr
1027    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1028    {
1029        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1030        const uint32_t a = bits(machInst, 11, 8);
1031        const IntRegIndex vd =
1032            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1033                               (bits(machInst, 22) << 4)));
1034        const IntRegIndex vn =
1035            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1036                               (bits(machInst, 7) << 4)));
1037        const IntRegIndex vm =
1038            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1039                               (bits(machInst, 5) << 4)));
1040        const unsigned size = bits(machInst, 21, 20);
1041        switch (a) {
1042          case 0x0:
1043            return decodeNeonUSThreeUSReg<Vaddl>(
1044                    u, size, machInst, vd, vn, vm);
1045          case 0x1:
1046            return decodeNeonUSThreeUSReg<Vaddw>(
1047                    u, size, machInst, vd, vn, vm);
1048          case 0x2:
1049            return decodeNeonUSThreeUSReg<Vsubl>(
1050                    u, size, machInst, vd, vn, vm);
1051          case 0x3:
1052            return decodeNeonUSThreeUSReg<Vsubw>(
1053                    u, size, machInst, vd, vn, vm);
1054          case 0x4:
1055            if (u) {
1056                return decodeNeonUThreeUSReg<Vraddhn>(
1057                        size, machInst, vd, vn, vm);
1058            } else {
1059                return decodeNeonUThreeUSReg<Vaddhn>(
1060                        size, machInst, vd, vn, vm);
1061            }
1062          case 0x5:
1063            return decodeNeonUSThreeUSReg<Vabal>(
1064                    u, size, machInst, vd, vn, vm);
1065          case 0x6:
1066            if (u) {
1067                return decodeNeonUThreeUSReg<Vrsubhn>(
1068                        size, machInst, vd, vn, vm);
1069            } else {
1070                return decodeNeonUThreeUSReg<Vsubhn>(
1071                        size, machInst, vd, vn, vm);
1072            }
1073          case 0x7:
1074            if (bits(machInst, 23)) {
1075                return decodeNeonUSThreeUSReg<Vabdl>(
1076                        u, size, machInst, vd, vn, vm);
1077            } else {
1078                return decodeNeonUSThreeReg<VabdD, VabdQ>(
1079                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
1080            }
1081          case 0x8:
1082            return decodeNeonUSThreeUSReg<Vmlal>(
1083                    u, size, machInst, vd, vn, vm);
1084          case 0xa:
1085            return decodeNeonUSThreeUSReg<Vmlsl>(
1086                    u, size, machInst, vd, vn, vm);
1087          case 0x9:
1088            if (u) {
1089                return new Unknown(machInst);
1090            } else {
1091                return decodeNeonSThreeUSReg<Vqdmlal>(
1092                        size, machInst, vd, vn, vm);
1093            }
1094          case 0xb:
1095            if (u) {
1096                return new Unknown(machInst);
1097            } else {
1098                return decodeNeonSThreeUSReg<Vqdmlsl>(
1099                        size, machInst, vd, vn, vm);
1100            }
1101          case 0xc:
1102            return decodeNeonUSThreeUSReg<Vmull>(
1103                    u, size, machInst, vd, vn, vm);
1104          case 0xd:
1105            if (u) {
1106                return new Unknown(machInst);
1107            } else {
1108                return decodeNeonSThreeUSReg<Vqdmull>(
1109                        size, machInst, vd, vn, vm);
1110            }
1111          case 0xe:
1112            return decodeNeonUThreeUSReg<Vmullp>(
1113                    size, machInst, vd, vn, vm);
1114        }
1115        return new Unknown(machInst);
1116    }
1117
1118    static StaticInstPtr
1119    decodeNeonTwoRegScalar(ExtMachInst machInst)
1120    {
1121        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1122        const uint32_t a = bits(machInst, 11, 8);
1123        const unsigned size = bits(machInst, 21, 20);
1124        const IntRegIndex vd =
1125            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1126                               (bits(machInst, 22) << 4)));
1127        const IntRegIndex vn =
1128            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1129                               (bits(machInst, 7) << 4)));
1130        const IntRegIndex vm = (size == 2) ?
1131            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1132            (IntRegIndex)(2 * bits(machInst, 2, 0));
1133        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1134            (bits(machInst, 3) | (bits(machInst, 5) << 1));
1135        switch (a) {
1136          case 0x0:
1137            if (u) {
1138                switch (size) {
1139                  case 1:
1140                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1141                  case 2:
1142                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1143                  default:
1144                    return new Unknown(machInst);
1145                }
1146            } else {
1147                switch (size) {
1148                  case 1:
1149                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1150                  case 2:
1151                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1152                  default:
1153                    return new Unknown(machInst);
1154                }
1155            }
1156          case 0x1:
1157            if (u)
1158                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1159            else
1160                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1161          case 0x4:
1162            if (u) {
1163                switch (size) {
1164                  case 1:
1165                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1166                  case 2:
1167                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1168                  default:
1169                    return new Unknown(machInst);
1170                }
1171            } else {
1172                switch (size) {
1173                  case 1:
1174                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1175                  case 2:
1176                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1177                  default:
1178                    return new Unknown(machInst);
1179                }
1180            }
1181          case 0x5:
1182            if (u)
1183                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1184            else
1185                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1186          case 0x2:
1187            if (u) {
1188                switch (size) {
1189                  case 1:
1190                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1191                  case 2:
1192                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1193                  default:
1194                    return new Unknown(machInst);
1195                }
1196            } else {
1197                switch (size) {
1198                  case 1:
1199                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1200                  case 2:
1201                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1202                  default:
1203                    return new Unknown(machInst);
1204                }
1205            }
1206          case 0x6:
1207            if (u) {
1208                switch (size) {
1209                  case 1:
1210                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1211                  case 2:
1212                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1213                  default:
1214                    return new Unknown(machInst);
1215                }
1216            } else {
1217                switch (size) {
1218                  case 1:
1219                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1220                  case 2:
1221                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1222                  default:
1223                    return new Unknown(machInst);
1224                }
1225            }
1226          case 0x3:
1227            if (u) {
1228                return new Unknown(machInst);
1229            } else {
1230                switch (size) {
1231                  case 1:
1232                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1233                  case 2:
1234                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1235                  default:
1236                    return new Unknown(machInst);
1237                }
1238            }
1239          case 0x7:
1240            if (u) {
1241                return new Unknown(machInst);
1242            } else {
1243                switch (size) {
1244                  case 1:
1245                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1246                  case 2:
1247                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1248                  default:
1249                    return new Unknown(machInst);
1250                }
1251            }
1252          case 0x8:
1253            if (u) {
1254                switch (size) {
1255                  case 1:
1256                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1257                  case 2:
1258                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1259                  default:
1260                    return new Unknown(machInst);
1261                }
1262            } else {
1263                switch (size) {
1264                  case 1:
1265                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1266                  case 2:
1267                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1268                  default:
1269                    return new Unknown(machInst);
1270                }
1271            }
1272          case 0x9:
1273            if (u)
1274                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1275            else
1276                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1277          case 0xa:
1278            if (u) {
1279                switch (size) {
1280                  case 1:
1281                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1282                  case 2:
1283                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1284                  default:
1285                    return new Unknown(machInst);
1286                }
1287            } else {
1288                switch (size) {
1289                  case 1:
1290                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1291                  case 2:
1292                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1293                  default:
1294                    return new Unknown(machInst);
1295                }
1296            }
1297          case 0xb:
1298            if (u) {
1299                return new Unknown(machInst);
1300            } else {
1301                if (u) {
1302                    switch (size) {
1303                      case 1:
1304                        return new Vqdmulls<uint16_t>(
1305                                machInst, vd, vn, vm, index);
1306                      case 2:
1307                        return new Vqdmulls<uint32_t>(
1308                                machInst, vd, vn, vm, index);
1309                      default:
1310                        return new Unknown(machInst);
1311                    }
1312                } else {
1313                    switch (size) {
1314                      case 1:
1315                        return new Vqdmulls<int16_t>(
1316                                machInst, vd, vn, vm, index);
1317                      case 2:
1318                        return new Vqdmulls<int32_t>(
1319                                machInst, vd, vn, vm, index);
1320                      default:
1321                        return new Unknown(machInst);
1322                    }
1323                }
1324            }
1325          case 0xc:
1326            if (u) {
1327                switch (size) {
1328                  case 1:
1329                    return new VqdmulhsQ<int16_t>(
1330                            machInst, vd, vn, vm, index);
1331                  case 2:
1332                    return new VqdmulhsQ<int32_t>(
1333                            machInst, vd, vn, vm, index);
1334                  default:
1335                    return new Unknown(machInst);
1336                }
1337            } else {
1338                switch (size) {
1339                  case 1:
1340                    return new VqdmulhsD<int16_t>(
1341                            machInst, vd, vn, vm, index);
1342                  case 2:
1343                    return new VqdmulhsD<int32_t>(
1344                            machInst, vd, vn, vm, index);
1345                  default:
1346                    return new Unknown(machInst);
1347                }
1348            }
1349          case 0xd:
1350            if (u) {
1351                switch (size) {
1352                  case 1:
1353                    return new VqrdmulhsQ<int16_t>(
1354                            machInst, vd, vn, vm, index);
1355                  case 2:
1356                    return new VqrdmulhsQ<int32_t>(
1357                            machInst, vd, vn, vm, index);
1358                  default:
1359                    return new Unknown(machInst);
1360                }
1361            } else {
1362                switch (size) {
1363                  case 1:
1364                    return new VqrdmulhsD<int16_t>(
1365                            machInst, vd, vn, vm, index);
1366                  case 2:
1367                    return new VqrdmulhsD<int32_t>(
1368                            machInst, vd, vn, vm, index);
1369                  default:
1370                    return new Unknown(machInst);
1371                }
1372            }
1373        }
1374        return new Unknown(machInst);
1375    }
1376
1377    static StaticInstPtr
1378    decodeNeonTwoRegMisc(ExtMachInst machInst)
1379    {
1380        const uint32_t a = bits(machInst, 17, 16);
1381        const uint32_t b = bits(machInst, 10, 6);
1382        const bool q = bits(machInst, 6);
1383        const IntRegIndex vd =
1384            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1385                               (bits(machInst, 22) << 4)));
1386        const IntRegIndex vm =
1387            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1388                               (bits(machInst, 5) << 4)));
1389        const unsigned size = bits(machInst, 19, 18);
1390        switch (a) {
1391          case 0x0:
1392            switch (bits(b, 4, 1)) {
1393              case 0x0:
1394                switch (size) {
1395                  case 0:
1396                    if (q) {
1397                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
1398                    } else {
1399                        return new NVrev64D<uint8_t>(machInst, vd, vm);
1400                    }
1401                  case 1:
1402                    if (q) {
1403                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
1404                    } else {
1405                        return new NVrev64D<uint16_t>(machInst, vd, vm);
1406                    }
1407                  case 2:
1408                    if (q) {
1409                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
1410                    } else {
1411                        return new NVrev64D<uint32_t>(machInst, vd, vm);
1412                    }
1413                  default:
1414                    return new Unknown(machInst);
1415                }
1416              case 0x1:
1417                switch (size) {
1418                  case 0:
1419                    if (q) {
1420                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
1421                    } else {
1422                        return new NVrev32D<uint8_t>(machInst, vd, vm);
1423                    }
1424                  case 1:
1425                    if (q) {
1426                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1427                    } else {
1428                        return new NVrev32D<uint16_t>(machInst, vd, vm);
1429                    }
1430                  default:
1431                    return new Unknown(machInst);
1432                }
1433              case 0x2:
1434                if (size != 0) {
1435                    return new Unknown(machInst);
1436                } else if (q) {
1437                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
1438                } else {
1439                    return new NVrev16D<uint8_t>(machInst, vd, vm);
1440                }
1441              case 0x4:
1442                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1443                        q, size, machInst, vd, vm);
1444              case 0x5:
1445                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1446                        q, size, machInst, vd, vm);
1447              case 0x8:
1448                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1449                        q, size, machInst, vd, vm);
1450              case 0x9:
1451                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1452                        q, size, machInst, vd, vm);
1453              case 0xa:
1454                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1455                        q, size, machInst, vd, vm);
1456              case 0xb:
1457                if (q)
1458                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
1459                else
1460                    return new NVmvnD<uint64_t>(machInst, vd, vm);
1461              case 0xc:
1462                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1463                        q, size, machInst, vd, vm);
1464              case 0xd:
1465                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1466                        q, size, machInst, vd, vm);
1467              case 0xe:
1468                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1469                        q, size, machInst, vd, vm);
1470              case 0xf:
1471                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1472                        q, size, machInst, vd, vm);
1473              default:
1474                return new Unknown(machInst);
1475            }
1476          case 0x1:
1477            switch (bits(b, 3, 1)) {
1478              case 0x0:
1479                if (bits(b, 4)) {
1480                    if (q) {
1481                        return new NVcgtQFp<float>(machInst, vd, vm);
1482                    } else {
1483                        return new NVcgtDFp<float>(machInst, vd, vm);
1484                    }
1485                } else {
1486                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1487                            q, size, machInst, vd, vm);
1488                }
1489              case 0x1:
1490                if (bits(b, 4)) {
1491                    if (q) {
1492                        return new NVcgeQFp<float>(machInst, vd, vm);
1493                    } else {
1494                        return new NVcgeDFp<float>(machInst, vd, vm);
1495                    }
1496                } else {
1497                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1498                            q, size, machInst, vd, vm);
1499                }
1500              case 0x2:
1501                if (bits(b, 4)) {
1502                    if (q) {
1503                        return new NVceqQFp<float>(machInst, vd, vm);
1504                    } else {
1505                        return new NVceqDFp<float>(machInst, vd, vm);
1506                    }
1507                } else {
1508                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1509                            q, size, machInst, vd, vm);
1510                }
1511              case 0x3:
1512                if (bits(b, 4)) {
1513                    if (q) {
1514                        return new NVcleQFp<float>(machInst, vd, vm);
1515                    } else {
1516                        return new NVcleDFp<float>(machInst, vd, vm);
1517                    }
1518                } else {
1519                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1520                            q, size, machInst, vd, vm);
1521                }
1522              case 0x4:
1523                if (bits(b, 4)) {
1524                    if (q) {
1525                        return new NVcltQFp<float>(machInst, vd, vm);
1526                    } else {
1527                        return new NVcltDFp<float>(machInst, vd, vm);
1528                    }
1529                } else {
1530                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1531                            q, size, machInst, vd, vm);
1532                }
1533              case 0x6:
1534                if (bits(machInst, 10)) {
1535                    if (q)
1536                        return new NVabsQFp<float>(machInst, vd, vm);
1537                    else
1538                        return new NVabsDFp<float>(machInst, vd, vm);
1539                } else {
1540                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1541                            q, size, machInst, vd, vm);
1542                }
1543              case 0x7:
1544                if (bits(machInst, 10)) {
1545                    if (q)
1546                        return new NVnegQFp<float>(machInst, vd, vm);
1547                    else
1548                        return new NVnegDFp<float>(machInst, vd, vm);
1549                } else {
1550                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1551                            q, size, machInst, vd, vm);
1552                }
1553            }
1554          case 0x2:
1555            switch (bits(b, 4, 1)) {
1556              case 0x0:
1557                if (q)
1558                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1559                else
1560                    return new NVswpD<uint64_t>(machInst, vd, vm);
1561              case 0x1:
1562                return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1563                        q, size, machInst, vd, vm);
1564              case 0x2:
1565                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1566                        q, size, machInst, vd, vm);
1567              case 0x3:
1568                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1569                        q, size, machInst, vd, vm);
1570              case 0x4:
1571                if (b == 0x8) {
1572                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1573                            size, machInst, vd, vm);
1574                } else {
1575                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1576                            size, machInst, vd, vm);
1577                }
1578              case 0x5:
1579                if (q) {
1580                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1581                            size, machInst, vd, vm);
1582                } else {
1583                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1584                            size, machInst, vd, vm);
1585                }
1586              case 0x6:
1587                if (b == 0xc) {
1588                    return decodeNeonSTwoShiftUSReg<NVshll>(
1589                            size, machInst, vd, vm, 8 << size);
1590                } else {
1591                    return new Unknown(machInst);
1592                }
1593              case 0xc:
1594              case 0xe:
1595                if (b == 0x18) {
1596                    if (size != 1 || (vm % 2))
1597                        return new Unknown(machInst);
1598                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1599                } else if (b == 0x1c) {
1600                    if (size != 1 || (vd % 2))
1601                        return new Unknown(machInst);
1602                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1603                } else {
1604                    return new Unknown(machInst);
1605                }
1606              default:
1607                return new Unknown(machInst);
1608            }
1609          case 0x3:
1610            if (bits(b, 4, 3) == 0x3) {
1611                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1612                    return new Unknown(machInst);
1613                } else {
1614                    if (bits(b, 2)) {
1615                        if (bits(b, 1)) {
1616                            if (q) {
1617                                return new NVcvt2ufxQ<float>(
1618                                        machInst, vd, vm, 0);
1619                            } else {
1620                                return new NVcvt2ufxD<float>(
1621                                        machInst, vd, vm, 0);
1622                            }
1623                        } else {
1624                            if (q) {
1625                                return new NVcvt2sfxQ<float>(
1626                                        machInst, vd, vm, 0);
1627                            } else {
1628                                return new NVcvt2sfxD<float>(
1629                                        machInst, vd, vm, 0);
1630                            }
1631                        }
1632                    } else {
1633                        if (bits(b, 1)) {
1634                            if (q) {
1635                                return new NVcvtu2fpQ<float>(
1636                                        machInst, vd, vm, 0);
1637                            } else {
1638                                return new NVcvtu2fpD<float>(
1639                                        machInst, vd, vm, 0);
1640                            }
1641                        } else {
1642                            if (q) {
1643                                return new NVcvts2fpQ<float>(
1644                                        machInst, vd, vm, 0);
1645                            } else {
1646                                return new NVcvts2fpD<float>(
1647                                        machInst, vd, vm, 0);
1648                            }
1649                        }
1650                    }
1651                }
1652            } else if ((b & 0x1a) == 0x10) {
1653                if (bits(b, 2)) {
1654                    if (q) {
1655                        return new NVrecpeQFp<float>(machInst, vd, vm);
1656                    } else {
1657                        return new NVrecpeDFp<float>(machInst, vd, vm);
1658                    }
1659                } else {
1660                    if (q) {
1661                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1662                    } else {
1663                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1664                    }
1665                }
1666            } else if ((b & 0x1a) == 0x12) {
1667                if (bits(b, 2)) {
1668                    if (q) {
1669                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1670                    } else {
1671                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1672                    }
1673                } else {
1674                    if (q) {
1675                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1676                    } else {
1677                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1678                    }
1679                }
1680            } else {
1681                return new Unknown(machInst);
1682            }
1683        }
1684        return new Unknown(machInst);
1685    }
1686
1687    StaticInstPtr
1688    decodeNeonData(ExtMachInst machInst)
1689    {
1690        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1691        const uint32_t a = bits(machInst, 23, 19);
1692        const uint32_t b = bits(machInst, 11, 8);
1693        const uint32_t c = bits(machInst, 7, 4);
1694        if (bits(a, 4) == 0) {
1695            return decodeNeonThreeRegistersSameLength(machInst);
1696        } else if ((c & 0x9) == 1) {
1697            if ((a & 0x7) == 0) {
1698                return decodeNeonOneRegModImm(machInst);
1699            } else {
1700                return decodeNeonTwoRegAndShift(machInst);
1701            }
1702        } else if ((c & 0x9) == 9) {
1703            return decodeNeonTwoRegAndShift(machInst);
1704        } else if (bits(a, 2, 1) != 0x3) {
1705            if ((c & 0x5) == 0) {
1706                return decodeNeonThreeRegDiffLengths(machInst);
1707            } else if ((c & 0x5) == 4) {
1708                return decodeNeonTwoRegScalar(machInst);
1709            }
1710        } else if ((a & 0x16) == 0x16) {
1711            const IntRegIndex vd =
1712                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1713                                   (bits(machInst, 22) << 4)));
1714            const IntRegIndex vn =
1715                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1716                                   (bits(machInst, 7) << 4)));
1717            const IntRegIndex vm =
1718                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1719                                   (bits(machInst, 5) << 4)));
1720            if (!u) {
1721                if (bits(c, 0) == 0) {
1722                    unsigned imm4 = bits(machInst, 11, 8);
1723                    bool q = bits(machInst, 6);
1724                    if (imm4 >= 16 && !q)
1725                        return new Unknown(machInst);
1726                    if (q) {
1727                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1728                    } else {
1729                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1730                    }
1731                }
1732            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1733                return decodeNeonTwoRegMisc(machInst);
1734            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1735                unsigned length = bits(machInst, 9, 8) + 1;
1736                if ((uint32_t)vn / 2 + length > 32)
1737                    return new Unknown(machInst);
1738                if (bits(machInst, 6) == 0) {
1739                    switch (length) {
1740                      case 1:
1741                        return new NVtbl1(machInst, vd, vn, vm);
1742                      case 2:
1743                        return new NVtbl2(machInst, vd, vn, vm);
1744                      case 3:
1745                        return new NVtbl3(machInst, vd, vn, vm);
1746                      case 4:
1747                        return new NVtbl4(machInst, vd, vn, vm);
1748                    }
1749                } else {
1750                    switch (length) {
1751                      case 1:
1752                        return new NVtbx1(machInst, vd, vn, vm);
1753                      case 2:
1754                        return new NVtbx2(machInst, vd, vn, vm);
1755                      case 3:
1756                        return new NVtbx3(machInst, vd, vn, vm);
1757                      case 4:
1758                        return new NVtbx4(machInst, vd, vn, vm);
1759                    }
1760                }
1761            } else if (b == 0xc && (c & 0x9) == 0) {
1762                unsigned imm4 = bits(machInst, 19, 16);
1763                if (bits(imm4, 2, 0) == 0)
1764                    return new Unknown(machInst);
1765                unsigned size = 0;
1766                while ((imm4 & 0x1) == 0) {
1767                    size++;
1768                    imm4 >>= 1;
1769                }
1770                unsigned index = imm4 >> 1;
1771                const bool q = bits(machInst, 6);
1772                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1773                        q, size, machInst, vd, vm, index);
1774            }
1775        }
1776        return new Unknown(machInst);
1777    }
1778    '''
1779}};
1780
1781def format ThumbNeonMem() {{
1782    decode_block = '''
1783    return decodeNeonMem(machInst);
1784    '''
1785}};
1786
1787def format ThumbNeonData() {{
1788    decode_block = '''
1789    return decodeNeonData(machInst);
1790    '''
1791}};
1792
1793let {{
1794    header_output = '''
1795    StaticInstPtr
1796    decodeExtensionRegLoadStore(ExtMachInst machInst);
1797    '''
1798    decoder_output = '''
1799    StaticInstPtr
1800    decodeExtensionRegLoadStore(ExtMachInst machInst)
1801    {
1802        const uint32_t opcode = bits(machInst, 24, 20);
1803        const uint32_t offset = bits(machInst, 7, 0);
1804        const bool single = (bits(machInst, 8) == 0);
1805        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1806        RegIndex vd;
1807        if (single) {
1808            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1809                                      bits(machInst, 22));
1810        } else {
1811            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1812                                      (bits(machInst, 22) << 5));
1813        }
1814        switch (bits(opcode, 4, 3)) {
1815          case 0x0:
1816            if (bits(opcode, 4, 1) == 0x2 &&
1817                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1818                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1819                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1820                    break;
1821                }
1822                const IntRegIndex rt =
1823                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1824                const IntRegIndex rt2 =
1825                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1826                const bool op = bits(machInst, 20);
1827                uint32_t vm;
1828                if (single) {
1829                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1830                } else {
1831                    vm = (bits(machInst, 3, 0) << 1) |
1832                         (bits(machInst, 5) << 5);
1833                }
1834                if (op) {
1835                    return new Vmov2Core2Reg(machInst, rt, rt2,
1836                                             (IntRegIndex)vm);
1837                } else {
1838                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1839                                             rt, rt2);
1840                }
1841            }
1842            break;
1843          case 0x1:
1844            {
1845                if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1846                    break;
1847                }
1848                switch (bits(opcode, 1, 0)) {
1849                  case 0x0:
1850                    return new VLdmStm(machInst, rn, vd, single,
1851                                       true, false, false, offset);
1852                  case 0x1:
1853                    return new VLdmStm(machInst, rn, vd, single,
1854                                       true, false, true, offset);
1855                  case 0x2:
1856                    return new VLdmStm(machInst, rn, vd, single,
1857                                       true, true, false, offset);
1858                  case 0x3:
1859                    // If rn == sp, then this is called vpop.
1860                    return new VLdmStm(machInst, rn, vd, single,
1861                                       true, true, true, offset);
1862                }
1863            }
1864          case 0x2:
1865            if (bits(opcode, 1, 0) == 0x2) {
1866                // If rn == sp, then this is called vpush.
1867                return new VLdmStm(machInst, rn, vd, single,
1868                                   false, true, false, offset);
1869            } else if (bits(opcode, 1, 0) == 0x3) {
1870                return new VLdmStm(machInst, rn, vd, single,
1871                                   false, true, true, offset);
1872            }
1873            // Fall through on purpose
1874          case 0x3:
1875            const bool up = (bits(machInst, 23) == 1);
1876            const uint32_t imm = bits(machInst, 7, 0) << 2;
1877            if (single) {
1878                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1879                                          (bits(machInst, 22)));
1880            } else {
1881                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1882                                          (bits(machInst, 22) << 5));
1883            }
1884            if (bits(opcode, 1, 0) == 0x0) {
1885                if (single) {
1886                    if (up) {
1887                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1888                    } else {
1889                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1890                    }
1891                } else {
1892                    if (up) {
1893                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1894                                               rn, up, imm);
1895                    } else {
1896                        return new %(vstr_d)s(machInst, vd, vd + 1,
1897                                              rn, up, imm);
1898                    }
1899                }
1900            } else if (bits(opcode, 1, 0) == 0x1) {
1901                if (single) {
1902                    if (up) {
1903                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1904                    } else {
1905                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1906                    }
1907                } else {
1908                    if (up) {
1909                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1910                                               rn, up, imm);
1911                    } else {
1912                        return new %(vldr_d)s(machInst, vd, vd + 1,
1913                                              rn, up, imm);
1914                    }
1915                }
1916            }
1917        }
1918        return new Unknown(machInst);
1919    }
1920    ''' % {
1921        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1922        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1923        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1924        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1925        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1926        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1927        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1928        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1929    }
1930}};
1931
1932def format ExtensionRegLoadStore() {{
1933    decode_block = '''
1934    return decodeExtensionRegLoadStore(machInst);
1935    '''
1936}};
1937
1938let {{
1939    header_output = '''
1940    StaticInstPtr
1941    decodeShortFpTransfer(ExtMachInst machInst);
1942    '''
1943    decoder_output = '''
1944    StaticInstPtr
1945    decodeShortFpTransfer(ExtMachInst machInst)
1946    {
1947        const uint32_t l = bits(machInst, 20);
1948        const uint32_t c = bits(machInst, 8);
1949        const uint32_t a = bits(machInst, 23, 21);
1950        const uint32_t b = bits(machInst, 6, 5);
1951        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1952            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1953            // Determine if this is backported aarch64 FP instruction
1954            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
1955            const bool b23 = bits(machInst, 23);
1956            const bool b21_b18 = bits(machInst, 21, 18) == 0xE;
1957            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
1958            const bool sz = bits(machInst, 8);
1959            const bool b7_b6   = bits(machInst, 7, 6) == 0x1;
1960            const bool b6 = bits(machInst, 6) == 0x0;
1961            const bool b4 = bits(machInst, 4) == 0x0;
1962            if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) {
1963                  // VINT* Integer Rounding Instructon
1964                  const uint32_t rm = bits(machInst, 17, 16);
1965
1966                  if (sz) {
1967                      const IntRegIndex vd =
1968                          (IntRegIndex)((bits(machInst, 22) << 5) |
1969                                        (bits(machInst, 15, 12) << 1));
1970                      const IntRegIndex vm =
1971                          (IntRegIndex)((bits(machInst, 5) << 5) |
1972                                        (bits(machInst, 3, 0) << 1));
1973                      switch(rm) {
1974                        case 0x0:
1975                          return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
1976                                                            true);
1977                        case 0x1:
1978                          return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
1979                                                            true);
1980                        case 0x2:
1981                          return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
1982                                                            true);
1983                        case 0x3:
1984                          return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
1985                                                            true);
1986                        default: return new Unknown(machInst);
1987                      }
1988                  } else {
1989                      const IntRegIndex vd =
1990                          (IntRegIndex)(bits(machInst, 22) |
1991                                       (bits(machInst, 15, 12) << 1));
1992                      const IntRegIndex vm =
1993                          (IntRegIndex)(bits(machInst, 5) |
1994                                        (bits(machInst, 3, 0) << 1));
1995                      switch(rm) {
1996                        case 0x0:
1997                          return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
1998                                                            false);
1999                        case 0x1:
2000                          return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2001                                                            false);
2002                        case 0x2:
2003                          return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2004                                                            false);
2005                        case 0x3:
2006                          return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2007                                                            false);
2008                        default: return new Unknown(machInst);
2009                      }
2010                  }
2011            } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){
2012                // VSEL* floating point conditional select
2013
2014                ConditionCode cond;
2015                switch(bits(machInst, 21, 20)) {
2016                  case 0x0: cond = COND_EQ; break;
2017                  case 0x1: cond = COND_VS; break;
2018                  case 0x2: cond = COND_GE; break;
2019                  case 0x3: cond = COND_GT; break;
2020                }
2021
2022                if (sz) {
2023                      const IntRegIndex vd =
2024                          (IntRegIndex)((bits(machInst, 22) << 5) |
2025                                        (bits(machInst, 15, 12) << 1));
2026                      const IntRegIndex vm =
2027                          (IntRegIndex)((bits(machInst, 5) << 5) |
2028                                        (bits(machInst, 3, 0) << 1));
2029                      const IntRegIndex vn =
2030                          (IntRegIndex)((bits(machInst, 7) << 5) |
2031                                       (bits(machInst, 19, 16) << 1));
2032                    return new VselD(machInst, vd, vn, vm, cond);
2033                } else {
2034                      const IntRegIndex vd =
2035                          (IntRegIndex)(bits(machInst, 22) |
2036                                       (bits(machInst, 15, 12) << 1));
2037                      const IntRegIndex vm =
2038                          (IntRegIndex)(bits(machInst, 5) |
2039                                        (bits(machInst, 3, 0) << 1));
2040                      const IntRegIndex vn =
2041                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2042                                        bits(machInst, 7));
2043                      return new VselS(machInst, vd, vn, vm, cond);
2044                }
2045            } else {
2046                return new Unknown(machInst);
2047            }
2048        }
2049        if (l == 0 && c == 0) {
2050            if (a == 0) {
2051                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2052                                    bits(machInst, 7);
2053                const IntRegIndex rt =
2054                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2055                if (bits(machInst, 20) == 1) {
2056                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2057                } else {
2058                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2059                }
2060            } else if (a == 0x7) {
2061                const IntRegIndex rt =
2062                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2063                uint32_t reg = bits(machInst, 19, 16);
2064                uint32_t specReg;
2065                switch (reg) {
2066                  case 0:
2067                    specReg = MISCREG_FPSID;
2068                    break;
2069                  case 1:
2070                    specReg = MISCREG_FPSCR;
2071                    break;
2072                  case 6:
2073                    specReg = MISCREG_MVFR1;
2074                    break;
2075                  case 7:
2076                    specReg = MISCREG_MVFR0;
2077                    break;
2078                  case 8:
2079                    specReg = MISCREG_FPEXC;
2080                    break;
2081                  default:
2082                    return new Unknown(machInst);
2083                }
2084                if (specReg == MISCREG_FPSCR) {
2085                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2086                } else {
2087                    uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2088                        reg, a, bits(machInst, 7, 5));
2089                    return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2090                }
2091            }
2092        } else if (l == 0 && c == 1) {
2093            if (bits(a, 2) == 0) {
2094                uint32_t vd = (bits(machInst, 7) << 5) |
2095                              (bits(machInst, 19, 16) << 1);
2096                // Handle accessing each single precision half of the vector.
2097                vd += bits(machInst, 21);
2098                const IntRegIndex rt =
2099                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2100                if (bits(machInst, 22) == 1) {
2101                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2102                                            rt, bits(machInst, 6, 5));
2103                } else if (bits(machInst, 5) == 1) {
2104                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2105                                            rt, bits(machInst, 6));
2106                } else if (bits(machInst, 6) == 0) {
2107                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2108                } else {
2109                    return new Unknown(machInst);
2110                }
2111            } else if (bits(b, 1) == 0) {
2112                bool q = bits(machInst, 21);
2113                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2114                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2115                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2116                IntRegIndex rt = (IntRegIndex)(uint32_t)
2117                    bits(machInst, 15, 12);
2118                if (q) {
2119                    switch (be) {
2120                      case 0:
2121                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2122                      case 1:
2123                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2124                      case 2:
2125                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2126                      case 3:
2127                        return new Unknown(machInst);
2128                    }
2129                } else {
2130                    switch (be) {
2131                      case 0:
2132                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2133                      case 1:
2134                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2135                      case 2:
2136                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2137                      case 3:
2138                        return new Unknown(machInst);
2139                    }
2140                }
2141            }
2142        } else if (l == 1 && c == 0) {
2143            if (a == 0) {
2144                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2145                                    bits(machInst, 7);
2146                const IntRegIndex rt =
2147                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2148                if (bits(machInst, 20) == 1) {
2149                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2150                } else {
2151                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2152                }
2153            } else if (a == 7) {
2154                const IntRegIndex rt =
2155                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2156                uint32_t reg = bits(machInst, 19, 16);
2157                uint32_t specReg;
2158                switch (reg) {
2159                  case 0:
2160                    specReg = MISCREG_FPSID;
2161                    break;
2162                  case 1:
2163                    specReg = MISCREG_FPSCR;
2164                    break;
2165                  case 6:
2166                    specReg = MISCREG_MVFR1;
2167                    break;
2168                  case 7:
2169                    specReg = MISCREG_MVFR0;
2170                    break;
2171                  case 8:
2172                    specReg = MISCREG_FPEXC;
2173                    break;
2174                  default:
2175                    return new Unknown(machInst);
2176                }
2177                if (rt == 0xf) {
2178                    if (specReg == MISCREG_FPSCR) {
2179                        return new VmrsApsrFpscr(machInst);
2180                    } else {
2181                        return new Unknown(machInst);
2182                    }
2183                } else if (specReg == MISCREG_FPSCR) {
2184                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2185                } else {
2186                    uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2187                        reg, a, bits(machInst, 7, 5));
2188                    return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2189                }
2190            }
2191        } else {
2192            uint32_t vd = (bits(machInst, 7) << 5) |
2193                          (bits(machInst, 19, 16) << 1);
2194            // Handle indexing into each single precision half of the vector.
2195            vd += bits(machInst, 21);
2196            uint32_t index;
2197            const IntRegIndex rt =
2198                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2199            const bool u = (bits(machInst, 23) == 1);
2200            if (bits(machInst, 22) == 1) {
2201                index = bits(machInst, 6, 5);
2202                if (u) {
2203                    return new VmovRegCoreUB(machInst, rt,
2204                                             (IntRegIndex)vd, index);
2205                } else {
2206                    return new VmovRegCoreSB(machInst, rt,
2207                                             (IntRegIndex)vd, index);
2208                }
2209            } else if (bits(machInst, 5) == 1) {
2210                index = bits(machInst, 6);
2211                if (u) {
2212                    return new VmovRegCoreUH(machInst, rt,
2213                                             (IntRegIndex)vd, index);
2214                } else {
2215                    return new VmovRegCoreSH(machInst, rt,
2216                                             (IntRegIndex)vd, index);
2217                }
2218            } else if (bits(machInst, 6) == 0 && !u) {
2219                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2220            } else {
2221                return new Unknown(machInst);
2222            }
2223        }
2224        return new Unknown(machInst);
2225    }
2226    '''
2227}};
2228
2229def format ShortFpTransfer() {{
2230    decode_block = '''
2231    return decodeShortFpTransfer(machInst);
2232    '''
2233}};
2234
2235let {{
2236    header_output = '''
2237    StaticInstPtr
2238    decodeVfpData(ExtMachInst machInst);
2239    '''
2240    decoder_output = '''
2241    StaticInstPtr
2242    decodeVfpData(ExtMachInst machInst)
2243    {
2244        const uint32_t opc1 = bits(machInst, 23, 20);
2245        const uint32_t opc2 = bits(machInst, 19, 16);
2246        const uint32_t opc3 = bits(machInst, 7, 6);
2247        //const uint32_t opc4 = bits(machInst, 3, 0);
2248        const bool single = (bits(machInst, 8) == 0);
2249        // Used to select between vcmp and vcmpe.
2250        const bool e = (bits(machInst, 7) == 1);
2251        IntRegIndex vd;
2252        IntRegIndex vm;
2253        IntRegIndex vn;
2254        if (single) {
2255            vd = (IntRegIndex)(bits(machInst, 22) |
2256                    (bits(machInst, 15, 12) << 1));
2257            vm = (IntRegIndex)(bits(machInst, 5) |
2258                    (bits(machInst, 3, 0) << 1));
2259            vn = (IntRegIndex)(bits(machInst, 7) |
2260                    (bits(machInst, 19, 16) << 1));
2261        } else {
2262            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2263                    (bits(machInst, 15, 12) << 1));
2264            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2265                    (bits(machInst, 3, 0) << 1));
2266            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2267                    (bits(machInst, 19, 16) << 1));
2268        }
2269        switch (opc1 & 0xb /* 1011 */) {
2270          case 0x0:
2271            if (bits(machInst, 6) == 0) {
2272                if (single) {
2273                    return decodeVfpRegRegRegOp<VmlaS>(
2274                            machInst, vd, vn, vm, false);
2275                } else {
2276                    return decodeVfpRegRegRegOp<VmlaD>(
2277                            machInst, vd, vn, vm, true);
2278                }
2279            } else {
2280                if (single) {
2281                    return decodeVfpRegRegRegOp<VmlsS>(
2282                            machInst, vd, vn, vm, false);
2283                } else {
2284                    return decodeVfpRegRegRegOp<VmlsD>(
2285                            machInst, vd, vn, vm, true);
2286                }
2287            }
2288          case 0x1:
2289            if (bits(machInst, 6) == 1) {
2290                if (single) {
2291                    return decodeVfpRegRegRegOp<VnmlaS>(
2292                            machInst, vd, vn, vm, false);
2293                } else {
2294                    return decodeVfpRegRegRegOp<VnmlaD>(
2295                            machInst, vd, vn, vm, true);
2296                }
2297            } else {
2298                if (single) {
2299                    return decodeVfpRegRegRegOp<VnmlsS>(
2300                            machInst, vd, vn, vm, false);
2301                } else {
2302                    return decodeVfpRegRegRegOp<VnmlsD>(
2303                            machInst, vd, vn, vm, true);
2304                }
2305            }
2306          case 0x2:
2307            if ((opc3 & 0x1) == 0) {
2308                if (single) {
2309                    return decodeVfpRegRegRegOp<VmulS>(
2310                            machInst, vd, vn, vm, false);
2311                } else {
2312                    return decodeVfpRegRegRegOp<VmulD>(
2313                            machInst, vd, vn, vm, true);
2314                }
2315            } else {
2316                if (single) {
2317                    return decodeVfpRegRegRegOp<VnmulS>(
2318                            machInst, vd, vn, vm, false);
2319                } else {
2320                    return decodeVfpRegRegRegOp<VnmulD>(
2321                            machInst, vd, vn, vm, true);
2322                }
2323            }
2324          case 0x3:
2325            if ((opc3 & 0x1) == 0) {
2326                if (single) {
2327                    return decodeVfpRegRegRegOp<VaddS>(
2328                            machInst, vd, vn, vm, false);
2329                } else {
2330                    return decodeVfpRegRegRegOp<VaddD>(
2331                            machInst, vd, vn, vm, true);
2332                }
2333            } else {
2334                if (single) {
2335                    return decodeVfpRegRegRegOp<VsubS>(
2336                            machInst, vd, vn, vm, false);
2337                } else {
2338                    return decodeVfpRegRegRegOp<VsubD>(
2339                            machInst, vd, vn, vm, true);
2340                }
2341            }
2342          case 0x8:
2343            if ((opc3 & 0x1) == 0) {
2344                if (single) {
2345                    return decodeVfpRegRegRegOp<VdivS>(
2346                            machInst, vd, vn, vm, false);
2347                } else {
2348                    return decodeVfpRegRegRegOp<VdivD>(
2349                            machInst, vd, vn, vm, true);
2350                }
2351            }
2352            break;
2353          case 0x9:
2354            if ((opc3 & 0x1) == 0) {
2355                if (single) {
2356                    return decodeVfpRegRegRegOp<VfnmaS>(
2357                            machInst, vd, vn, vm, false);
2358                } else {
2359                    return decodeVfpRegRegRegOp<VfnmaD>(
2360                            machInst, vd, vn, vm, true);
2361                }
2362            } else {
2363                if (single) {
2364                    return decodeVfpRegRegRegOp<VfnmsS>(
2365                            machInst, vd, vn, vm, false);
2366                } else {
2367                    return decodeVfpRegRegRegOp<VfnmsD>(
2368                            machInst, vd, vn, vm, true);
2369                }
2370            }
2371            break;
2372          case 0xa:
2373            if ((opc3 & 0x1) == 0) {
2374                if (single) {
2375                    return decodeVfpRegRegRegOp<VfmaS>(
2376                            machInst, vd, vn, vm, false);
2377                } else {
2378                    return decodeVfpRegRegRegOp<VfmaD>(
2379                            machInst, vd, vn, vm, true);
2380                }
2381            } else {
2382                if (single) {
2383                    return decodeVfpRegRegRegOp<VfmsS>(
2384                            machInst, vd, vn, vm, false);
2385                } else {
2386                    return decodeVfpRegRegRegOp<VfmsD>(
2387                            machInst, vd, vn, vm, true);
2388                }
2389            }
2390            break;
2391          case 0xb:
2392            if ((opc3 & 0x1) == 0) {
2393                const uint32_t baseImm =
2394                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2395                if (single) {
2396                    uint32_t imm = vfp_modified_imm(baseImm, false);
2397                    return decodeVfpRegImmOp<VmovImmS>(
2398                            machInst, vd, imm, false);
2399                } else {
2400                    uint64_t imm = vfp_modified_imm(baseImm, true);
2401                    return decodeVfpRegImmOp<VmovImmD>(
2402                            machInst, vd, imm, true);
2403                }
2404            }
2405            switch (opc2) {
2406              case 0x0:
2407                if (opc3 == 1) {
2408                    if (single) {
2409                        return decodeVfpRegRegOp<VmovRegS>(
2410                                machInst, vd, vm, false);
2411                    } else {
2412                        return decodeVfpRegRegOp<VmovRegD>(
2413                                machInst, vd, vm, true);
2414                    }
2415                } else {
2416                    if (single) {
2417                        return decodeVfpRegRegOp<VabsS>(
2418                                machInst, vd, vm, false);
2419                    } else {
2420                        return decodeVfpRegRegOp<VabsD>(
2421                                machInst, vd, vm, true);
2422                    }
2423                }
2424              case 0x1:
2425                if (opc3 == 1) {
2426                    if (single) {
2427                        return decodeVfpRegRegOp<VnegS>(
2428                                machInst, vd, vm, false);
2429                    } else {
2430                        return decodeVfpRegRegOp<VnegD>(
2431                                machInst, vd, vm, true);
2432                    }
2433                } else {
2434                    if (single) {
2435                        return decodeVfpRegRegOp<VsqrtS>(
2436                                machInst, vd, vm, false);
2437                    } else {
2438                        return decodeVfpRegRegOp<VsqrtD>(
2439                                machInst, vd, vm, true);
2440                    }
2441                }
2442              case 0x2:
2443              case 0x3:
2444                {
2445                    const bool toHalf = bits(machInst, 16);
2446                    const bool top = bits(machInst, 7);
2447                    if (top) {
2448                        if (toHalf) {
2449                            return new VcvtFpSFpHT(machInst, vd, vm);
2450                        } else {
2451                            return new VcvtFpHTFpS(machInst, vd, vm);
2452                        }
2453                    } else {
2454                        if (toHalf) {
2455                            return new VcvtFpSFpHB(machInst, vd, vm);
2456                        } else {
2457                            return new VcvtFpHBFpS(machInst, vd, vm);
2458                        }
2459                    }
2460                }
2461              case 0x4:
2462                if (single) {
2463                    if (e) {
2464                        return new VcmpeS(machInst, vd, vm);
2465                    } else {
2466                        return new VcmpS(machInst, vd, vm);
2467                    }
2468                } else {
2469                    if (e) {
2470                        return new VcmpeD(machInst, vd, vm);
2471                    } else {
2472                        return new VcmpD(machInst, vd, vm);
2473                    }
2474                }
2475              case 0x5:
2476                if (single) {
2477                    if (e) {
2478                        return new VcmpeZeroS(machInst, vd, 0);
2479                    } else {
2480                        return new VcmpZeroS(machInst, vd, 0);
2481                    }
2482                } else {
2483                    if (e) {
2484                        return new VcmpeZeroD(machInst, vd, 0);
2485                    } else {
2486                        return new VcmpZeroD(machInst, vd, 0);
2487                    }
2488                }
2489              case 0x7:
2490                if (opc3 == 0x3) {
2491                    if (single) {
2492                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2493                                (bits(machInst, 15, 12) << 1));
2494                        return new VcvtFpSFpD(machInst, vd, vm);
2495                    } else {
2496                        vd = (IntRegIndex)(bits(machInst, 22) |
2497                                (bits(machInst, 15, 12) << 1));
2498                        return new VcvtFpDFpS(machInst, vd, vm);
2499                    }
2500                }
2501                break;
2502              case 0x8:
2503                if (bits(machInst, 7) == 0) {
2504                    if (single) {
2505                        return new VcvtUIntFpS(machInst, vd, vm);
2506                    } else {
2507                        vm = (IntRegIndex)(bits(machInst, 5) |
2508                                (bits(machInst, 3, 0) << 1));
2509                        return new VcvtUIntFpD(machInst, vd, vm);
2510                    }
2511                } else {
2512                    if (single) {
2513                        return new VcvtSIntFpS(machInst, vd, vm);
2514                    } else {
2515                        vm = (IntRegIndex)(bits(machInst, 5) |
2516                                (bits(machInst, 3, 0) << 1));
2517                        return new VcvtSIntFpD(machInst, vd, vm);
2518                    }
2519                }
2520              case 0xa:
2521                {
2522                    const bool half = (bits(machInst, 7) == 0);
2523                    const uint32_t imm = bits(machInst, 5) |
2524                                         (bits(machInst, 3, 0) << 1);
2525                    const uint32_t size =
2526                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2527                    if (single) {
2528                        if (half) {
2529                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2530                        } else {
2531                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2532                        }
2533                    } else {
2534                        if (half) {
2535                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2536                        } else {
2537                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2538                        }
2539                    }
2540                }
2541              case 0xb:
2542                {
2543                    const bool half = (bits(machInst, 7) == 0);
2544                    const uint32_t imm = bits(machInst, 5) |
2545                                         (bits(machInst, 3, 0) << 1);
2546                    const uint32_t size =
2547                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2548                    if (single) {
2549                        if (half) {
2550                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2551                        } else {
2552                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2553                        }
2554                    } else {
2555                        if (half) {
2556                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2557                        } else {
2558                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2559                        }
2560                    }
2561                }
2562              case 0xc:
2563                if (bits(machInst, 7) == 0) {
2564                    if (single) {
2565                        return new VcvtFpUIntSR(machInst, vd, vm);
2566                    } else {
2567                        vd = (IntRegIndex)(bits(machInst, 22) |
2568                                (bits(machInst, 15, 12) << 1));
2569                        return new VcvtFpUIntDR(machInst, vd, vm);
2570                    }
2571                } else {
2572                    if (single) {
2573                        return new VcvtFpUIntS(machInst, vd, vm);
2574                    } else {
2575                        vd = (IntRegIndex)(bits(machInst, 22) |
2576                                (bits(machInst, 15, 12) << 1));
2577                        return new VcvtFpUIntD(machInst, vd, vm);
2578                    }
2579                }
2580              case 0xd:
2581                if (bits(machInst, 7) == 0) {
2582                    if (single) {
2583                        return new VcvtFpSIntSR(machInst, vd, vm);
2584                    } else {
2585                        vd = (IntRegIndex)(bits(machInst, 22) |
2586                                (bits(machInst, 15, 12) << 1));
2587                        return new VcvtFpSIntDR(machInst, vd, vm);
2588                    }
2589                } else {
2590                    if (single) {
2591                        return new VcvtFpSIntS(machInst, vd, vm);
2592                    } else {
2593                        vd = (IntRegIndex)(bits(machInst, 22) |
2594                                (bits(machInst, 15, 12) << 1));
2595                        return new VcvtFpSIntD(machInst, vd, vm);
2596                    }
2597                }
2598              case 0xe:
2599                {
2600                    const bool half = (bits(machInst, 7) == 0);
2601                    const uint32_t imm = bits(machInst, 5) |
2602                                         (bits(machInst, 3, 0) << 1);
2603                    const uint32_t size =
2604                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2605                    if (single) {
2606                        if (half) {
2607                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2608                        } else {
2609                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2610                        }
2611                    } else {
2612                        if (half) {
2613                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2614                        } else {
2615                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2616                        }
2617                    }
2618                }
2619              case 0xf:
2620                {
2621                    const bool half = (bits(machInst, 7) == 0);
2622                    const uint32_t imm = bits(machInst, 5) |
2623                                         (bits(machInst, 3, 0) << 1);
2624                    const uint32_t size =
2625                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2626                    if (single) {
2627                        if (half) {
2628                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2629                        } else {
2630                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2631                        }
2632                    } else {
2633                        if (half) {
2634                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2635                        } else {
2636                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2637                        }
2638                    }
2639                }
2640            }
2641            break;
2642        }
2643        return new Unknown(machInst);
2644    }
2645    '''
2646}};
2647
2648def format VfpData() {{
2649    decode_block = '''
2650    return decodeVfpData(machInst);
2651    '''
2652}};
2653