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