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