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