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