fp.isa revision 13977:13f7408bafff
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                    return new Unknown(machInst);
746                } else {
747                    if (bits(size, 1) == 0) {
748                        if (q) {
749                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
750                        } else {
751                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
752                        }
753                    } else {
754                        if (q) {
755                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
756                        } else {
757                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
758                        }
759                    }
760                }
761            } else {
762                if (u) {
763                    if (bits(size, 1) == 0) {
764                        if (q) {
765                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
766                        } else {
767                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
768                        }
769                    } else {
770                        if (q) {
771                            return new VpminQFp<float>(machInst, vd, vn, vm);
772                        } else {
773                            return new VpminDFp<float>(machInst, vd, vn, vm);
774                        }
775                    }
776                } else {
777                    if (bits(size, 1) == 0) {
778                        if (q) {
779                            return new VmaxQFp<float>(machInst, vd, vn, vm);
780                        } else {
781                            return new VmaxDFp<float>(machInst, vd, vn, vm);
782                        }
783                    } else {
784                        if (q) {
785                            return new VminQFp<float>(machInst, vd, vn, vm);
786                        } else {
787                            return new VminDFp<float>(machInst, vd, vn, vm);
788                        }
789                    }
790                }
791            }
792        }
793        return new Unknown(machInst);
794    }
795
796    static StaticInstPtr
797    decodeNeonOneRegModImm(ExtMachInst machInst)
798    {
799        const IntRegIndex vd =
800            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
801                               (bits(machInst, 22) << 4)));
802        const bool q = bits(machInst, 6);
803        const bool op = bits(machInst, 5);
804        const uint8_t cmode = bits(machInst, 11, 8);
805        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
806                                      bits(machInst, 24)) << 7) |
807                            (bits(machInst, 18, 16) << 4) |
808                            (bits(machInst, 3, 0) << 0);
809
810        // Check for invalid immediate encodings and return an unknown op
811        // if it happens
812        bool immValid = true;
813        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
814        if (!immValid) {
815            return new Unknown(machInst);
816        }
817
818        if (op) {
819            if (bits(cmode, 3) == 0) {
820                if (bits(cmode, 0) == 0) {
821                    if (q)
822                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
823                    else
824                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
825                } else {
826                    if (q)
827                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
828                    else
829                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
830                }
831            } else {
832                if (bits(cmode, 2) == 1) {
833                    switch (bits(cmode, 1, 0)) {
834                      case 0:
835                      case 1:
836                        if (q)
837                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
838                        else
839                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
840                      case 2:
841                        if (q)
842                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
843                        else
844                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
845                      case 3:
846                        if (q)
847                            return new Unknown(machInst);
848                        else
849                            return new Unknown(machInst);
850                    }
851                } else {
852                    if (bits(cmode, 0) == 0) {
853                        if (q)
854                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
855                        else
856                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
857                    } else {
858                        if (q)
859                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
860                        else
861                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
862                    }
863                }
864            }
865        } else {
866            if (bits(cmode, 3) == 0) {
867                if (bits(cmode, 0) == 0) {
868                    if (q)
869                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
870                    else
871                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
872                } else {
873                    if (q)
874                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
875                    else
876                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
877                }
878            } else {
879                if (bits(cmode, 2) == 1) {
880                    if (q)
881                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
882                    else
883                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
884                } else {
885                    if (bits(cmode, 0) == 0) {
886                        if (q)
887                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
888                        else
889                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
890                    } else {
891                        if (q)
892                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
893                        else
894                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
895                    }
896                }
897            }
898        }
899        return new Unknown(machInst);
900    }
901
902    static StaticInstPtr
903    decodeNeonTwoRegAndShift(ExtMachInst machInst)
904    {
905        const uint32_t opc = bits(machInst, 11, 8);
906        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
907        const bool q = bits(machInst, 6);
908        const bool l = bits(machInst, 7);
909        const IntRegIndex vd =
910            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
911                               (bits(machInst, 22) << 4)));
912        const IntRegIndex vm =
913            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
914                               (bits(machInst, 5) << 4)));
915        unsigned imm6 = bits(machInst, 21, 16);
916        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
917        unsigned size = 3;
918        unsigned lShiftAmt = 0;
919        unsigned bitSel;
920        for (bitSel = 1 << 6; true; bitSel >>= 1) {
921            if (bitSel & imm)
922                break;
923            else if (!size)
924                return new Unknown(machInst);
925            size--;
926        }
927        lShiftAmt = imm6 & ~bitSel;
928        unsigned rShiftAmt = 0;
929        if (opc != 0xe && opc != 0xf) {
930            if (size > 2)
931                rShiftAmt = 64 - imm6;
932            else
933                rShiftAmt = 2 * (8 << size) - imm6;
934        }
935
936        switch (opc) {
937          case 0x0:
938            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
939                    q, u, size, machInst, vd, vm, rShiftAmt);
940          case 0x1:
941            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
942                    q, u, size, machInst, vd, vm, rShiftAmt);
943          case 0x2:
944            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
945                    q, u, size, machInst, vd, vm, rShiftAmt);
946          case 0x3:
947            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
948                    q, u, size, machInst, vd, vm, rShiftAmt);
949          case 0x4:
950            if (u) {
951                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
952                        q, size, machInst, vd, vm, rShiftAmt);
953            } else {
954                return new Unknown(machInst);
955            }
956          case 0x5:
957            if (u) {
958                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
959                        q, size, machInst, vd, vm, lShiftAmt);
960            } else {
961                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
962                        q, size, machInst, vd, vm, lShiftAmt);
963            }
964          case 0x6:
965          case 0x7:
966            if (u) {
967                if (opc == 0x6) {
968                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
969                            q, size, machInst, vd, vm, lShiftAmt);
970                } else {
971                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
972                            q, size, machInst, vd, vm, lShiftAmt);
973                }
974            } else {
975                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
976                        q, size, machInst, vd, vm, lShiftAmt);
977            }
978          case 0x8:
979            if (l) {
980                return new Unknown(machInst);
981            } else if (u) {
982                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
983                        q, size, machInst, vd, vm, rShiftAmt);
984            } else {
985                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
986                        q, size, machInst, vd, vm, rShiftAmt);
987            }
988          case 0x9:
989            if (l) {
990                return new Unknown(machInst);
991            } else if (u) {
992                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
993                        q, size, machInst, vd, vm, rShiftAmt);
994            } else {
995                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
996                        q, size, machInst, vd, vm, rShiftAmt);
997            }
998          case 0xa:
999            if (l || q) {
1000                return new Unknown(machInst);
1001            } else {
1002                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
1003                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
1004            }
1005          case 0xe:
1006            if (l) {
1007                return new Unknown(machInst);
1008            } else {
1009                if (bits(imm6, 5) == 0)
1010                    return new Unknown(machInst);
1011                if (u) {
1012                    if (q) {
1013                        return new NVcvtu2fpQ<float>(
1014                                machInst, vd, vm, 64 - imm6);
1015                    } else {
1016                        return new NVcvtu2fpD<float>(
1017                                machInst, vd, vm, 64 - imm6);
1018                    }
1019                } else {
1020                    if (q) {
1021                        return new NVcvts2fpQ<float>(
1022                                machInst, vd, vm, 64 - imm6);
1023                    } else {
1024                        return new NVcvts2fpD<float>(
1025                                machInst, vd, vm, 64 - imm6);
1026                    }
1027                }
1028            }
1029          case 0xf:
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 NVcvt2ufxQ<float>(
1038                                machInst, vd, vm, 64 - imm6);
1039                    } else {
1040                        return new NVcvt2ufxD<float>(
1041                                machInst, vd, vm, 64 - imm6);
1042                    }
1043                } else {
1044                    if (q) {
1045                        return new NVcvt2sfxQ<float>(
1046                                machInst, vd, vm, 64 - imm6);
1047                    } else {
1048                        return new NVcvt2sfxD<float>(
1049                                machInst, vd, vm, 64 - imm6);
1050                    }
1051                }
1052            }
1053        }
1054        return new Unknown(machInst);
1055    }
1056
1057    static StaticInstPtr
1058    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1059    {
1060        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1061        const uint32_t opc = bits(machInst, 11, 8);
1062        const IntRegIndex vd =
1063            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1064                               (bits(machInst, 22) << 4)));
1065        const IntRegIndex vn =
1066            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1067                               (bits(machInst, 7) << 4)));
1068        const IntRegIndex vm =
1069            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1070                               (bits(machInst, 5) << 4)));
1071        const unsigned size = bits(machInst, 21, 20);
1072        switch (opc) {
1073          case 0x0:
1074            return decodeNeonUSThreeUSReg<Vaddl>(
1075                    u, size, machInst, vd, vn, vm);
1076          case 0x1:
1077            return decodeNeonUSThreeUSReg<Vaddw>(
1078                    u, size, machInst, vd, vn, vm);
1079          case 0x2:
1080            return decodeNeonUSThreeUSReg<Vsubl>(
1081                    u, size, machInst, vd, vn, vm);
1082          case 0x3:
1083            return decodeNeonUSThreeUSReg<Vsubw>(
1084                    u, size, machInst, vd, vn, vm);
1085          case 0x4:
1086            if (u) {
1087                return decodeNeonUThreeUSReg<Vraddhn>(
1088                        size, machInst, vd, vn, vm);
1089            } else {
1090                return decodeNeonUThreeUSReg<Vaddhn>(
1091                        size, machInst, vd, vn, vm);
1092            }
1093          case 0x5:
1094            return decodeNeonUSThreeUSReg<Vabal>(
1095                    u, size, machInst, vd, vn, vm);
1096          case 0x6:
1097            if (u) {
1098                return decodeNeonUThreeUSReg<Vrsubhn>(
1099                        size, machInst, vd, vn, vm);
1100            } else {
1101                return decodeNeonUThreeUSReg<Vsubhn>(
1102                        size, machInst, vd, vn, vm);
1103            }
1104          case 0x7:
1105            if (bits(machInst, 23)) {
1106                return decodeNeonUSThreeUSReg<Vabdl>(
1107                        u, size, machInst, vd, vn, vm);
1108            } else {
1109                return decodeNeonUSThreeReg<VabdD, VabdQ>(
1110                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
1111            }
1112          case 0x8:
1113            return decodeNeonUSThreeUSReg<Vmlal>(
1114                    u, size, machInst, vd, vn, vm);
1115          case 0xa:
1116            return decodeNeonUSThreeUSReg<Vmlsl>(
1117                    u, size, machInst, vd, vn, vm);
1118          case 0x9:
1119            if (u) {
1120                return new Unknown(machInst);
1121            } else {
1122                return decodeNeonSThreeUSReg<Vqdmlal>(
1123                        size, machInst, vd, vn, vm);
1124            }
1125          case 0xb:
1126            if (u) {
1127                return new Unknown(machInst);
1128            } else {
1129                return decodeNeonSThreeUSReg<Vqdmlsl>(
1130                        size, machInst, vd, vn, vm);
1131            }
1132          case 0xc:
1133            return decodeNeonUSThreeUSReg<Vmull>(
1134                    u, size, machInst, vd, vn, vm);
1135          case 0xd:
1136            if (u) {
1137                return new Unknown(machInst);
1138            } else {
1139                return decodeNeonSThreeUSReg<Vqdmull>(
1140                        size, machInst, vd, vn, vm);
1141            }
1142          case 0xe:
1143            return decodeNeonUThreeUSReg<Vmullp>(
1144                    size, machInst, vd, vn, vm);
1145        }
1146        return new Unknown(machInst);
1147    }
1148
1149    static StaticInstPtr
1150    decodeNeonTwoRegScalar(ExtMachInst machInst)
1151    {
1152        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1153        const uint32_t opc = bits(machInst, 11, 8);
1154        const unsigned size = bits(machInst, 21, 20);
1155        const IntRegIndex vd =
1156            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1157                               (bits(machInst, 22) << 4)));
1158        const IntRegIndex vn =
1159            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1160                               (bits(machInst, 7) << 4)));
1161        const IntRegIndex vm = (size == 2) ?
1162            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1163            (IntRegIndex)(2 * bits(machInst, 2, 0));
1164        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1165            (bits(machInst, 3) | (bits(machInst, 5) << 1));
1166        switch (opc) {
1167          case 0x0:
1168            if (u) {
1169                switch (size) {
1170                  case 1:
1171                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1172                  case 2:
1173                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1174                  default:
1175                    return new Unknown(machInst);
1176                }
1177            } else {
1178                switch (size) {
1179                  case 1:
1180                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1181                  case 2:
1182                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1183                  default:
1184                    return new Unknown(machInst);
1185                }
1186            }
1187          case 0x1:
1188            if (u)
1189                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1190            else
1191                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1192          case 0x4:
1193            if (u) {
1194                switch (size) {
1195                  case 1:
1196                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1197                  case 2:
1198                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1199                  default:
1200                    return new Unknown(machInst);
1201                }
1202            } else {
1203                switch (size) {
1204                  case 1:
1205                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1206                  case 2:
1207                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1208                  default:
1209                    return new Unknown(machInst);
1210                }
1211            }
1212          case 0x5:
1213            if (u)
1214                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1215            else
1216                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1217          case 0x2:
1218            if (u) {
1219                switch (size) {
1220                  case 1:
1221                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1222                  case 2:
1223                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1224                  default:
1225                    return new Unknown(machInst);
1226                }
1227            } else {
1228                switch (size) {
1229                  case 1:
1230                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1231                  case 2:
1232                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1233                  default:
1234                    return new Unknown(machInst);
1235                }
1236            }
1237          case 0x6:
1238            if (u) {
1239                switch (size) {
1240                  case 1:
1241                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1242                  case 2:
1243                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1244                  default:
1245                    return new Unknown(machInst);
1246                }
1247            } else {
1248                switch (size) {
1249                  case 1:
1250                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1251                  case 2:
1252                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1253                  default:
1254                    return new Unknown(machInst);
1255                }
1256            }
1257          case 0x3:
1258            if (u) {
1259                return new Unknown(machInst);
1260            } else {
1261                switch (size) {
1262                  case 1:
1263                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1264                  case 2:
1265                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1266                  default:
1267                    return new Unknown(machInst);
1268                }
1269            }
1270          case 0x7:
1271            if (u) {
1272                return new Unknown(machInst);
1273            } else {
1274                switch (size) {
1275                  case 1:
1276                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1277                  case 2:
1278                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1279                  default:
1280                    return new Unknown(machInst);
1281                }
1282            }
1283          case 0x8:
1284            if (u) {
1285                switch (size) {
1286                  case 1:
1287                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1288                  case 2:
1289                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1290                  default:
1291                    return new Unknown(machInst);
1292                }
1293            } else {
1294                switch (size) {
1295                  case 1:
1296                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1297                  case 2:
1298                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1299                  default:
1300                    return new Unknown(machInst);
1301                }
1302            }
1303          case 0x9:
1304            if (u)
1305                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1306            else
1307                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1308          case 0xa:
1309            if (u) {
1310                switch (size) {
1311                  case 1:
1312                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1313                  case 2:
1314                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1315                  default:
1316                    return new Unknown(machInst);
1317                }
1318            } else {
1319                switch (size) {
1320                  case 1:
1321                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1322                  case 2:
1323                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1324                  default:
1325                    return new Unknown(machInst);
1326                }
1327            }
1328          case 0xb:
1329            if (u) {
1330                return new Unknown(machInst);
1331            } else {
1332                if (u) {
1333                    switch (size) {
1334                      case 1:
1335                        return new Vqdmulls<uint16_t>(
1336                                machInst, vd, vn, vm, index);
1337                      case 2:
1338                        return new Vqdmulls<uint32_t>(
1339                                machInst, vd, vn, vm, index);
1340                      default:
1341                        return new Unknown(machInst);
1342                    }
1343                } else {
1344                    switch (size) {
1345                      case 1:
1346                        return new Vqdmulls<int16_t>(
1347                                machInst, vd, vn, vm, index);
1348                      case 2:
1349                        return new Vqdmulls<int32_t>(
1350                                machInst, vd, vn, vm, index);
1351                      default:
1352                        return new Unknown(machInst);
1353                    }
1354                }
1355            }
1356          case 0xc:
1357            if (u) {
1358                switch (size) {
1359                  case 1:
1360                    return new VqdmulhsQ<int16_t>(
1361                            machInst, vd, vn, vm, index);
1362                  case 2:
1363                    return new VqdmulhsQ<int32_t>(
1364                            machInst, vd, vn, vm, index);
1365                  default:
1366                    return new Unknown(machInst);
1367                }
1368            } else {
1369                switch (size) {
1370                  case 1:
1371                    return new VqdmulhsD<int16_t>(
1372                            machInst, vd, vn, vm, index);
1373                  case 2:
1374                    return new VqdmulhsD<int32_t>(
1375                            machInst, vd, vn, vm, index);
1376                  default:
1377                    return new Unknown(machInst);
1378                }
1379            }
1380          case 0xd:
1381            if (u) {
1382                switch (size) {
1383                  case 1:
1384                    return new VqrdmulhsQ<int16_t>(
1385                            machInst, vd, vn, vm, index);
1386                  case 2:
1387                    return new VqrdmulhsQ<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 VqrdmulhsD<int16_t>(
1396                            machInst, vd, vn, vm, index);
1397                  case 2:
1398                    return new VqrdmulhsD<int32_t>(
1399                            machInst, vd, vn, vm, index);
1400                  default:
1401                    return new Unknown(machInst);
1402                }
1403            }
1404        }
1405        return new Unknown(machInst);
1406    }
1407
1408    static StaticInstPtr
1409    decodeNeonTwoRegMisc(ExtMachInst machInst)
1410    {
1411        const uint32_t opc1 = bits(machInst, 17, 16);
1412        const uint32_t b = bits(machInst, 10, 6);
1413        const bool q = bits(machInst, 6);
1414        const IntRegIndex vd =
1415            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1416                               (bits(machInst, 22) << 4)));
1417        const IntRegIndex vm =
1418            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1419                               (bits(machInst, 5) << 4)));
1420        const unsigned size = bits(machInst, 19, 18);
1421        switch (opc1) {
1422          case 0x0:
1423            switch (bits(b, 4, 1)) {
1424              case 0x0:
1425                switch (size) {
1426                  case 0:
1427                    if (q) {
1428                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
1429                    } else {
1430                        return new NVrev64D<uint8_t>(machInst, vd, vm);
1431                    }
1432                  case 1:
1433                    if (q) {
1434                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
1435                    } else {
1436                        return new NVrev64D<uint16_t>(machInst, vd, vm);
1437                    }
1438                  case 2:
1439                    if (q) {
1440                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
1441                    } else {
1442                        return new NVrev64D<uint32_t>(machInst, vd, vm);
1443                    }
1444                  default:
1445                    return new Unknown(machInst);
1446                }
1447              case 0x1:
1448                switch (size) {
1449                  case 0:
1450                    if (q) {
1451                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
1452                    } else {
1453                        return new NVrev32D<uint8_t>(machInst, vd, vm);
1454                    }
1455                  case 1:
1456                    if (q) {
1457                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1458                    } else {
1459                        return new NVrev32D<uint16_t>(machInst, vd, vm);
1460                    }
1461                  default:
1462                    return new Unknown(machInst);
1463                }
1464              case 0x2:
1465                if (size != 0) {
1466                    return new Unknown(machInst);
1467                } else if (q) {
1468                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
1469                } else {
1470                    return new NVrev16D<uint8_t>(machInst, vd, vm);
1471                }
1472              case 0x4:
1473                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1474                        q, size, machInst, vd, vm);
1475              case 0x5:
1476                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1477                        q, size, machInst, vd, vm);
1478              case 0x6:
1479                if (q == 0) {
1480                    return new AESE(machInst, vd, vd, vm);
1481                } else {
1482                    return new AESD(machInst, vd, vd, vm);
1483                }
1484              case 0x7:
1485                if (q == 0) {
1486                    return new AESMC(machInst, vd, vm);
1487                } else {
1488                    return new AESIMC(machInst, vd, vm);
1489                }
1490              case 0x8:
1491                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1492                        q, size, machInst, vd, vm);
1493              case 0x9:
1494                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1495                        q, size, machInst, vd, vm);
1496              case 0xa:
1497                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1498                        q, size, machInst, vd, vm);
1499              case 0xb:
1500                if (q)
1501                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
1502                else
1503                    return new NVmvnD<uint64_t>(machInst, vd, vm);
1504              case 0xc:
1505                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1506                        q, size, machInst, vd, vm);
1507              case 0xd:
1508                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1509                        q, size, machInst, vd, vm);
1510              case 0xe:
1511                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1512                        q, size, machInst, vd, vm);
1513              case 0xf:
1514                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1515                        q, size, machInst, vd, vm);
1516              default:
1517                return new Unknown(machInst);
1518            }
1519          case 0x1:
1520            switch (bits(b, 3, 1)) {
1521              case 0x0:
1522                if (bits(b, 4)) {
1523                    if (q) {
1524                        return new NVcgtQFp<float>(machInst, vd, vm);
1525                    } else {
1526                        return new NVcgtDFp<float>(machInst, vd, vm);
1527                    }
1528                } else {
1529                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1530                            q, size, machInst, vd, vm);
1531                }
1532              case 0x1:
1533                if (bits(b, 4)) {
1534                    if (q) {
1535                        return new NVcgeQFp<float>(machInst, vd, vm);
1536                    } else {
1537                        return new NVcgeDFp<float>(machInst, vd, vm);
1538                    }
1539                } else {
1540                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1541                            q, size, machInst, vd, vm);
1542                }
1543              case 0x2:
1544                if (bits(b, 4)) {
1545                    if (q) {
1546                        return new NVceqQFp<float>(machInst, vd, vm);
1547                    } else {
1548                        return new NVceqDFp<float>(machInst, vd, vm);
1549                    }
1550                } else {
1551                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1552                            q, size, machInst, vd, vm);
1553                }
1554              case 0x3:
1555                if (bits(b, 4)) {
1556                    if (q) {
1557                        return new NVcleQFp<float>(machInst, vd, vm);
1558                    } else {
1559                        return new NVcleDFp<float>(machInst, vd, vm);
1560                    }
1561                } else {
1562                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1563                            q, size, machInst, vd, vm);
1564                }
1565              case 0x4:
1566                if (bits(b, 4)) {
1567                    if (q) {
1568                        return new NVcltQFp<float>(machInst, vd, vm);
1569                    } else {
1570                        return new NVcltDFp<float>(machInst, vd, vm);
1571                    }
1572                } else {
1573                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1574                            q, size, machInst, vd, vm);
1575                }
1576              case 0x5:
1577                if (q) {
1578                    return new SHA1H(machInst, vd, vm);
1579                } else {
1580                    return new Unknown(machInst);
1581                }
1582              case 0x6:
1583                if (bits(machInst, 10)) {
1584                    if (q)
1585                        return new NVabsQFp<float>(machInst, vd, vm);
1586                    else
1587                        return new NVabsDFp<float>(machInst, vd, vm);
1588                } else {
1589                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1590                            q, size, machInst, vd, vm);
1591                }
1592              case 0x7:
1593                if (bits(machInst, 10)) {
1594                    if (q)
1595                        return new NVnegQFp<float>(machInst, vd, vm);
1596                    else
1597                        return new NVnegDFp<float>(machInst, vd, vm);
1598                } else {
1599                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1600                            q, size, machInst, vd, vm);
1601                }
1602              default:
1603                return new Unknown64(machInst);
1604            }
1605          case 0x2:
1606            switch (bits(b, 4, 1)) {
1607              case 0x0:
1608                if (q)
1609                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1610                else
1611                    return new NVswpD<uint64_t>(machInst, vd, vm);
1612              case 0x1:
1613                return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1614                        q, size, machInst, vd, vm);
1615              case 0x2:
1616                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1617                        q, size, machInst, vd, vm);
1618              case 0x3:
1619                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1620                        q, size, machInst, vd, vm);
1621              case 0x4:
1622                if (b == 0x8) {
1623                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1624                            size, machInst, vd, vm);
1625                } else {
1626                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1627                            size, machInst, vd, vm);
1628                }
1629              case 0x5:
1630                if (q) {
1631                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1632                            size, machInst, vd, vm);
1633                } else {
1634                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1635                            size, machInst, vd, vm);
1636                }
1637              case 0x6:
1638                if (b == 0xc) {
1639                    return decodeNeonSTwoShiftUSReg<NVshll>(
1640                            size, machInst, vd, vm, 8 << size);
1641                } else {
1642                    return new Unknown(machInst);
1643                }
1644              case 0x7:
1645                if (q) {
1646                    return new SHA256SU0(machInst, vd, vm);
1647                } else {
1648                    return new SHA1SU1(machInst, vd, vm);
1649                }
1650              case 0xc:
1651              case 0xe:
1652                if (b == 0x18) {
1653                    if (size != 1 || (vm % 2))
1654                        return new Unknown(machInst);
1655                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1656                } else if (b == 0x1c) {
1657                    if (size != 1 || (vd % 2))
1658                        return new Unknown(machInst);
1659                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1660                } else {
1661                    return new Unknown(machInst);
1662                }
1663              default:
1664                return new Unknown(machInst);
1665            }
1666          case 0x3:
1667            if (bits(b, 4, 3) == 0x3) {
1668                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1669                    return new Unknown(machInst);
1670                } else {
1671                    if (bits(b, 2)) {
1672                        if (bits(b, 1)) {
1673                            if (q) {
1674                                return new NVcvt2ufxQ<float>(
1675                                        machInst, vd, vm, 0);
1676                            } else {
1677                                return new NVcvt2ufxD<float>(
1678                                        machInst, vd, vm, 0);
1679                            }
1680                        } else {
1681                            if (q) {
1682                                return new NVcvt2sfxQ<float>(
1683                                        machInst, vd, vm, 0);
1684                            } else {
1685                                return new NVcvt2sfxD<float>(
1686                                        machInst, vd, vm, 0);
1687                            }
1688                        }
1689                    } else {
1690                        if (bits(b, 1)) {
1691                            if (q) {
1692                                return new NVcvtu2fpQ<float>(
1693                                        machInst, vd, vm, 0);
1694                            } else {
1695                                return new NVcvtu2fpD<float>(
1696                                        machInst, vd, vm, 0);
1697                            }
1698                        } else {
1699                            if (q) {
1700                                return new NVcvts2fpQ<float>(
1701                                        machInst, vd, vm, 0);
1702                            } else {
1703                                return new NVcvts2fpD<float>(
1704                                        machInst, vd, vm, 0);
1705                            }
1706                        }
1707                    }
1708                }
1709            } else if ((b & 0x1a) == 0x10) {
1710                if (bits(b, 2)) {
1711                    if (q) {
1712                        return new NVrecpeQFp<float>(machInst, vd, vm);
1713                    } else {
1714                        return new NVrecpeDFp<float>(machInst, vd, vm);
1715                    }
1716                } else {
1717                    if (q) {
1718                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1719                    } else {
1720                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1721                    }
1722                }
1723            } else if ((b & 0x1a) == 0x12) {
1724                if (bits(b, 2)) {
1725                    if (q) {
1726                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1727                    } else {
1728                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1729                    }
1730                } else {
1731                    if (q) {
1732                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1733                    } else {
1734                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1735                    }
1736                }
1737            } else {
1738                return new Unknown(machInst);
1739            }
1740        }
1741        return new Unknown(machInst);
1742    }
1743
1744    StaticInstPtr
1745    decodeNeonData(ExtMachInst machInst)
1746    {
1747        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1748        const uint32_t a = bits(machInst, 23, 19);
1749        const uint32_t q = bits(machInst, 11, 8);
1750        const uint32_t c = bits(machInst, 7, 4);
1751        if (bits(a, 4) == 0) {
1752            return decodeNeonThreeRegistersSameLength(machInst);
1753        } else if ((c & 0x9) == 1) {
1754            if ((a & 0x7) == 0) {
1755                return decodeNeonOneRegModImm(machInst);
1756            } else {
1757                return decodeNeonTwoRegAndShift(machInst);
1758            }
1759        } else if ((c & 0x9) == 9) {
1760            return decodeNeonTwoRegAndShift(machInst);
1761        } else if (bits(a, 2, 1) != 0x3) {
1762            if ((c & 0x5) == 0) {
1763                return decodeNeonThreeRegDiffLengths(machInst);
1764            } else if ((c & 0x5) == 4) {
1765                return decodeNeonTwoRegScalar(machInst);
1766            }
1767        } else if ((a & 0x16) == 0x16) {
1768            const IntRegIndex vd =
1769                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1770                                   (bits(machInst, 22) << 4)));
1771            const IntRegIndex vn =
1772                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1773                                   (bits(machInst, 7) << 4)));
1774            const IntRegIndex vm =
1775                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1776                                   (bits(machInst, 5) << 4)));
1777            if (!u) {
1778                if (bits(c, 0) == 0) {
1779                    unsigned imm4 = bits(machInst, 11, 8);
1780                    bool q = bits(machInst, 6);
1781                    if (imm4 >= 16 && !q)
1782                        return new Unknown(machInst);
1783                    if (q) {
1784                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1785                    } else {
1786                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1787                    }
1788                }
1789            } else if (bits(q, 3) == 0 && bits(c, 0) == 0) {
1790                return decodeNeonTwoRegMisc(machInst);
1791            } else if (bits(q, 3, 2) == 0x2 && bits(c, 0) == 0) {
1792                unsigned length = bits(machInst, 9, 8) + 1;
1793                if ((uint32_t)vn / 2 + length > 32)
1794                    return new Unknown(machInst);
1795                if (bits(machInst, 6) == 0) {
1796                    switch (length) {
1797                      case 1:
1798                        return new NVtbl1(machInst, vd, vn, vm);
1799                      case 2:
1800                        return new NVtbl2(machInst, vd, vn, vm);
1801                      case 3:
1802                        return new NVtbl3(machInst, vd, vn, vm);
1803                      case 4:
1804                        return new NVtbl4(machInst, vd, vn, vm);
1805                    }
1806                } else {
1807                    switch (length) {
1808                      case 1:
1809                        return new NVtbx1(machInst, vd, vn, vm);
1810                      case 2:
1811                        return new NVtbx2(machInst, vd, vn, vm);
1812                      case 3:
1813                        return new NVtbx3(machInst, vd, vn, vm);
1814                      case 4:
1815                        return new NVtbx4(machInst, vd, vn, vm);
1816                    }
1817                }
1818            } else if (q == 0xc && (c & 0x9) == 0) {
1819                unsigned imm4 = bits(machInst, 19, 16);
1820                if (bits(imm4, 2, 0) == 0)
1821                    return new Unknown(machInst);
1822                unsigned size = 0;
1823                while ((imm4 & 0x1) == 0) {
1824                    size++;
1825                    imm4 >>= 1;
1826                }
1827                unsigned index = imm4 >> 1;
1828                const bool q = bits(machInst, 6);
1829                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1830                        q, size, machInst, vd, vm, index);
1831            }
1832        }
1833        return new Unknown(machInst);
1834    }
1835    '''
1836}};
1837
1838def format ThumbNeonMem() {{
1839    decode_block = '''
1840    return decodeNeonMem(machInst);
1841    '''
1842}};
1843
1844def format ThumbNeonData() {{
1845    decode_block = '''
1846    return decodeNeonData(machInst);
1847    '''
1848}};
1849
1850let {{
1851    header_output = '''
1852    StaticInstPtr
1853    decodeExtensionRegLoadStore(ExtMachInst machInst);
1854    '''
1855    decoder_output = '''
1856    StaticInstPtr
1857    decodeExtensionRegLoadStore(ExtMachInst machInst)
1858    {
1859        const uint32_t opcode = bits(machInst, 24, 20);
1860        const uint32_t offset = bits(machInst, 7, 0);
1861        const bool single = (bits(machInst, 8) == 0);
1862        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1863        RegIndex vd;
1864        if (single) {
1865            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1866                                      bits(machInst, 22));
1867        } else {
1868            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1869                                      (bits(machInst, 22) << 5));
1870        }
1871        switch (bits(opcode, 4, 3)) {
1872          case 0x0:
1873            if (bits(opcode, 4, 1) == 0x2 &&
1874                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1875                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1876                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1877                    break;
1878                }
1879                const IntRegIndex rt =
1880                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1881                const IntRegIndex rt2 =
1882                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1883                const bool op = bits(machInst, 20);
1884                uint32_t vm;
1885                if (single) {
1886                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1887                } else {
1888                    vm = (bits(machInst, 3, 0) << 1) |
1889                         (bits(machInst, 5) << 5);
1890                }
1891                if (op) {
1892                    return new Vmov2Core2Reg(machInst, rt, rt2,
1893                                             (IntRegIndex)vm);
1894                } else {
1895                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1896                                             rt, rt2);
1897                }
1898            }
1899            break;
1900          case 0x1:
1901            {
1902                if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1903                    break;
1904                }
1905                switch (bits(opcode, 1, 0)) {
1906                  case 0x0:
1907                    return new VLdmStm(machInst, rn, vd, single,
1908                                       true, false, false, offset);
1909                  case 0x1:
1910                    return new VLdmStm(machInst, rn, vd, single,
1911                                       true, false, true, offset);
1912                  case 0x2:
1913                    return new VLdmStm(machInst, rn, vd, single,
1914                                       true, true, false, offset);
1915                  case 0x3:
1916                    // If rn == sp, then this is called vpop.
1917                    return new VLdmStm(machInst, rn, vd, single,
1918                                       true, true, true, offset);
1919                  default:
1920                    M5_UNREACHABLE;
1921                }
1922            }
1923          case 0x2:
1924            if (bits(opcode, 1, 0) == 0x2) {
1925                // If rn == sp, then this is called vpush.
1926                return new VLdmStm(machInst, rn, vd, single,
1927                                   false, true, false, offset);
1928            } else if (bits(opcode, 1, 0) == 0x3) {
1929                return new VLdmStm(machInst, rn, vd, single,
1930                                   false, true, true, offset);
1931            }
1932            M5_FALLTHROUGH;
1933          case 0x3:
1934            const bool up = (bits(machInst, 23) == 1);
1935            const uint32_t imm = bits(machInst, 7, 0) << 2;
1936            if (single) {
1937                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1938                                          (bits(machInst, 22)));
1939            } else {
1940                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1941                                          (bits(machInst, 22) << 5));
1942            }
1943            if (bits(opcode, 1, 0) == 0x0) {
1944                if (single) {
1945                    if (up) {
1946                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1947                    } else {
1948                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1949                    }
1950                } else {
1951                    if (up) {
1952                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1953                                               rn, up, imm);
1954                    } else {
1955                        return new %(vstr_d)s(machInst, vd, vd + 1,
1956                                              rn, up, imm);
1957                    }
1958                }
1959            } else if (bits(opcode, 1, 0) == 0x1) {
1960                if (single) {
1961                    if (up) {
1962                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1963                    } else {
1964                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1965                    }
1966                } else {
1967                    if (up) {
1968                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1969                                               rn, up, imm);
1970                    } else {
1971                        return new %(vldr_d)s(machInst, vd, vd + 1,
1972                                              rn, up, imm);
1973                    }
1974                }
1975            }
1976        }
1977        return new Unknown(machInst);
1978    }
1979    ''' % {
1980        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1981        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1982        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1983        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1984        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1985        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1986        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1987        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1988    }
1989}};
1990
1991def format ExtensionRegLoadStore() {{
1992    decode_block = '''
1993    return decodeExtensionRegLoadStore(machInst);
1994    '''
1995}};
1996
1997let {{
1998    header_output = '''
1999    StaticInstPtr
2000    decodeShortFpTransfer(ExtMachInst machInst);
2001    '''
2002    decoder_output = '''
2003    IntRegIndex decodeFpVd(ExtMachInst machInst, uint32_t size, bool isInt)
2004    {
2005        if (!isInt and size == 3) {
2006            return (IntRegIndex)((bits(machInst, 22) << 5) |
2007                               (bits(machInst, 15, 12) << 1));
2008        } else {
2009            return (IntRegIndex)(bits(machInst, 22) |
2010                              (bits(machInst, 15, 12) << 1));
2011        }
2012    }
2013    IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2014    {
2015        if (!isInt and size == 3) {
2016            return (IntRegIndex)((bits(machInst, 5) << 5) |
2017                               (bits(machInst, 3, 0) << 1));
2018        } else {
2019            return (IntRegIndex)(bits(machInst, 5) |
2020                              (bits(machInst, 3, 0) << 1));
2021        }
2022    }
2023    StaticInstPtr
2024    decodeShortFpTransfer(ExtMachInst machInst)
2025    {
2026        const uint32_t l = bits(machInst, 20);
2027        const uint32_t c = bits(machInst, 8);
2028        const uint32_t a = bits(machInst, 23, 21);
2029        const uint32_t q = bits(machInst, 6, 5);
2030        const uint32_t o1 = bits(machInst, 18);
2031        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2032            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2033            // Determine if this is backported aarch64 FP instruction
2034            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
2035            const bool b23 = bits(machInst, 23);
2036            const bool b21_b19 = bits(machInst, 21, 19) == 0x7;
2037            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
2038            const uint32_t size = bits(machInst, 9, 8);
2039            const bool op3 = bits(machInst, 6);
2040            const bool b4 = bits(machInst, 4) == 0x0;
2041            const uint32_t rm = bits(machInst, 17, 16);
2042            IntRegIndex vd = decodeFpVd(machInst, size, false);
2043            IntRegIndex vm = decodeFpVm(machInst, size, false);
2044            IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2045            if (b31_b24 && b23 && b21_b19 && b11_b9 && op3 && b4) {
2046                if (o1 == 0) {
2047                    // VINT* Integer Rounding Instruction
2048                    if (size == 3) {
2049                        switch(rm) {
2050                            case 0x0:
2051                            return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2052                                                                true);
2053                            case 0x1:
2054                            return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2055                                                                true);
2056                            case 0x2:
2057                            return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
2058                                                                true);
2059                            case 0x3:
2060                            return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
2061                                                                true);
2062                            default: return new Unknown(machInst);
2063                        }
2064                    } else {
2065                        switch(rm) {
2066                            case 0x0:
2067                            return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
2068                                                                false);
2069                            case 0x1:
2070                            return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2071                                                                false);
2072                            case 0x2:
2073                            return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2074                                                                false);
2075                            case 0x3:
2076                            return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2077                                                                false);
2078                            default: return new Unknown(machInst);
2079                        }
2080                    }
2081                } else {
2082                    const bool op = bits(machInst, 7);
2083                    switch(rm) {
2084                      case 0x0:
2085                        switch(size) {
2086                          case 0x0:
2087                            return new Unknown(machInst);
2088                          case 0x1:
2089                            return new FailUnimplemented(
2090                                "vcvta.u32.f16", machInst);
2091                          case 0x2:
2092                            if (op) {
2093                                return new VcvtaFpSIntS(machInst, vdInt, vm);
2094                            } else {
2095                                return new VcvtaFpUIntS(machInst, vdInt, vm);
2096                            }
2097                          case 0x3:
2098                            if (op) {
2099                                return new VcvtaFpSIntD(machInst, vdInt, vm);
2100                            } else {
2101                                return new VcvtaFpUIntD(machInst, vdInt, vm);
2102                            }
2103                          default: return new Unknown(machInst);
2104                        }
2105                      case 0x1:
2106                        switch(size) {
2107                          case 0x0:
2108                            return new Unknown(machInst);
2109                          case 0x1:
2110                            return new FailUnimplemented(
2111                                "vcvtn.u32.f16", machInst);
2112                          case 0x2:
2113                            if (op) {
2114                                return new VcvtnFpSIntS(machInst, vdInt, vm);
2115                            } else {
2116                                return new VcvtnFpUIntS(machInst, vdInt, vm);
2117                            }
2118                          case 0x3:
2119                            if (op) {
2120                                return new VcvtnFpSIntD(machInst, vdInt, vm);
2121                            } else {
2122                                return new VcvtnFpUIntD(machInst, vdInt, vm);
2123                            }
2124                          default: return new Unknown(machInst);
2125                        }
2126                      case 0x2:
2127                        switch(size) {
2128                          case 0x0:
2129                            return new Unknown(machInst);
2130                          case 0x1:
2131                            return new FailUnimplemented(
2132                                "vcvtp.u32.f16", machInst);
2133                          case 0x2:
2134                            if (op) {
2135                                return new VcvtpFpSIntS(machInst, vdInt, vm);
2136                            } else {
2137                                return new VcvtpFpUIntS(machInst, vdInt, vm);
2138                            }
2139                          case 0x3:
2140                            if (op) {
2141                                return new VcvtpFpSIntD(machInst, vdInt, vm);
2142                            } else {
2143                                return new VcvtpFpUIntD(machInst, vdInt, vm);
2144                            }
2145                          default: return new Unknown(machInst);
2146                        }
2147                      case 0x3:
2148                        switch(size) {
2149                          case 0x0:
2150                            return new Unknown(machInst);
2151                          case 0x1:
2152                            return new FailUnimplemented(
2153                                "vcvtm.u32.f16", machInst);
2154                          case 0x2:
2155                            if (op) {
2156                                return new VcvtmFpSIntS(machInst, vdInt, vm);
2157                            } else {
2158                                return new VcvtmFpUIntS(machInst, vdInt, vm);
2159                            }
2160                          case 0x3:
2161                            if (op) {
2162                                return new VcvtmFpSIntD(machInst, vdInt, vm);
2163                            } else {
2164                                return new VcvtmFpUIntD(machInst, vdInt, vm);
2165                            }
2166                          default: return new Unknown(machInst);
2167                        }
2168                      default: return new Unknown(machInst);
2169                    }
2170                }
2171            } else if (b31_b24 && !b23 && b11_b9 && !op3 && b4){
2172                // VSEL* floating point conditional select
2173
2174                ConditionCode cond;
2175                switch(bits(machInst, 21, 20)) {
2176                  case 0x0: cond = COND_EQ; break;
2177                  case 0x1: cond = COND_VS; break;
2178                  case 0x2: cond = COND_GE; break;
2179                  case 0x3: cond = COND_GT; break;
2180                }
2181
2182                if (size == 3) {
2183                      const IntRegIndex vn =
2184                          (IntRegIndex)((bits(machInst, 7) << 5) |
2185                                       (bits(machInst, 19, 16) << 1));
2186                    return new VselD(machInst, vd, vn, vm, cond);
2187                } else {
2188                      const IntRegIndex vn =
2189                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2190                                        bits(machInst, 7));
2191                      return new VselS(machInst, vd, vn, vm, cond);
2192                }
2193            } else {
2194                return new Unknown(machInst);
2195            }
2196        }
2197        if (l == 0 && c == 0) {
2198            if (a == 0) {
2199                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2200                                    bits(machInst, 7);
2201                const IntRegIndex rt =
2202                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2203                if (bits(machInst, 20) == 1) {
2204                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2205                } else {
2206                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2207                }
2208            } else if (a == 0x7) {
2209                const IntRegIndex rt =
2210                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2211                uint32_t reg = bits(machInst, 19, 16);
2212                uint32_t specReg;
2213                switch (reg) {
2214                  case 0:
2215                    specReg = MISCREG_FPSID;
2216                    break;
2217                  case 1:
2218                    specReg = MISCREG_FPSCR;
2219                    break;
2220                  case 6:
2221                    specReg = MISCREG_MVFR1;
2222                    break;
2223                  case 7:
2224                    specReg = MISCREG_MVFR0;
2225                    break;
2226                  case 8:
2227                    specReg = MISCREG_FPEXC;
2228                    break;
2229                  default:
2230                    return new Unknown(machInst);
2231                }
2232                if (specReg == MISCREG_FPSCR) {
2233                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2234                } else {
2235                    uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2236                        reg, a, bits(machInst, 7, 5));
2237                    return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2238                }
2239            }
2240        } else if (l == 0 && c == 1) {
2241            if (bits(a, 2) == 0) {
2242                uint32_t vd = (bits(machInst, 7) << 5) |
2243                              (bits(machInst, 19, 16) << 1);
2244                // Handle accessing each single precision half of the vector.
2245                vd += bits(machInst, 21);
2246                const IntRegIndex rt =
2247                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2248                if (bits(machInst, 22) == 1) {
2249                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2250                                            rt, bits(machInst, 6, 5));
2251                } else if (bits(machInst, 5) == 1) {
2252                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2253                                            rt, bits(machInst, 6));
2254                } else if (bits(machInst, 6) == 0) {
2255                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2256                } else {
2257                    return new Unknown(machInst);
2258                }
2259            } else if (bits(q, 1) == 0) {
2260                bool q = bits(machInst, 21);
2261                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2262                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2263                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2264                IntRegIndex rt = (IntRegIndex)(uint32_t)
2265                    bits(machInst, 15, 12);
2266                if (q) {
2267                    switch (be) {
2268                      case 0:
2269                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2270                      case 1:
2271                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2272                      case 2:
2273                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2274                      case 3:
2275                        return new Unknown(machInst);
2276                    }
2277                } else {
2278                    switch (be) {
2279                      case 0:
2280                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2281                      case 1:
2282                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2283                      case 2:
2284                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2285                      case 3:
2286                        return new Unknown(machInst);
2287                    }
2288                }
2289            }
2290        } else if (l == 1 && c == 0) {
2291            if (a == 0) {
2292                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2293                                    bits(machInst, 7);
2294                const IntRegIndex rt =
2295                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2296                if (bits(machInst, 20) == 1) {
2297                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2298                } else {
2299                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2300                }
2301            } else if (a == 7) {
2302                const IntRegIndex rt =
2303                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2304                uint32_t reg = bits(machInst, 19, 16);
2305                uint32_t specReg;
2306                switch (reg) {
2307                  case 0:
2308                    specReg = MISCREG_FPSID;
2309                    break;
2310                  case 1:
2311                    specReg = MISCREG_FPSCR;
2312                    break;
2313                  case 6:
2314                    specReg = MISCREG_MVFR1;
2315                    break;
2316                  case 7:
2317                    specReg = MISCREG_MVFR0;
2318                    break;
2319                  case 8:
2320                    specReg = MISCREG_FPEXC;
2321                    break;
2322                  default:
2323                    return new Unknown(machInst);
2324                }
2325                if (rt == 0xf) {
2326                    if (specReg == MISCREG_FPSCR) {
2327                        return new VmrsApsrFpscr(machInst);
2328                    } else {
2329                        return new Unknown(machInst);
2330                    }
2331                } else if (specReg == MISCREG_FPSCR) {
2332                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2333                } else {
2334                    uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2335                        reg, a, bits(machInst, 7, 5));
2336                    return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2337                }
2338            }
2339        } else {
2340            uint32_t vd = (bits(machInst, 7) << 5) |
2341                          (bits(machInst, 19, 16) << 1);
2342            // Handle indexing into each single precision half of the vector.
2343            vd += bits(machInst, 21);
2344            uint32_t index;
2345            const IntRegIndex rt =
2346                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2347            const bool u = (bits(machInst, 23) == 1);
2348            if (bits(machInst, 22) == 1) {
2349                index = bits(machInst, 6, 5);
2350                if (u) {
2351                    return new VmovRegCoreUB(machInst, rt,
2352                                             (IntRegIndex)vd, index);
2353                } else {
2354                    return new VmovRegCoreSB(machInst, rt,
2355                                             (IntRegIndex)vd, index);
2356                }
2357            } else if (bits(machInst, 5) == 1) {
2358                index = bits(machInst, 6);
2359                if (u) {
2360                    return new VmovRegCoreUH(machInst, rt,
2361                                             (IntRegIndex)vd, index);
2362                } else {
2363                    return new VmovRegCoreSH(machInst, rt,
2364                                             (IntRegIndex)vd, index);
2365                }
2366            } else if (bits(machInst, 6) == 0 && !u) {
2367                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2368            } else {
2369                return new Unknown(machInst);
2370            }
2371        }
2372        return new Unknown(machInst);
2373    }
2374    '''
2375}};
2376
2377def format ShortFpTransfer() {{
2378    decode_block = '''
2379    return decodeShortFpTransfer(machInst);
2380    '''
2381}};
2382
2383let {{
2384    header_output = '''
2385    StaticInstPtr
2386    decodeVfpData(ExtMachInst machInst);
2387    '''
2388    decoder_output = '''
2389    StaticInstPtr
2390    decodeVfpData(ExtMachInst machInst)
2391    {
2392        const uint32_t opc1 = bits(machInst, 23, 20);
2393        const uint32_t opc2 = bits(machInst, 19, 16);
2394        const uint32_t opc3 = bits(machInst, 7, 6);
2395        //const uint32_t opc4 = bits(machInst, 3, 0);
2396        const bool single = (bits(machInst, 8) == 0);
2397        // Used to select between vcmp and vcmpe.
2398        const bool e = (bits(machInst, 7) == 1);
2399        IntRegIndex vd;
2400        IntRegIndex vm;
2401        IntRegIndex vn;
2402        if (single) {
2403            vd = (IntRegIndex)(bits(machInst, 22) |
2404                    (bits(machInst, 15, 12) << 1));
2405            vm = (IntRegIndex)(bits(machInst, 5) |
2406                    (bits(machInst, 3, 0) << 1));
2407            vn = (IntRegIndex)(bits(machInst, 7) |
2408                    (bits(machInst, 19, 16) << 1));
2409        } else {
2410            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2411                    (bits(machInst, 15, 12) << 1));
2412            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2413                    (bits(machInst, 3, 0) << 1));
2414            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2415                    (bits(machInst, 19, 16) << 1));
2416        }
2417        switch (opc1 & 0xb /* 1011 */) {
2418          case 0x0:
2419            if (bits(machInst, 6) == 0) {
2420                if (single) {
2421                    return decodeVfpRegRegRegOp<VmlaS>(
2422                            machInst, vd, vn, vm, false);
2423                } else {
2424                    return decodeVfpRegRegRegOp<VmlaD>(
2425                            machInst, vd, vn, vm, true);
2426                }
2427            } else {
2428                if (single) {
2429                    return decodeVfpRegRegRegOp<VmlsS>(
2430                            machInst, vd, vn, vm, false);
2431                } else {
2432                    return decodeVfpRegRegRegOp<VmlsD>(
2433                            machInst, vd, vn, vm, true);
2434                }
2435            }
2436          case 0x1:
2437            if (bits(machInst, 6) == 1) {
2438                if (single) {
2439                    return decodeVfpRegRegRegOp<VnmlaS>(
2440                            machInst, vd, vn, vm, false);
2441                } else {
2442                    return decodeVfpRegRegRegOp<VnmlaD>(
2443                            machInst, vd, vn, vm, true);
2444                }
2445            } else {
2446                if (single) {
2447                    return decodeVfpRegRegRegOp<VnmlsS>(
2448                            machInst, vd, vn, vm, false);
2449                } else {
2450                    return decodeVfpRegRegRegOp<VnmlsD>(
2451                            machInst, vd, vn, vm, true);
2452                }
2453            }
2454          case 0x2:
2455            if ((opc3 & 0x1) == 0) {
2456                if (single) {
2457                    return decodeVfpRegRegRegOp<VmulS>(
2458                            machInst, vd, vn, vm, false);
2459                } else {
2460                    return decodeVfpRegRegRegOp<VmulD>(
2461                            machInst, vd, vn, vm, true);
2462                }
2463            } else {
2464                if (single) {
2465                    return decodeVfpRegRegRegOp<VnmulS>(
2466                            machInst, vd, vn, vm, false);
2467                } else {
2468                    return decodeVfpRegRegRegOp<VnmulD>(
2469                            machInst, vd, vn, vm, true);
2470                }
2471            }
2472          case 0x3:
2473            if ((opc3 & 0x1) == 0) {
2474                if (single) {
2475                    return decodeVfpRegRegRegOp<VaddS>(
2476                            machInst, vd, vn, vm, false);
2477                } else {
2478                    return decodeVfpRegRegRegOp<VaddD>(
2479                            machInst, vd, vn, vm, true);
2480                }
2481            } else {
2482                if (single) {
2483                    return decodeVfpRegRegRegOp<VsubS>(
2484                            machInst, vd, vn, vm, false);
2485                } else {
2486                    return decodeVfpRegRegRegOp<VsubD>(
2487                            machInst, vd, vn, vm, true);
2488                }
2489            }
2490          case 0x8:
2491            if ((opc3 & 0x1) == 0) {
2492                if (single) {
2493                    return decodeVfpRegRegRegOp<VdivS>(
2494                            machInst, vd, vn, vm, false);
2495                } else {
2496                    return decodeVfpRegRegRegOp<VdivD>(
2497                            machInst, vd, vn, vm, true);
2498                }
2499            }
2500            break;
2501          case 0x9:
2502            if ((opc3 & 0x1) == 0) {
2503                if (single) {
2504                    return decodeVfpRegRegRegOp<VfnmaS>(
2505                            machInst, vd, vn, vm, false);
2506                } else {
2507                    return decodeVfpRegRegRegOp<VfnmaD>(
2508                            machInst, vd, vn, vm, true);
2509                }
2510            } else {
2511                if (single) {
2512                    return decodeVfpRegRegRegOp<VfnmsS>(
2513                            machInst, vd, vn, vm, false);
2514                } else {
2515                    return decodeVfpRegRegRegOp<VfnmsD>(
2516                            machInst, vd, vn, vm, true);
2517                }
2518            }
2519            break;
2520          case 0xa:
2521            if ((opc3 & 0x1) == 0) {
2522                if (single) {
2523                    return decodeVfpRegRegRegOp<VfmaS>(
2524                            machInst, vd, vn, vm, false);
2525                } else {
2526                    return decodeVfpRegRegRegOp<VfmaD>(
2527                            machInst, vd, vn, vm, true);
2528                }
2529            } else {
2530                if (single) {
2531                    return decodeVfpRegRegRegOp<VfmsS>(
2532                            machInst, vd, vn, vm, false);
2533                } else {
2534                    return decodeVfpRegRegRegOp<VfmsD>(
2535                            machInst, vd, vn, vm, true);
2536                }
2537            }
2538            break;
2539          case 0xb:
2540            if ((opc3 & 0x1) == 0) {
2541                const uint32_t baseImm =
2542                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2543                if (single) {
2544                    uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32);
2545                    return decodeVfpRegImmOp<VmovImmS>(
2546                            machInst, vd, imm, false);
2547                } else {
2548                    uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64);
2549                    return decodeVfpRegImmOp<VmovImmD>(
2550                            machInst, vd, imm, true);
2551                }
2552            }
2553            switch (opc2) {
2554              case 0x0:
2555                if (opc3 == 1) {
2556                    if (single) {
2557                        return decodeVfpRegRegOp<VmovRegS>(
2558                                machInst, vd, vm, false);
2559                    } else {
2560                        return decodeVfpRegRegOp<VmovRegD>(
2561                                machInst, vd, vm, true);
2562                    }
2563                } else {
2564                    if (single) {
2565                        return decodeVfpRegRegOp<VabsS>(
2566                                machInst, vd, vm, false);
2567                    } else {
2568                        return decodeVfpRegRegOp<VabsD>(
2569                                machInst, vd, vm, true);
2570                    }
2571                }
2572              case 0x1:
2573                if (opc3 == 1) {
2574                    if (single) {
2575                        return decodeVfpRegRegOp<VnegS>(
2576                                machInst, vd, vm, false);
2577                    } else {
2578                        return decodeVfpRegRegOp<VnegD>(
2579                                machInst, vd, vm, true);
2580                    }
2581                } else {
2582                    if (single) {
2583                        return decodeVfpRegRegOp<VsqrtS>(
2584                                machInst, vd, vm, false);
2585                    } else {
2586                        return decodeVfpRegRegOp<VsqrtD>(
2587                                machInst, vd, vm, true);
2588                    }
2589                }
2590              case 0x2:
2591              case 0x3:
2592                {
2593                    const bool toHalf = bits(machInst, 16);
2594                    const bool top = bits(machInst, 7);
2595                    if (top) {
2596                        if (toHalf) {
2597                            return new VcvtFpSFpHT(machInst, vd, vm);
2598                        } else {
2599                            return new VcvtFpHTFpS(machInst, vd, vm);
2600                        }
2601                    } else {
2602                        if (toHalf) {
2603                            return new VcvtFpSFpHB(machInst, vd, vm);
2604                        } else {
2605                            return new VcvtFpHBFpS(machInst, vd, vm);
2606                        }
2607                    }
2608                }
2609              case 0x4:
2610                if (single) {
2611                    if (e) {
2612                        return new VcmpeS(machInst, vd, vm);
2613                    } else {
2614                        return new VcmpS(machInst, vd, vm);
2615                    }
2616                } else {
2617                    if (e) {
2618                        return new VcmpeD(machInst, vd, vm);
2619                    } else {
2620                        return new VcmpD(machInst, vd, vm);
2621                    }
2622                }
2623              case 0x5:
2624                if (single) {
2625                    if (e) {
2626                        return new VcmpeZeroS(machInst, vd, 0);
2627                    } else {
2628                        return new VcmpZeroS(machInst, vd, 0);
2629                    }
2630                } else {
2631                    if (e) {
2632                        return new VcmpeZeroD(machInst, vd, 0);
2633                    } else {
2634                        return new VcmpZeroD(machInst, vd, 0);
2635                    }
2636                }
2637              case 0x7:
2638                if (opc3 == 0x3) {
2639                    if (single) {
2640                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2641                                (bits(machInst, 15, 12) << 1));
2642                        return new VcvtFpSFpD(machInst, vd, vm);
2643                    } else {
2644                        vd = (IntRegIndex)(bits(machInst, 22) |
2645                                (bits(machInst, 15, 12) << 1));
2646                        return new VcvtFpDFpS(machInst, vd, vm);
2647                    }
2648                }
2649                break;
2650              case 0x8:
2651                if (bits(machInst, 7) == 0) {
2652                    if (single) {
2653                        return new VcvtUIntFpS(machInst, vd, vm);
2654                    } else {
2655                        vm = (IntRegIndex)(bits(machInst, 5) |
2656                                (bits(machInst, 3, 0) << 1));
2657                        return new VcvtUIntFpD(machInst, vd, vm);
2658                    }
2659                } else {
2660                    if (single) {
2661                        return new VcvtSIntFpS(machInst, vd, vm);
2662                    } else {
2663                        vm = (IntRegIndex)(bits(machInst, 5) |
2664                                (bits(machInst, 3, 0) << 1));
2665                        return new VcvtSIntFpD(machInst, vd, vm);
2666                    }
2667                }
2668              case 0xa:
2669                {
2670                    const bool half = (bits(machInst, 7) == 0);
2671                    const uint32_t imm = bits(machInst, 5) |
2672                                         (bits(machInst, 3, 0) << 1);
2673                    const uint32_t size =
2674                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2675                    if (single) {
2676                        if (half) {
2677                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2678                        } else {
2679                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2680                        }
2681                    } else {
2682                        if (half) {
2683                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2684                        } else {
2685                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2686                        }
2687                    }
2688                }
2689              case 0xb:
2690                {
2691                    const bool half = (bits(machInst, 7) == 0);
2692                    const uint32_t imm = bits(machInst, 5) |
2693                                         (bits(machInst, 3, 0) << 1);
2694                    const uint32_t size =
2695                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2696                    if (single) {
2697                        if (half) {
2698                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2699                        } else {
2700                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2701                        }
2702                    } else {
2703                        if (half) {
2704                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2705                        } else {
2706                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2707                        }
2708                    }
2709                }
2710              case 0xc:
2711                if (bits(machInst, 7) == 0) {
2712                    if (single) {
2713                        return new VcvtFpUIntSR(machInst, vd, vm);
2714                    } else {
2715                        vd = (IntRegIndex)(bits(machInst, 22) |
2716                                (bits(machInst, 15, 12) << 1));
2717                        return new VcvtFpUIntDR(machInst, vd, vm);
2718                    }
2719                } else {
2720                    if (single) {
2721                        return new VcvtFpUIntS(machInst, vd, vm);
2722                    } else {
2723                        vd = (IntRegIndex)(bits(machInst, 22) |
2724                                (bits(machInst, 15, 12) << 1));
2725                        return new VcvtFpUIntD(machInst, vd, vm);
2726                    }
2727                }
2728              case 0xd:
2729                if (bits(machInst, 7) == 0) {
2730                    if (single) {
2731                        return new VcvtFpSIntSR(machInst, vd, vm);
2732                    } else {
2733                        vd = (IntRegIndex)(bits(machInst, 22) |
2734                                (bits(machInst, 15, 12) << 1));
2735                        return new VcvtFpSIntDR(machInst, vd, vm);
2736                    }
2737                } else {
2738                    if (single) {
2739                        return new VcvtFpSIntS(machInst, vd, vm);
2740                    } else {
2741                        vd = (IntRegIndex)(bits(machInst, 22) |
2742                                (bits(machInst, 15, 12) << 1));
2743                        return new VcvtFpSIntD(machInst, vd, vm);
2744                    }
2745                }
2746              case 0xe:
2747                {
2748                    const bool half = (bits(machInst, 7) == 0);
2749                    const uint32_t imm = bits(machInst, 5) |
2750                                         (bits(machInst, 3, 0) << 1);
2751                    const uint32_t size =
2752                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2753                    if (single) {
2754                        if (half) {
2755                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2756                        } else {
2757                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2758                        }
2759                    } else {
2760                        if (half) {
2761                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2762                        } else {
2763                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2764                        }
2765                    }
2766                }
2767              case 0xf:
2768                {
2769                    const bool half = (bits(machInst, 7) == 0);
2770                    const uint32_t imm = bits(machInst, 5) |
2771                                         (bits(machInst, 3, 0) << 1);
2772                    const uint32_t size =
2773                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2774                    if (single) {
2775                        if (half) {
2776                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2777                        } else {
2778                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2779                        }
2780                    } else {
2781                        if (half) {
2782                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2783                        } else {
2784                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2785                        }
2786                    }
2787                }
2788            }
2789            break;
2790        }
2791        return new Unknown(machInst);
2792    }
2793    '''
2794}};
2795
2796def format VfpData() {{
2797    decode_block = '''
2798    return decodeVfpData(machInst);
2799    '''
2800}};
2801