fp.isa revision 12595
17322Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27322Sgblack@eecs.umich.edu
37322Sgblack@eecs.umich.edu// Copyright (c) 2010-2011,2016 ARM Limited
47322Sgblack@eecs.umich.edu// All rights reserved
57322Sgblack@eecs.umich.edu//
67322Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
77322Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
87322Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
97322Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
107322Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
117322Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
127322Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
137322Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
147322Sgblack@eecs.umich.edu//
157322Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University
167322Sgblack@eecs.umich.edu// All rights reserved.
177322Sgblack@eecs.umich.edu//
187322Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
197322Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
207322Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
217322Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
227322Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
237322Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
247322Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
257322Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
267322Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
277322Sgblack@eecs.umich.edu// this software without specific prior written permission.
287322Sgblack@eecs.umich.edu//
297322Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
307322Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
317322Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
327322Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
337322Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
347322Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
357322Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
367322Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
377322Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
387322Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
397322Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
407376Sgblack@eecs.umich.edu//
417376Sgblack@eecs.umich.edu// Authors: Stephen Hines
427376Sgblack@eecs.umich.edu
437376Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
447376Sgblack@eecs.umich.edu//
457376Sgblack@eecs.umich.edu// Floating Point operate instructions
467376Sgblack@eecs.umich.edu//
477376Sgblack@eecs.umich.edu
487376Sgblack@eecs.umich.eduoutput header {{
497376Sgblack@eecs.umich.edu
507376Sgblack@eecs.umich.edu    template<template <typename T> class Base>
517376Sgblack@eecs.umich.edu    StaticInstPtr
527376Sgblack@eecs.umich.edu    newNeonMemInst(const unsigned size,
537376Sgblack@eecs.umich.edu                   const ExtMachInst &machInst,
547376Sgblack@eecs.umich.edu                   const RegIndex dest, const RegIndex ra,
557376Sgblack@eecs.umich.edu                   const uint32_t imm, const unsigned extraMemFlags)
567376Sgblack@eecs.umich.edu    {
577376Sgblack@eecs.umich.edu        switch (size) {
587376Sgblack@eecs.umich.edu          case 0:
597376Sgblack@eecs.umich.edu            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
607376Sgblack@eecs.umich.edu          case 1:
617376Sgblack@eecs.umich.edu            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
627376Sgblack@eecs.umich.edu          case 2:
637376Sgblack@eecs.umich.edu            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
647376Sgblack@eecs.umich.edu          case 3:
657376Sgblack@eecs.umich.edu            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
667376Sgblack@eecs.umich.edu          default:
677376Sgblack@eecs.umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
687376Sgblack@eecs.umich.edu        }
697376Sgblack@eecs.umich.edu    }
707376Sgblack@eecs.umich.edu
717376Sgblack@eecs.umich.edu    template<template <typename T> class Base>
727376Sgblack@eecs.umich.edu    StaticInstPtr
737376Sgblack@eecs.umich.edu    newNeonMixInst(const unsigned size,
747376Sgblack@eecs.umich.edu                   const ExtMachInst &machInst,
757376Sgblack@eecs.umich.edu                   const RegIndex dest, const RegIndex op1,
767376Sgblack@eecs.umich.edu                   const uint32_t step)
777376Sgblack@eecs.umich.edu    {
787376Sgblack@eecs.umich.edu        switch (size) {
797376Sgblack@eecs.umich.edu          case 0:
807376Sgblack@eecs.umich.edu            return new Base<uint8_t>(machInst, dest, op1, step);
817376Sgblack@eecs.umich.edu          case 1:
827376Sgblack@eecs.umich.edu            return new Base<uint16_t>(machInst, dest, op1, step);
837376Sgblack@eecs.umich.edu          case 2:
847376Sgblack@eecs.umich.edu            return new Base<uint32_t>(machInst, dest, op1, step);
857376Sgblack@eecs.umich.edu          case 3:
867376Sgblack@eecs.umich.edu            return new Base<uint64_t>(machInst, dest, op1, step);
877376Sgblack@eecs.umich.edu          default:
887376Sgblack@eecs.umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
897376Sgblack@eecs.umich.edu        }
907376Sgblack@eecs.umich.edu    }
917376Sgblack@eecs.umich.edu
927376Sgblack@eecs.umich.edu}};
937376Sgblack@eecs.umich.edu
947376Sgblack@eecs.umich.edulet {{
957376Sgblack@eecs.umich.edu    header_output = '''
967376Sgblack@eecs.umich.edu    StaticInstPtr
977376Sgblack@eecs.umich.edu    decodeNeonMem(ExtMachInst machInst);
987376Sgblack@eecs.umich.edu
997376Sgblack@eecs.umich.edu    StaticInstPtr
1007376Sgblack@eecs.umich.edu    decodeNeonData(ExtMachInst machInst);
1017376Sgblack@eecs.umich.edu    '''
1027376Sgblack@eecs.umich.edu
1037376Sgblack@eecs.umich.edu    decoder_output = '''
1047376Sgblack@eecs.umich.edu    StaticInstPtr
1057376Sgblack@eecs.umich.edu    decodeNeonMem(ExtMachInst machInst)
1067376Sgblack@eecs.umich.edu    {
1077376Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 11, 8);
1087376Sgblack@eecs.umich.edu        const bool single = bits(machInst, 23);
1097376Sgblack@eecs.umich.edu        const bool singleAll = single && (bits(b, 3, 2) == 3);
1107376Sgblack@eecs.umich.edu        const bool load = bits(machInst, 21);
1117376Sgblack@eecs.umich.edu
1127376Sgblack@eecs.umich.edu        unsigned width = 0;
1137376Sgblack@eecs.umich.edu
1147376Sgblack@eecs.umich.edu        if (single) {
1157376Sgblack@eecs.umich.edu            width = bits(b, 1, 0) + 1;
1167376Sgblack@eecs.umich.edu        } else {
1177376Sgblack@eecs.umich.edu            switch (bits(b, 3, 1)) {
1187376Sgblack@eecs.umich.edu              case 0x0: width = 4;
1197376Sgblack@eecs.umich.edu                break;
1207376Sgblack@eecs.umich.edu              case 0x1: width = (b & 0x1) ? 2 : 1;
1217376Sgblack@eecs.umich.edu                break;
1227376Sgblack@eecs.umich.edu              case 0x2: width = 3;
1237376Sgblack@eecs.umich.edu                break;
1247376Sgblack@eecs.umich.edu              case 0x3: width = 1;
1257376Sgblack@eecs.umich.edu                break;
1267376Sgblack@eecs.umich.edu              case 0x4: width = 2;
1277376Sgblack@eecs.umich.edu                break;
1287376Sgblack@eecs.umich.edu              case 0x5:
1297376Sgblack@eecs.umich.edu                if ((b & 0x1) == 0) {
1307376Sgblack@eecs.umich.edu                    width = 1;
1317376Sgblack@eecs.umich.edu                    break;
1327376Sgblack@eecs.umich.edu                }
1337376Sgblack@eecs.umich.edu                M5_FALLTHROUGH;
1347376Sgblack@eecs.umich.edu              default:
1357376Sgblack@eecs.umich.edu                return new Unknown(machInst);
1367376Sgblack@eecs.umich.edu            }
1377376Sgblack@eecs.umich.edu        }
1387376Sgblack@eecs.umich.edu        assert(width > 0 && width <= 4);
1397376Sgblack@eecs.umich.edu
1407376Sgblack@eecs.umich.edu        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
1417376Sgblack@eecs.umich.edu        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
1427376Sgblack@eecs.umich.edu        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
1437376Sgblack@eecs.umich.edu                                                 bits(machInst, 22) << 4);
1447376Sgblack@eecs.umich.edu        const uint32_t type = bits(machInst, 11, 8);
1457376Sgblack@eecs.umich.edu        uint32_t size = 0;
1467376Sgblack@eecs.umich.edu        uint32_t align = TLB::MustBeOne;
1477376Sgblack@eecs.umich.edu        unsigned inc = 1;
1487376Sgblack@eecs.umich.edu        unsigned regs = 1;
1497376Sgblack@eecs.umich.edu        unsigned lane = 0;
1507376Sgblack@eecs.umich.edu        if (single) {
1517376Sgblack@eecs.umich.edu            if (singleAll) {
1527376Sgblack@eecs.umich.edu                size = bits(machInst, 7, 6);
1537376Sgblack@eecs.umich.edu                bool t = bits(machInst, 5);
1547376Sgblack@eecs.umich.edu                align = size | TLB::AllowUnaligned;
1557376Sgblack@eecs.umich.edu                if (width == 1) {
1567376Sgblack@eecs.umich.edu                    regs = t ? 2 : 1;
1577376Sgblack@eecs.umich.edu                    inc = 1;
1587376Sgblack@eecs.umich.edu                } else {
1597376Sgblack@eecs.umich.edu                    regs = width;
1607376Sgblack@eecs.umich.edu                    inc = t ? 2 : 1;
1617376Sgblack@eecs.umich.edu                }
1627376Sgblack@eecs.umich.edu                switch (width) {
1637376Sgblack@eecs.umich.edu                  case 1:
1647376Sgblack@eecs.umich.edu                  case 2:
1657376Sgblack@eecs.umich.edu                    if (bits(machInst, 4))
1667376Sgblack@eecs.umich.edu                        align = size + width - 1;
1677376Sgblack@eecs.umich.edu                    break;
1687376Sgblack@eecs.umich.edu                  case 3:
1697376Sgblack@eecs.umich.edu                    break;
1707376Sgblack@eecs.umich.edu                  case 4:
1717376Sgblack@eecs.umich.edu                    if (size == 3) {
1727376Sgblack@eecs.umich.edu                        if (bits(machInst, 4) == 0)
1737376Sgblack@eecs.umich.edu                            return new Unknown(machInst);
1747376Sgblack@eecs.umich.edu                        size = 2;
1757376Sgblack@eecs.umich.edu                        align = 0x4;
1767376Sgblack@eecs.umich.edu                    } else if (size == 2) {
1777376Sgblack@eecs.umich.edu                        if (bits(machInst, 4))
1787376Sgblack@eecs.umich.edu                            align = 0x3;
1797376Sgblack@eecs.umich.edu                    } else {
1807376Sgblack@eecs.umich.edu                        if (bits(machInst, 4))
1817376Sgblack@eecs.umich.edu                            align = size + 2;
1827376Sgblack@eecs.umich.edu                    }
1837376Sgblack@eecs.umich.edu                    break;
1847376Sgblack@eecs.umich.edu                }
1857376Sgblack@eecs.umich.edu            } else {
1867376Sgblack@eecs.umich.edu                size = bits(machInst, 11, 10);
1877376Sgblack@eecs.umich.edu                align = size | TLB::AllowUnaligned;
1887322Sgblack@eecs.umich.edu                regs = width;
1897322Sgblack@eecs.umich.edu                unsigned indexAlign = bits(machInst, 7, 4);
1907322Sgblack@eecs.umich.edu                // If width is 1, inc is always 1. That's overridden later.
1917322Sgblack@eecs.umich.edu                switch (size) {
1927322Sgblack@eecs.umich.edu                  case 0:
1937322Sgblack@eecs.umich.edu                    inc = 1;
1947375Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3, 1);
1957322Sgblack@eecs.umich.edu                    break;
1967322Sgblack@eecs.umich.edu                  case 1:
1977375Sgblack@eecs.umich.edu                    inc = bits(indexAlign, 1) ? 2 : 1;
1987375Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3, 2);
1997322Sgblack@eecs.umich.edu                    break;
2007324Sgblack@eecs.umich.edu                  case 2:
2017375Sgblack@eecs.umich.edu                    inc = bits(indexAlign, 2) ? 2 : 1;
2027324Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3);
2037324Sgblack@eecs.umich.edu                    break;
2047375Sgblack@eecs.umich.edu                }
2057375Sgblack@eecs.umich.edu                // Override inc for width of 1.
2067324Sgblack@eecs.umich.edu                if (width == 1) {
2077333Sgblack@eecs.umich.edu                    inc = 1;
2087333Sgblack@eecs.umich.edu                }
2097333Sgblack@eecs.umich.edu                switch (width) {
2107333Sgblack@eecs.umich.edu                  case 1:
2117375Sgblack@eecs.umich.edu                    switch (size) {
2127333Sgblack@eecs.umich.edu                      case 0:
2137333Sgblack@eecs.umich.edu                        break;
2147375Sgblack@eecs.umich.edu                      case 1:
2157375Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2167333Sgblack@eecs.umich.edu                            align = 1;
2177333Sgblack@eecs.umich.edu                        break;
2187333Sgblack@eecs.umich.edu                      case 2:
2197333Sgblack@eecs.umich.edu                        if (bits(indexAlign, 1, 0))
2207333Sgblack@eecs.umich.edu                            align = 2;
2217333Sgblack@eecs.umich.edu                        break;
2227375Sgblack@eecs.umich.edu                    }
2237333Sgblack@eecs.umich.edu                    break;
2247333Sgblack@eecs.umich.edu                  case 2:
2257375Sgblack@eecs.umich.edu                    if (bits(indexAlign, 0))
2267375Sgblack@eecs.umich.edu                        align = size + 1;
2277333Sgblack@eecs.umich.edu                    break;
2287333Sgblack@eecs.umich.edu                  case 3:
2297333Sgblack@eecs.umich.edu                    break;
2307333Sgblack@eecs.umich.edu                  case 4:
2317333Sgblack@eecs.umich.edu                    switch (size) {
2327333Sgblack@eecs.umich.edu                      case 0:
2337333Sgblack@eecs.umich.edu                      case 1:
2347333Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2357375Sgblack@eecs.umich.edu                            align = size + 2;
2367333Sgblack@eecs.umich.edu                        break;
2377333Sgblack@eecs.umich.edu                      case 2:
2387375Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2397375Sgblack@eecs.umich.edu                            align = bits(indexAlign, 1, 0) + 2;
2407333Sgblack@eecs.umich.edu                        break;
2417333Sgblack@eecs.umich.edu                    }
2427333Sgblack@eecs.umich.edu                    break;
2437333Sgblack@eecs.umich.edu                }
2447333Sgblack@eecs.umich.edu            }
2457375Sgblack@eecs.umich.edu            if (size == 0x3) {
2467333Sgblack@eecs.umich.edu                return new Unknown(machInst);
2477333Sgblack@eecs.umich.edu            }
2487375Sgblack@eecs.umich.edu        } else {
2497375Sgblack@eecs.umich.edu            size = bits(machInst, 7, 6);
2507333Sgblack@eecs.umich.edu            align = bits(machInst, 5, 4);
2517333Sgblack@eecs.umich.edu            if (align == 0) {
2527333Sgblack@eecs.umich.edu                // @align wasn't specified, so alignment can be turned off.
2537333Sgblack@eecs.umich.edu                align = size | TLB::AllowUnaligned;
2547333Sgblack@eecs.umich.edu            } else {
2557333Sgblack@eecs.umich.edu                align = align + 2;
2567375Sgblack@eecs.umich.edu            }
2577333Sgblack@eecs.umich.edu            switch (width) {
2587333Sgblack@eecs.umich.edu              case 1:
2597375Sgblack@eecs.umich.edu                switch (type) {
2607375Sgblack@eecs.umich.edu                  case 0x7: regs = 1;
2617333Sgblack@eecs.umich.edu                    break;
2627333Sgblack@eecs.umich.edu                  case 0xa: regs = 2;
2637333Sgblack@eecs.umich.edu                    break;
2647333Sgblack@eecs.umich.edu                  case 0x6: regs = 3;
2657333Sgblack@eecs.umich.edu                    break;
2667333Sgblack@eecs.umich.edu                  case 0x2: regs = 4;
2677333Sgblack@eecs.umich.edu                    break;
2687333Sgblack@eecs.umich.edu                  default:
2697375Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2707333Sgblack@eecs.umich.edu                }
2717333Sgblack@eecs.umich.edu                break;
2727375Sgblack@eecs.umich.edu              case 2:
2737375Sgblack@eecs.umich.edu                // Regs doesn't behave exactly as it does in the manual
2747333Sgblack@eecs.umich.edu                // because they loop over regs registers twice and we break
2757333Sgblack@eecs.umich.edu                // it down in the macroop.
2767333Sgblack@eecs.umich.edu                switch (type) {
2777333Sgblack@eecs.umich.edu                  case 0x8: regs = 2; inc = 1;
2787333Sgblack@eecs.umich.edu                    break;
2797375Sgblack@eecs.umich.edu                  case 0x9: regs = 2; inc = 2;
2807333Sgblack@eecs.umich.edu                    break;
2817333Sgblack@eecs.umich.edu                  case 0x3: regs = 4; inc = 2;
2827375Sgblack@eecs.umich.edu                    break;
2837375Sgblack@eecs.umich.edu                  default:
2847333Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2857333Sgblack@eecs.umich.edu                }
2867333Sgblack@eecs.umich.edu                break;
2877333Sgblack@eecs.umich.edu              case 3:
2887333Sgblack@eecs.umich.edu                regs = 3;
2897375Sgblack@eecs.umich.edu                switch (type) {
2907333Sgblack@eecs.umich.edu                  case 0x4: inc = 1;
2917333Sgblack@eecs.umich.edu                    break;
2927375Sgblack@eecs.umich.edu                  case 0x5: inc = 2;;
2937375Sgblack@eecs.umich.edu                    break;
2947333Sgblack@eecs.umich.edu                  default:
2957333Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2967333Sgblack@eecs.umich.edu                }
2977333Sgblack@eecs.umich.edu                break;
2987333Sgblack@eecs.umich.edu              case 4:
2997375Sgblack@eecs.umich.edu                regs = 4;
3007333Sgblack@eecs.umich.edu                switch (type) {
3017333Sgblack@eecs.umich.edu                  case 0: inc = 1;
3027375Sgblack@eecs.umich.edu                    break;
3037375Sgblack@eecs.umich.edu                  case 1: inc = 2;
3047333Sgblack@eecs.umich.edu                    break;
3057333Sgblack@eecs.umich.edu                  default:
3067333Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3077333Sgblack@eecs.umich.edu                }
3087333Sgblack@eecs.umich.edu                break;
3097375Sgblack@eecs.umich.edu            }
3107333Sgblack@eecs.umich.edu        }
3117333Sgblack@eecs.umich.edu
3127375Sgblack@eecs.umich.edu        if (load) {
3137375Sgblack@eecs.umich.edu            // Load instructions.
3147333Sgblack@eecs.umich.edu            if (single) {
3157333Sgblack@eecs.umich.edu                return new VldSingle(machInst, singleAll, width, rn, vd,
3167333Sgblack@eecs.umich.edu                                     regs, inc, size, align, rm, lane);
3177333Sgblack@eecs.umich.edu            } else {
3187333Sgblack@eecs.umich.edu                return new VldMult(machInst, width, rn, vd,
3197375Sgblack@eecs.umich.edu                                   regs, inc, size, align, rm);
3207333Sgblack@eecs.umich.edu            }
3217333Sgblack@eecs.umich.edu        } else {
3227375Sgblack@eecs.umich.edu            // Store instructions.
3237375Sgblack@eecs.umich.edu            if (single) {
3247333Sgblack@eecs.umich.edu                if (singleAll) {
3257333Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3267333Sgblack@eecs.umich.edu                } else {
3277333Sgblack@eecs.umich.edu                    return new VstSingle(machInst, false, width, rn, vd,
3287333Sgblack@eecs.umich.edu                                         regs, inc, size, align, rm, lane);
3297375Sgblack@eecs.umich.edu                }
3307333Sgblack@eecs.umich.edu            } else {
3317333Sgblack@eecs.umich.edu                return new VstMult(machInst, width, rn, vd,
3327375Sgblack@eecs.umich.edu                                   regs, inc, size, align, rm);
3337375Sgblack@eecs.umich.edu            }
3347333Sgblack@eecs.umich.edu        }
3357333Sgblack@eecs.umich.edu        return new Unknown(machInst);
3367333Sgblack@eecs.umich.edu    }
3377333Sgblack@eecs.umich.edu    '''
3387333Sgblack@eecs.umich.edu
3397375Sgblack@eecs.umich.edu    decoder_output += '''
3407333Sgblack@eecs.umich.edu    static StaticInstPtr
3417333Sgblack@eecs.umich.edu    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
3427375Sgblack@eecs.umich.edu    {
3437375Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
3447333Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
3457333Sgblack@eecs.umich.edu        const bool b = bits(machInst, 4);
3467333Sgblack@eecs.umich.edu        const uint32_t c = bits(machInst, 21, 20);
3477333Sgblack@eecs.umich.edu        const IntRegIndex vd =
3487333Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
3497375Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
3507333Sgblack@eecs.umich.edu        const IntRegIndex vn =
3517333Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
3527375Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
3537375Sgblack@eecs.umich.edu        const IntRegIndex vm =
3547333Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
3557333Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
3567333Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
3577333Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
3587333Sgblack@eecs.umich.edu        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
3597333Sgblack@eecs.umich.edu            return new Unknown(machInst);
3607375Sgblack@eecs.umich.edu        switch (a) {
3617333Sgblack@eecs.umich.edu          case 0x0:
3627333Sgblack@eecs.umich.edu            if (b) {
3637375Sgblack@eecs.umich.edu                if (u) {
3647375Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3657333Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
3667333Sgblack@eecs.umich.edu                } else {
3677333Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
3687333Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
3697333Sgblack@eecs.umich.edu                }
3707333Sgblack@eecs.umich.edu            } else {
3717375Sgblack@eecs.umich.edu                if (size == 3)
3727333Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3737333Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
3747375Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
3757375Sgblack@eecs.umich.edu            }
3767333Sgblack@eecs.umich.edu          case 0x1:
3777381Sgblack@eecs.umich.edu            if (!b) {
3787381Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
3797381Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
3807381Sgblack@eecs.umich.edu            } else {
3817381Sgblack@eecs.umich.edu                if (u) {
3827381Sgblack@eecs.umich.edu                    switch (c) {
3837381Sgblack@eecs.umich.edu                      case 0:
3847364Sgblack@eecs.umich.edu                        if (q) {
3857364Sgblack@eecs.umich.edu                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
3867382Sgblack@eecs.umich.edu                        } else {
3877378Sgblack@eecs.umich.edu                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
3887381Sgblack@eecs.umich.edu                        }
3897385Sgblack@eecs.umich.edu                      case 1:
3907381Sgblack@eecs.umich.edu                        if (q) {
3917378Sgblack@eecs.umich.edu                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3927364Sgblack@eecs.umich.edu                        } else {
3937364Sgblack@eecs.umich.edu                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
3947364Sgblack@eecs.umich.edu                        }
3957364Sgblack@eecs.umich.edu                      case 2:
3967375Sgblack@eecs.umich.edu                        if (q) {
3977364Sgblack@eecs.umich.edu                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
3987364Sgblack@eecs.umich.edu                        } else {
3997375Sgblack@eecs.umich.edu                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
4007375Sgblack@eecs.umich.edu                        }
4017364Sgblack@eecs.umich.edu                      case 3:
4027364Sgblack@eecs.umich.edu                        if (q) {
4037364Sgblack@eecs.umich.edu                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
4047364Sgblack@eecs.umich.edu                        } else {
4057364Sgblack@eecs.umich.edu                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
4067364Sgblack@eecs.umich.edu                        }
4077382Sgblack@eecs.umich.edu                      default:
4087378Sgblack@eecs.umich.edu                        M5_UNREACHABLE;
4097381Sgblack@eecs.umich.edu                    }
4107385Sgblack@eecs.umich.edu                } else {
4117381Sgblack@eecs.umich.edu                    switch (c) {
4127378Sgblack@eecs.umich.edu                      case 0:
4137364Sgblack@eecs.umich.edu                        if (q) {
4147364Sgblack@eecs.umich.edu                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
4157364Sgblack@eecs.umich.edu                        } else {
4167364Sgblack@eecs.umich.edu                            return new VandD<uint64_t>(machInst, vd, vn, vm);
4177364Sgblack@eecs.umich.edu                        }
4187364Sgblack@eecs.umich.edu                      case 1:
4197364Sgblack@eecs.umich.edu                        if (q) {
4207375Sgblack@eecs.umich.edu                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
4217364Sgblack@eecs.umich.edu                        } else {
4227364Sgblack@eecs.umich.edu                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
4237375Sgblack@eecs.umich.edu                        }
4247375Sgblack@eecs.umich.edu                      case 2:
4257364Sgblack@eecs.umich.edu                        if (vn == vm) {
4267365Sgblack@eecs.umich.edu                            if (q) {
4277365Sgblack@eecs.umich.edu                                return new VmovQ<uint64_t>(
4287365Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4297365Sgblack@eecs.umich.edu                            } else {
4307375Sgblack@eecs.umich.edu                                return new VmovD<uint64_t>(
4317365Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4327365Sgblack@eecs.umich.edu                            }
4337375Sgblack@eecs.umich.edu                        } else {
4347375Sgblack@eecs.umich.edu                            if (q) {
4357365Sgblack@eecs.umich.edu                                return new VorrQ<uint64_t>(
4367365Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4377365Sgblack@eecs.umich.edu                            } else {
4387365Sgblack@eecs.umich.edu                                return new VorrD<uint64_t>(
4397365Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4407365Sgblack@eecs.umich.edu                            }
4417365Sgblack@eecs.umich.edu                        }
4427365Sgblack@eecs.umich.edu                      case 3:
4437365Sgblack@eecs.umich.edu                        if (q) {
4447375Sgblack@eecs.umich.edu                            return new VornQ<uint64_t>(
4457365Sgblack@eecs.umich.edu                                    machInst, vd, vn, vm);
4467365Sgblack@eecs.umich.edu                        } else {
4477375Sgblack@eecs.umich.edu                            return new VornD<uint64_t>(
4487375Sgblack@eecs.umich.edu                                    machInst, vd, vn, vm);
4497365Sgblack@eecs.umich.edu                        }
4507366Sgblack@eecs.umich.edu                      default:
4517366Sgblack@eecs.umich.edu                        M5_UNREACHABLE;
4527366Sgblack@eecs.umich.edu                    }
4537366Sgblack@eecs.umich.edu                }
4547375Sgblack@eecs.umich.edu            }
4557366Sgblack@eecs.umich.edu          case 0x2:
4567366Sgblack@eecs.umich.edu            if (b) {
4577375Sgblack@eecs.umich.edu                if (u) {
4587375Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
4597366Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4607366Sgblack@eecs.umich.edu                } else {
4617366Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
4627366Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4637366Sgblack@eecs.umich.edu                }
4647366Sgblack@eecs.umich.edu            } else {
4657366Sgblack@eecs.umich.edu                if (size == 3)
4667366Sgblack@eecs.umich.edu                    return new Unknown(machInst);
4677366Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
4687375Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4697366Sgblack@eecs.umich.edu            }
4707366Sgblack@eecs.umich.edu          case 0x3:
4717375Sgblack@eecs.umich.edu            if (b) {
4727375Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
4737366Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4747367Sgblack@eecs.umich.edu            } else {
4757367Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
4767382Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4777378Sgblack@eecs.umich.edu            }
4787381Sgblack@eecs.umich.edu          case 0x4:
4797385Sgblack@eecs.umich.edu            if (b) {
4807381Sgblack@eecs.umich.edu                if (u) {
4817378Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
4827367Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4837375Sgblack@eecs.umich.edu                } else {
4847367Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
4857367Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4867375Sgblack@eecs.umich.edu                }
4877375Sgblack@eecs.umich.edu            } else {
4887367Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VshlD, VshlQ>(
4897367Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
4907367Sgblack@eecs.umich.edu            }
4917367Sgblack@eecs.umich.edu          case 0x5:
4927367Sgblack@eecs.umich.edu            if (b) {
4937367Sgblack@eecs.umich.edu                if (u) {
4947385Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
4957385Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4967382Sgblack@eecs.umich.edu                } else {
4977378Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
4987381Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4997385Sgblack@eecs.umich.edu                }
5007385Sgblack@eecs.umich.edu            } else {
5017381Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
5027378Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
5037367Sgblack@eecs.umich.edu            }
5047367Sgblack@eecs.umich.edu          case 0x6:
5057367Sgblack@eecs.umich.edu            if (b) {
5067375Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VminD, VminQ>(
5077367Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5087367Sgblack@eecs.umich.edu            } else {
5097375Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
5107375Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5117367Sgblack@eecs.umich.edu            }
5127368Sgblack@eecs.umich.edu          case 0x7:
5137368Sgblack@eecs.umich.edu            if (b) {
5147382Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabaD, VabaQ>(
5157378Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5167381Sgblack@eecs.umich.edu            } else {
5177385Sgblack@eecs.umich.edu                if (bits(machInst, 23) == 1) {
5187381Sgblack@eecs.umich.edu                    if (q) {
5197378Sgblack@eecs.umich.edu                        return new Unknown(machInst);
5207368Sgblack@eecs.umich.edu                    } else {
5217375Sgblack@eecs.umich.edu                        return decodeNeonUSThreeUSReg<Vabdl>(
5227368Sgblack@eecs.umich.edu                                u, size, machInst, vd, vn, vm);
5237368Sgblack@eecs.umich.edu                    }
5247375Sgblack@eecs.umich.edu                } else {
5257375Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
5267368Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5277368Sgblack@eecs.umich.edu                }
5287368Sgblack@eecs.umich.edu            }
5297368Sgblack@eecs.umich.edu          case 0x8:
5307368Sgblack@eecs.umich.edu            if (b) {
5317368Sgblack@eecs.umich.edu                if (u) {
5327382Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VceqD, VceqQ>(
5337378Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5347381Sgblack@eecs.umich.edu                } else {
5357385Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VtstD, VtstQ>(
5367381Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5377378Sgblack@eecs.umich.edu                }
5387368Sgblack@eecs.umich.edu            } else {
5397368Sgblack@eecs.umich.edu                if (u) {
5407368Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5417375Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5427368Sgblack@eecs.umich.edu                } else {
5437368Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
5447375Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5457375Sgblack@eecs.umich.edu                }
5467368Sgblack@eecs.umich.edu            }
5477369Sgblack@eecs.umich.edu          case 0x9:
5487369Sgblack@eecs.umich.edu            if (b) {
5497382Sgblack@eecs.umich.edu                if (u) {
5507378Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5517381Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5527385Sgblack@eecs.umich.edu                } else {
5537381Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
5547378Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5557369Sgblack@eecs.umich.edu                }
5567375Sgblack@eecs.umich.edu            } else {
5577369Sgblack@eecs.umich.edu                if (u) {
5587369Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
5597375Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5607375Sgblack@eecs.umich.edu                } else {
5617369Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
5627369Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5637369Sgblack@eecs.umich.edu                }
5647369Sgblack@eecs.umich.edu            }
5657369Sgblack@eecs.umich.edu          case 0xa:
5667369Sgblack@eecs.umich.edu            if (q)
5677382Sgblack@eecs.umich.edu                return new Unknown(machInst);
5687378Sgblack@eecs.umich.edu            if (b) {
5697381Sgblack@eecs.umich.edu                return decodeNeonUSThreeUSReg<VpminD>(
5707385Sgblack@eecs.umich.edu                        u, size, machInst, vd, vn, vm);
5717381Sgblack@eecs.umich.edu            } else {
5727378Sgblack@eecs.umich.edu                return decodeNeonUSThreeUSReg<VpmaxD>(
5737369Sgblack@eecs.umich.edu                        u, size, machInst, vd, vn, vm);
5747369Sgblack@eecs.umich.edu            }
5757369Sgblack@eecs.umich.edu          case 0xb:
5767375Sgblack@eecs.umich.edu            if (b) {
5777369Sgblack@eecs.umich.edu                if (u || q) {
5787369Sgblack@eecs.umich.edu                    return new Unknown(machInst);
5797375Sgblack@eecs.umich.edu                } else {
5807375Sgblack@eecs.umich.edu                    return decodeNeonUThreeUSReg<NVpaddD>(
5817369Sgblack@eecs.umich.edu                            size, machInst, vd, vn, vm);
5827369Sgblack@eecs.umich.edu                }
5837369Sgblack@eecs.umich.edu            } else {
5847382Sgblack@eecs.umich.edu                if (u) {
5857378Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
5867381Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5877369Sgblack@eecs.umich.edu                } else {
5887381Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
5897378Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5907369Sgblack@eecs.umich.edu                }
5917369Sgblack@eecs.umich.edu            }
5927369Sgblack@eecs.umich.edu          case 0xc:
5937369Sgblack@eecs.umich.edu            if (b) {
5947375Sgblack@eecs.umich.edu                if (!u) {
5957369Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
5967369Sgblack@eecs.umich.edu                        if (q) {
5977375Sgblack@eecs.umich.edu                            return new NVfmaQFp<float>(machInst, vd, vn, vm);
5987375Sgblack@eecs.umich.edu                        } else {
5997369Sgblack@eecs.umich.edu                            return new NVfmaDFp<float>(machInst, vd, vn, vm);
6007369Sgblack@eecs.umich.edu                        }
6017369Sgblack@eecs.umich.edu                    } else {
6027369Sgblack@eecs.umich.edu                        if (q) {
6037369Sgblack@eecs.umich.edu                            return new NVfmsQFp<float>(machInst, vd, vn, vm);
6047382Sgblack@eecs.umich.edu                        } else {
6057378Sgblack@eecs.umich.edu                            return new NVfmsDFp<float>(machInst, vd, vn, vm);
6067381Sgblack@eecs.umich.edu                        }
6077369Sgblack@eecs.umich.edu                    }
6087381Sgblack@eecs.umich.edu                }
6097378Sgblack@eecs.umich.edu            }
6107369Sgblack@eecs.umich.edu            return new Unknown(machInst);
6117369Sgblack@eecs.umich.edu          case 0xd:
6127369Sgblack@eecs.umich.edu            if (b) {
6137369Sgblack@eecs.umich.edu                if (u) {
6147369Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6157369Sgblack@eecs.umich.edu                        if (q) {
6167375Sgblack@eecs.umich.edu                            return new NVmulQFp<float>(machInst, vd, vn, vm);
6177369Sgblack@eecs.umich.edu                        } else {
6187369Sgblack@eecs.umich.edu                            return new NVmulDFp<float>(machInst, vd, vn, vm);
6197375Sgblack@eecs.umich.edu                        }
6207375Sgblack@eecs.umich.edu                    } else {
6217369Sgblack@eecs.umich.edu                        return new Unknown(machInst);
6227381Sgblack@eecs.umich.edu                    }
6237381Sgblack@eecs.umich.edu                } else {
6247381Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6257381Sgblack@eecs.umich.edu                        if (q) {
6267381Sgblack@eecs.umich.edu                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6277381Sgblack@eecs.umich.edu                        } else {
6287381Sgblack@eecs.umich.edu                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
6297370Sgblack@eecs.umich.edu                        }
6307370Sgblack@eecs.umich.edu                    } else {
6317382Sgblack@eecs.umich.edu                        if (q) {
6327378Sgblack@eecs.umich.edu                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
6337381Sgblack@eecs.umich.edu                        } else {
6347385Sgblack@eecs.umich.edu                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
6357370Sgblack@eecs.umich.edu                        }
6367370Sgblack@eecs.umich.edu                    }
6377370Sgblack@eecs.umich.edu                }
6387382Sgblack@eecs.umich.edu            } else {
6397385Sgblack@eecs.umich.edu                if (u) {
6407381Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6417378Sgblack@eecs.umich.edu                        if (q) {
6427370Sgblack@eecs.umich.edu                            return new VpaddQFp<float>(machInst, vd, vn, vm);
6437375Sgblack@eecs.umich.edu                        } else {
6447370Sgblack@eecs.umich.edu                            return new VpaddDFp<float>(machInst, vd, vn, vm);
6457370Sgblack@eecs.umich.edu                        }
6467375Sgblack@eecs.umich.edu                    } else {
6477375Sgblack@eecs.umich.edu                        if (q) {
6487370Sgblack@eecs.umich.edu                            return new VabdQFp<float>(machInst, vd, vn, vm);
6497370Sgblack@eecs.umich.edu                        } else {
6507370Sgblack@eecs.umich.edu                            return new VabdDFp<float>(machInst, vd, vn, vm);
6517370Sgblack@eecs.umich.edu                        }
6527370Sgblack@eecs.umich.edu                    }
6537370Sgblack@eecs.umich.edu                } else {
6547370Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6557382Sgblack@eecs.umich.edu                        if (q) {
6567378Sgblack@eecs.umich.edu                            return new VaddQFp<float>(machInst, vd, vn, vm);
6577381Sgblack@eecs.umich.edu                        } else {
6587385Sgblack@eecs.umich.edu                            return new VaddDFp<float>(machInst, vd, vn, vm);
6597370Sgblack@eecs.umich.edu                        }
6607370Sgblack@eecs.umich.edu                    } else {
6617370Sgblack@eecs.umich.edu                        if (q) {
6627370Sgblack@eecs.umich.edu                            return new VsubQFp<float>(machInst, vd, vn, vm);
6637382Sgblack@eecs.umich.edu                        } else {
6647385Sgblack@eecs.umich.edu                            return new VsubDFp<float>(machInst, vd, vn, vm);
6657381Sgblack@eecs.umich.edu                        }
6667378Sgblack@eecs.umich.edu                    }
6677370Sgblack@eecs.umich.edu                }
6687370Sgblack@eecs.umich.edu            }
6697370Sgblack@eecs.umich.edu          case 0xe:
6707375Sgblack@eecs.umich.edu            if (b) {
6717370Sgblack@eecs.umich.edu                if (u) {
6727370Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6737375Sgblack@eecs.umich.edu                        if (q) {
6747375Sgblack@eecs.umich.edu                            return new VacgeQFp<float>(machInst, vd, vn, vm);
6757370Sgblack@eecs.umich.edu                        } else {
6767370Sgblack@eecs.umich.edu                            return new VacgeDFp<float>(machInst, vd, vn, vm);
6777370Sgblack@eecs.umich.edu                        }
6787382Sgblack@eecs.umich.edu                    } else {
6797378Sgblack@eecs.umich.edu                        if (q) {
6807381Sgblack@eecs.umich.edu                            return new VacgtQFp<float>(machInst, vd, vn, vm);
6817385Sgblack@eecs.umich.edu                        } else {
6827370Sgblack@eecs.umich.edu                            return new VacgtDFp<float>(machInst, vd, vn, vm);
6837370Sgblack@eecs.umich.edu                        }
6847370Sgblack@eecs.umich.edu                    }
6857382Sgblack@eecs.umich.edu                } else {
6867385Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6877381Sgblack@eecs.umich.edu                }
6887378Sgblack@eecs.umich.edu            } else {
6897370Sgblack@eecs.umich.edu                if (u) {
6907375Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6917370Sgblack@eecs.umich.edu                        if (q) {
6927370Sgblack@eecs.umich.edu                            return new VcgeQFp<float>(machInst, vd, vn, vm);
6937375Sgblack@eecs.umich.edu                        } else {
6947375Sgblack@eecs.umich.edu                            return new VcgeDFp<float>(machInst, vd, vn, vm);
6957370Sgblack@eecs.umich.edu                        }
6967370Sgblack@eecs.umich.edu                    } else {
6977370Sgblack@eecs.umich.edu                        if (q) {
6987370Sgblack@eecs.umich.edu                            return new VcgtQFp<float>(machInst, vd, vn, vm);
6997370Sgblack@eecs.umich.edu                        } else {
7007370Sgblack@eecs.umich.edu                            return new VcgtDFp<float>(machInst, vd, vn, vm);
7017370Sgblack@eecs.umich.edu                        }
7027382Sgblack@eecs.umich.edu                    }
7037378Sgblack@eecs.umich.edu                } else {
7047381Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7057385Sgblack@eecs.umich.edu                        if (q) {
7067370Sgblack@eecs.umich.edu                            return new VceqQFp<float>(machInst, vd, vn, vm);
7077370Sgblack@eecs.umich.edu                        } else {
7087370Sgblack@eecs.umich.edu                            return new VceqDFp<float>(machInst, vd, vn, vm);
7097370Sgblack@eecs.umich.edu                        }
7107385Sgblack@eecs.umich.edu                    } else {
7117382Sgblack@eecs.umich.edu                        return new Unknown(machInst);
7127381Sgblack@eecs.umich.edu                    }
7137378Sgblack@eecs.umich.edu                }
7147370Sgblack@eecs.umich.edu            }
7157370Sgblack@eecs.umich.edu          case 0xf:
7167370Sgblack@eecs.umich.edu            if (b) {
7177375Sgblack@eecs.umich.edu                if (u) {
7187370Sgblack@eecs.umich.edu                    return new Unknown(machInst);
7197370Sgblack@eecs.umich.edu                } else {
7207375Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7217375Sgblack@eecs.umich.edu                        if (q) {
7227370Sgblack@eecs.umich.edu                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
7237371Sgblack@eecs.umich.edu                        } else {
7247371Sgblack@eecs.umich.edu                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
7257382Sgblack@eecs.umich.edu                        }
7267378Sgblack@eecs.umich.edu                    } else {
7277381Sgblack@eecs.umich.edu                        if (q) {
7287385Sgblack@eecs.umich.edu                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
7297371Sgblack@eecs.umich.edu                        } else {
7307371Sgblack@eecs.umich.edu                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
7317371Sgblack@eecs.umich.edu                        }
7327382Sgblack@eecs.umich.edu                    }
7337385Sgblack@eecs.umich.edu                }
7347381Sgblack@eecs.umich.edu            } else {
7357378Sgblack@eecs.umich.edu                if (u) {
7367371Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7377375Sgblack@eecs.umich.edu                        if (q) {
7387371Sgblack@eecs.umich.edu                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
7397371Sgblack@eecs.umich.edu                        } else {
7407375Sgblack@eecs.umich.edu                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
7417375Sgblack@eecs.umich.edu                        }
7427371Sgblack@eecs.umich.edu                    } else {
7437371Sgblack@eecs.umich.edu                        if (q) {
7447371Sgblack@eecs.umich.edu                            return new VpminQFp<float>(machInst, vd, vn, vm);
7457371Sgblack@eecs.umich.edu                        } else {
7467371Sgblack@eecs.umich.edu                            return new VpminDFp<float>(machInst, vd, vn, vm);
7477371Sgblack@eecs.umich.edu                        }
7487371Sgblack@eecs.umich.edu                    }
7497382Sgblack@eecs.umich.edu                } else {
7507378Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7517381Sgblack@eecs.umich.edu                        if (q) {
7527385Sgblack@eecs.umich.edu                            return new VmaxQFp<float>(machInst, vd, vn, vm);
7537371Sgblack@eecs.umich.edu                        } else {
7547371Sgblack@eecs.umich.edu                            return new VmaxDFp<float>(machInst, vd, vn, vm);
7557371Sgblack@eecs.umich.edu                        }
7567371Sgblack@eecs.umich.edu                    } else {
7577382Sgblack@eecs.umich.edu                        if (q) {
7587385Sgblack@eecs.umich.edu                            return new VminQFp<float>(machInst, vd, vn, vm);
7597381Sgblack@eecs.umich.edu                        } else {
7607378Sgblack@eecs.umich.edu                            return new VminDFp<float>(machInst, vd, vn, vm);
7617371Sgblack@eecs.umich.edu                        }
7627371Sgblack@eecs.umich.edu                    }
7637371Sgblack@eecs.umich.edu                }
7647375Sgblack@eecs.umich.edu            }
7657371Sgblack@eecs.umich.edu        }
7667371Sgblack@eecs.umich.edu        return new Unknown(machInst);
7677375Sgblack@eecs.umich.edu    }
7687375Sgblack@eecs.umich.edu
7697371Sgblack@eecs.umich.edu    static StaticInstPtr
7707371Sgblack@eecs.umich.edu    decodeNeonOneRegModImm(ExtMachInst machInst)
7717371Sgblack@eecs.umich.edu    {
7727382Sgblack@eecs.umich.edu        const IntRegIndex vd =
7737378Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
7747381Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
7757385Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
7767371Sgblack@eecs.umich.edu        const bool op = bits(machInst, 5);
7777371Sgblack@eecs.umich.edu        const uint8_t cmode = bits(machInst, 11, 8);
7787371Sgblack@eecs.umich.edu        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
7797382Sgblack@eecs.umich.edu                                      bits(machInst, 24)) << 7) |
7807385Sgblack@eecs.umich.edu                            (bits(machInst, 18, 16) << 4) |
7817381Sgblack@eecs.umich.edu                            (bits(machInst, 3, 0) << 0);
7827378Sgblack@eecs.umich.edu
7837371Sgblack@eecs.umich.edu        // Check for invalid immediate encodings and return an unknown op
7847375Sgblack@eecs.umich.edu        // if it happens
7857371Sgblack@eecs.umich.edu        bool immValid = true;
7867371Sgblack@eecs.umich.edu        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
7877375Sgblack@eecs.umich.edu        if (!immValid) {
7887375Sgblack@eecs.umich.edu            return new Unknown(machInst);
7897371Sgblack@eecs.umich.edu        }
7907371Sgblack@eecs.umich.edu
7917371Sgblack@eecs.umich.edu        if (op) {
7927371Sgblack@eecs.umich.edu            if (bits(cmode, 3) == 0) {
7937371Sgblack@eecs.umich.edu                if (bits(cmode, 0) == 0) {
7947371Sgblack@eecs.umich.edu                    if (q)
7957371Sgblack@eecs.umich.edu                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7967382Sgblack@eecs.umich.edu                    else
7977378Sgblack@eecs.umich.edu                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7987381Sgblack@eecs.umich.edu                } else {
7997385Sgblack@eecs.umich.edu                    if (q)
8007371Sgblack@eecs.umich.edu                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8017371Sgblack@eecs.umich.edu                    else
8027371Sgblack@eecs.umich.edu                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8037371Sgblack@eecs.umich.edu                }
8047382Sgblack@eecs.umich.edu            } else {
8057385Sgblack@eecs.umich.edu                if (bits(cmode, 2) == 1) {
8067381Sgblack@eecs.umich.edu                    switch (bits(cmode, 1, 0)) {
8077378Sgblack@eecs.umich.edu                      case 0:
8087371Sgblack@eecs.umich.edu                      case 1:
8097371Sgblack@eecs.umich.edu                        if (q)
8107371Sgblack@eecs.umich.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
8117375Sgblack@eecs.umich.edu                        else
8127371Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8137371Sgblack@eecs.umich.edu                      case 2:
8147375Sgblack@eecs.umich.edu                        if (q)
8157375Sgblack@eecs.umich.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8167371Sgblack@eecs.umich.edu                        else
8177371Sgblack@eecs.umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8187371Sgblack@eecs.umich.edu                      case 3:
8197382Sgblack@eecs.umich.edu                        if (q)
8207378Sgblack@eecs.umich.edu                            return new Unknown(machInst);
8217381Sgblack@eecs.umich.edu                        else
8227385Sgblack@eecs.umich.edu                            return new Unknown(machInst);
8237371Sgblack@eecs.umich.edu                    }
8247371Sgblack@eecs.umich.edu                } else {
8257371Sgblack@eecs.umich.edu                    if (bits(cmode, 0) == 0) {
8267371Sgblack@eecs.umich.edu                        if (q)
8277381Sgblack@eecs.umich.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
8287378Sgblack@eecs.umich.edu                        else
8297371Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8307375Sgblack@eecs.umich.edu                    } else {
8317371Sgblack@eecs.umich.edu                        if (q)
8327371Sgblack@eecs.umich.edu                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8337375Sgblack@eecs.umich.edu                        else
8347375Sgblack@eecs.umich.edu                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8357371Sgblack@eecs.umich.edu                    }
8367371Sgblack@eecs.umich.edu                }
8377371Sgblack@eecs.umich.edu            }
8387371Sgblack@eecs.umich.edu        } else {
8397371Sgblack@eecs.umich.edu            if (bits(cmode, 3) == 0) {
8407371Sgblack@eecs.umich.edu                if (bits(cmode, 0) == 0) {
8417371Sgblack@eecs.umich.edu                    if (q)
8427382Sgblack@eecs.umich.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8437378Sgblack@eecs.umich.edu                    else
8447381Sgblack@eecs.umich.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8457385Sgblack@eecs.umich.edu                } else {
8467371Sgblack@eecs.umich.edu                    if (q)
8477371Sgblack@eecs.umich.edu                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8487371Sgblack@eecs.umich.edu                    else
8497371Sgblack@eecs.umich.edu                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8507371Sgblack@eecs.umich.edu                }
8517381Sgblack@eecs.umich.edu            } else {
8527378Sgblack@eecs.umich.edu                if (bits(cmode, 2) == 1) {
8537371Sgblack@eecs.umich.edu                    if (q)
8547371Sgblack@eecs.umich.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8557371Sgblack@eecs.umich.edu                    else
8567375Sgblack@eecs.umich.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8577371Sgblack@eecs.umich.edu                } else {
8587371Sgblack@eecs.umich.edu                    if (bits(cmode, 0) == 0) {
8597375Sgblack@eecs.umich.edu                        if (q)
8607375Sgblack@eecs.umich.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8617371Sgblack@eecs.umich.edu                        else
8627381Sgblack@eecs.umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8637381Sgblack@eecs.umich.edu                    } else {
8647381Sgblack@eecs.umich.edu                        if (q)
8657381Sgblack@eecs.umich.edu                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8667381Sgblack@eecs.umich.edu                        else
8677381Sgblack@eecs.umich.edu                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
8687381Sgblack@eecs.umich.edu                    }
8697373Sgblack@eecs.umich.edu                }
8707373Sgblack@eecs.umich.edu            }
8717378Sgblack@eecs.umich.edu        }
8727381Sgblack@eecs.umich.edu        return new Unknown(machInst);
8737373Sgblack@eecs.umich.edu    }
8747381Sgblack@eecs.umich.edu
8757378Sgblack@eecs.umich.edu    static StaticInstPtr
8767373Sgblack@eecs.umich.edu    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8777375Sgblack@eecs.umich.edu    {
8787373Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
8797373Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
8807375Sgblack@eecs.umich.edu        const bool b = bits(machInst, 6);
8817375Sgblack@eecs.umich.edu        const bool l = bits(machInst, 7);
8827373Sgblack@eecs.umich.edu        const IntRegIndex vd =
8837373Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
8847373Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
8857373Sgblack@eecs.umich.edu        const IntRegIndex vm =
8867378Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
8877381Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
8887373Sgblack@eecs.umich.edu        unsigned imm6 = bits(machInst, 21, 16);
8897381Sgblack@eecs.umich.edu        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
8907378Sgblack@eecs.umich.edu        unsigned size = 3;
8917373Sgblack@eecs.umich.edu        unsigned lShiftAmt = 0;
8927373Sgblack@eecs.umich.edu        unsigned bitSel;
8937373Sgblack@eecs.umich.edu        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8947375Sgblack@eecs.umich.edu            if (bitSel & imm)
8957373Sgblack@eecs.umich.edu                break;
8967373Sgblack@eecs.umich.edu            else if (!size)
8977375Sgblack@eecs.umich.edu                return new Unknown(machInst);
8987375Sgblack@eecs.umich.edu            size--;
8997373Sgblack@eecs.umich.edu        }
9007373Sgblack@eecs.umich.edu        lShiftAmt = imm6 & ~bitSel;
9017373Sgblack@eecs.umich.edu        unsigned rShiftAmt = 0;
9027378Sgblack@eecs.umich.edu        if (a != 0xe && a != 0xf) {
9037381Sgblack@eecs.umich.edu            if (size > 2)
9047373Sgblack@eecs.umich.edu                rShiftAmt = 64 - imm6;
9057381Sgblack@eecs.umich.edu            else
9067378Sgblack@eecs.umich.edu                rShiftAmt = 2 * (8 << size) - imm6;
9077373Sgblack@eecs.umich.edu        }
9087375Sgblack@eecs.umich.edu
9097373Sgblack@eecs.umich.edu        switch (a) {
9107373Sgblack@eecs.umich.edu          case 0x0:
9117375Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
9127375Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9137373Sgblack@eecs.umich.edu          case 0x1:
9147373Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
9157373Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9167373Sgblack@eecs.umich.edu          case 0x2:
9177378Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
9187381Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9197373Sgblack@eecs.umich.edu          case 0x3:
9207381Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
9217378Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9227373Sgblack@eecs.umich.edu          case 0x4:
9237373Sgblack@eecs.umich.edu            if (u) {
9247373Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
9257375Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9267373Sgblack@eecs.umich.edu            } else {
9277373Sgblack@eecs.umich.edu                return new Unknown(machInst);
9287375Sgblack@eecs.umich.edu            }
9297375Sgblack@eecs.umich.edu          case 0x5:
9307373Sgblack@eecs.umich.edu            if (u) {
9317373Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9327380Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9337382Sgblack@eecs.umich.edu            } else {
9347380Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9357381Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9367380Sgblack@eecs.umich.edu            }
9377381Sgblack@eecs.umich.edu          case 0x6:
9387380Sgblack@eecs.umich.edu          case 0x7:
9397380Sgblack@eecs.umich.edu            if (u) {
9407380Sgblack@eecs.umich.edu                if (a == 0x6) {
9417380Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9427380Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9437380Sgblack@eecs.umich.edu                } else {
9447380Sgblack@eecs.umich.edu                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
9457380Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9467380Sgblack@eecs.umich.edu                }
9477380Sgblack@eecs.umich.edu            } else {
9487380Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9497380Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9507382Sgblack@eecs.umich.edu            }
9517380Sgblack@eecs.umich.edu          case 0x8:
9527381Sgblack@eecs.umich.edu            if (l) {
9537380Sgblack@eecs.umich.edu                return new Unknown(machInst);
9547381Sgblack@eecs.umich.edu            } else if (u) {
9557380Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9567380Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9577380Sgblack@eecs.umich.edu            } else {
9587380Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
9597380Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9607380Sgblack@eecs.umich.edu            }
9617380Sgblack@eecs.umich.edu          case 0x9:
9627380Sgblack@eecs.umich.edu            if (l) {
9637380Sgblack@eecs.umich.edu                return new Unknown(machInst);
9647380Sgblack@eecs.umich.edu            } else if (u) {
9657380Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
9667382Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9677380Sgblack@eecs.umich.edu            } else {
9687381Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
9697380Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9707381Sgblack@eecs.umich.edu            }
9717380Sgblack@eecs.umich.edu          case 0xa:
9727380Sgblack@eecs.umich.edu            if (l || b) {
9737380Sgblack@eecs.umich.edu                return new Unknown(machInst);
9747380Sgblack@eecs.umich.edu            } else {
9757380Sgblack@eecs.umich.edu                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9767380Sgblack@eecs.umich.edu                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9777380Sgblack@eecs.umich.edu            }
9787380Sgblack@eecs.umich.edu          case 0xe:
9797380Sgblack@eecs.umich.edu            if (l) {
9807380Sgblack@eecs.umich.edu                return new Unknown(machInst);
9817380Sgblack@eecs.umich.edu            } else {
9827380Sgblack@eecs.umich.edu                if (bits(imm6, 5) == 0)
9837382Sgblack@eecs.umich.edu                    return new Unknown(machInst);
9847380Sgblack@eecs.umich.edu                if (u) {
9857381Sgblack@eecs.umich.edu                    if (b) {
9867380Sgblack@eecs.umich.edu                        return new NVcvtu2fpQ<float>(
9877381Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9887380Sgblack@eecs.umich.edu                    } else {
9897380Sgblack@eecs.umich.edu                        return new NVcvtu2fpD<float>(
9907380Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9917380Sgblack@eecs.umich.edu                    }
9927380Sgblack@eecs.umich.edu                } else {
9937380Sgblack@eecs.umich.edu                    if (b) {
9947380Sgblack@eecs.umich.edu                        return new NVcvts2fpQ<float>(
9957380Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9967380Sgblack@eecs.umich.edu                    } else {
9977380Sgblack@eecs.umich.edu                        return new NVcvts2fpD<float>(
9987373Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9997382Sgblack@eecs.umich.edu                    }
10007378Sgblack@eecs.umich.edu                }
10017380Sgblack@eecs.umich.edu            }
10027381Sgblack@eecs.umich.edu          case 0xf:
10037373Sgblack@eecs.umich.edu            if (l) {
10047381Sgblack@eecs.umich.edu                return new Unknown(machInst);
10057378Sgblack@eecs.umich.edu            } else {
10067373Sgblack@eecs.umich.edu                if (bits(imm6, 5) == 0)
10077375Sgblack@eecs.umich.edu                    return new Unknown(machInst);
10087373Sgblack@eecs.umich.edu                if (u) {
10097373Sgblack@eecs.umich.edu                    if (b) {
10107375Sgblack@eecs.umich.edu                        return new NVcvt2ufxQ<float>(
10117375Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
10127373Sgblack@eecs.umich.edu                    } else {
10137373Sgblack@eecs.umich.edu                        return new NVcvt2ufxD<float>(
10147373Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
10157373Sgblack@eecs.umich.edu                    }
10167373Sgblack@eecs.umich.edu                } else {
10177382Sgblack@eecs.umich.edu                    if (b) {
10187378Sgblack@eecs.umich.edu                        return new NVcvt2sfxQ<float>(
10197380Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
10207381Sgblack@eecs.umich.edu                    } else {
10217373Sgblack@eecs.umich.edu                        return new NVcvt2sfxD<float>(
10227381Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
10237378Sgblack@eecs.umich.edu                    }
10247373Sgblack@eecs.umich.edu                }
10257373Sgblack@eecs.umich.edu            }
10267375Sgblack@eecs.umich.edu        }
10277373Sgblack@eecs.umich.edu        return new Unknown(machInst);
10287373Sgblack@eecs.umich.edu    }
10297375Sgblack@eecs.umich.edu
10307375Sgblack@eecs.umich.edu    static StaticInstPtr
10317373Sgblack@eecs.umich.edu    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
10327373Sgblack@eecs.umich.edu    {
10337373Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10347382Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
10357378Sgblack@eecs.umich.edu        const IntRegIndex vd =
10367380Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
10377381Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
10387373Sgblack@eecs.umich.edu        const IntRegIndex vn =
10397381Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
10407378Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
10417373Sgblack@eecs.umich.edu        const IntRegIndex vm =
10427375Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10437373Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
10447373Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
10457375Sgblack@eecs.umich.edu        switch (a) {
10467375Sgblack@eecs.umich.edu          case 0x0:
10477373Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vaddl>(
10487373Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10497373Sgblack@eecs.umich.edu          case 0x1:
10507373Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vaddw>(
10517373Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10527382Sgblack@eecs.umich.edu          case 0x2:
10537378Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vsubl>(
10547380Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10557381Sgblack@eecs.umich.edu          case 0x3:
10567373Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vsubw>(
10577381Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10587378Sgblack@eecs.umich.edu          case 0x4:
10597373Sgblack@eecs.umich.edu            if (u) {
10607373Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vraddhn>(
10617375Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10627373Sgblack@eecs.umich.edu            } else {
10637373Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vaddhn>(
10647375Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10657375Sgblack@eecs.umich.edu            }
10667373Sgblack@eecs.umich.edu          case 0x5:
10677374Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vabal>(
10687374Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10697374Sgblack@eecs.umich.edu          case 0x6:
10707382Sgblack@eecs.umich.edu            if (u) {
10717378Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vrsubhn>(
10727381Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10737374Sgblack@eecs.umich.edu            } else {
10747381Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vsubhn>(
10757378Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10767374Sgblack@eecs.umich.edu            }
10777374Sgblack@eecs.umich.edu          case 0x7:
10787374Sgblack@eecs.umich.edu            if (bits(machInst, 23)) {
10797375Sgblack@eecs.umich.edu                return decodeNeonUSThreeUSReg<Vabdl>(
10807374Sgblack@eecs.umich.edu                        u, size, machInst, vd, vn, vm);
10817374Sgblack@eecs.umich.edu            } else {
10827375Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabdD, VabdQ>(
10837375Sgblack@eecs.umich.edu                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
10847374Sgblack@eecs.umich.edu            }
10857374Sgblack@eecs.umich.edu          case 0x8:
10867374Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmlal>(
10877374Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10887374Sgblack@eecs.umich.edu          case 0xa:
10897382Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmlsl>(
10907378Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10917381Sgblack@eecs.umich.edu          case 0x9:
10927374Sgblack@eecs.umich.edu            if (u) {
10937381Sgblack@eecs.umich.edu                return new Unknown(machInst);
10947378Sgblack@eecs.umich.edu            } else {
10957374Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmlal>(
10967375Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10977374Sgblack@eecs.umich.edu            }
10987374Sgblack@eecs.umich.edu          case 0xb:
10997375Sgblack@eecs.umich.edu            if (u) {
11007375Sgblack@eecs.umich.edu                return new Unknown(machInst);
11017374Sgblack@eecs.umich.edu            } else {
11027377Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmlsl>(
11037377Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
11047377Sgblack@eecs.umich.edu            }
11057382Sgblack@eecs.umich.edu          case 0xc:
11067377Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmull>(
11077377Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
11087377Sgblack@eecs.umich.edu          case 0xd:
11097377Sgblack@eecs.umich.edu            if (u) {
11107377Sgblack@eecs.umich.edu                return new Unknown(machInst);
11117377Sgblack@eecs.umich.edu            } else {
11127377Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmull>(
11137377Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
11147377Sgblack@eecs.umich.edu            }
11157377Sgblack@eecs.umich.edu          case 0xe:
11167377Sgblack@eecs.umich.edu            return decodeNeonUThreeUSReg<Vmullp>(
11177377Sgblack@eecs.umich.edu                    size, machInst, vd, vn, vm);
11187377Sgblack@eecs.umich.edu        }
11197377Sgblack@eecs.umich.edu        return new Unknown(machInst);
11207377Sgblack@eecs.umich.edu    }
11217377Sgblack@eecs.umich.edu
11227377Sgblack@eecs.umich.edu    static StaticInstPtr
11237377Sgblack@eecs.umich.edu    decodeNeonTwoRegScalar(ExtMachInst machInst)
11247377Sgblack@eecs.umich.edu    {
11257377Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
11267377Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
11277377Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
11287382Sgblack@eecs.umich.edu        const IntRegIndex vd =
11297377Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11307377Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
11317377Sgblack@eecs.umich.edu        const IntRegIndex vn =
11327377Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11337377Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
11347377Sgblack@eecs.umich.edu        const IntRegIndex vm = (size == 2) ?
11357377Sgblack@eecs.umich.edu            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
11367377Sgblack@eecs.umich.edu            (IntRegIndex)(2 * bits(machInst, 2, 0));
11377377Sgblack@eecs.umich.edu        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11387377Sgblack@eecs.umich.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11397377Sgblack@eecs.umich.edu        switch (a) {
11407377Sgblack@eecs.umich.edu          case 0x0:
11417377Sgblack@eecs.umich.edu            if (u) {
11427377Sgblack@eecs.umich.edu                switch (size) {
11437377Sgblack@eecs.umich.edu                  case 1:
11447377Sgblack@eecs.umich.edu                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
11457377Sgblack@eecs.umich.edu                  case 2:
11467377Sgblack@eecs.umich.edu                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
11477377Sgblack@eecs.umich.edu                  default:
11487377Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11497377Sgblack@eecs.umich.edu                }
11507382Sgblack@eecs.umich.edu            } else {
11517377Sgblack@eecs.umich.edu                switch (size) {
11527377Sgblack@eecs.umich.edu                  case 1:
11537377Sgblack@eecs.umich.edu                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
11547377Sgblack@eecs.umich.edu                  case 2:
11557377Sgblack@eecs.umich.edu                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
11567377Sgblack@eecs.umich.edu                  default:
11577377Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11587377Sgblack@eecs.umich.edu                }
11597377Sgblack@eecs.umich.edu            }
11607377Sgblack@eecs.umich.edu          case 0x1:
11617377Sgblack@eecs.umich.edu            if (u)
11627377Sgblack@eecs.umich.edu                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
11637377Sgblack@eecs.umich.edu            else
11647377Sgblack@eecs.umich.edu                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
11657377Sgblack@eecs.umich.edu          case 0x4:
11667377Sgblack@eecs.umich.edu            if (u) {
11677377Sgblack@eecs.umich.edu                switch (size) {
11687377Sgblack@eecs.umich.edu                  case 1:
11697377Sgblack@eecs.umich.edu                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11707377Sgblack@eecs.umich.edu                  case 2:
11717377Sgblack@eecs.umich.edu                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11727382Sgblack@eecs.umich.edu                  default:
11737377Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11747377Sgblack@eecs.umich.edu                }
11757377Sgblack@eecs.umich.edu            } else {
11767377Sgblack@eecs.umich.edu                switch (size) {
11777377Sgblack@eecs.umich.edu                  case 1:
11787377Sgblack@eecs.umich.edu                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
11797377Sgblack@eecs.umich.edu                  case 2:
11807377Sgblack@eecs.umich.edu                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11817377Sgblack@eecs.umich.edu                  default:
11827377Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11837377Sgblack@eecs.umich.edu                }
11847377Sgblack@eecs.umich.edu            }
11857377Sgblack@eecs.umich.edu          case 0x5:
11867377Sgblack@eecs.umich.edu            if (u)
11877377Sgblack@eecs.umich.edu                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
11887377Sgblack@eecs.umich.edu            else
11897377Sgblack@eecs.umich.edu                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
11907377Sgblack@eecs.umich.edu          case 0x2:
11917322Sgblack@eecs.umich.edu            if (u) {
11927379Sgblack@eecs.umich.edu                switch (size) {
11937379Sgblack@eecs.umich.edu                  case 1:
11947379Sgblack@eecs.umich.edu                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11957379Sgblack@eecs.umich.edu                  case 2:
11967379Sgblack@eecs.umich.edu                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11977379Sgblack@eecs.umich.edu                  default:
11987379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11997379Sgblack@eecs.umich.edu                }
12007382Sgblack@eecs.umich.edu            } else {
12017379Sgblack@eecs.umich.edu                switch (size) {
12027381Sgblack@eecs.umich.edu                  case 1:
12037379Sgblack@eecs.umich.edu                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
12047381Sgblack@eecs.umich.edu                  case 2:
12057379Sgblack@eecs.umich.edu                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
12067379Sgblack@eecs.umich.edu                  default:
12077379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12087379Sgblack@eecs.umich.edu                }
12097379Sgblack@eecs.umich.edu            }
12107379Sgblack@eecs.umich.edu          case 0x6:
12117379Sgblack@eecs.umich.edu            if (u) {
12127379Sgblack@eecs.umich.edu                switch (size) {
12137379Sgblack@eecs.umich.edu                  case 1:
12147379Sgblack@eecs.umich.edu                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
12157379Sgblack@eecs.umich.edu                  case 2:
12167379Sgblack@eecs.umich.edu                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
12177382Sgblack@eecs.umich.edu                  default:
12187379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12197381Sgblack@eecs.umich.edu                }
12207379Sgblack@eecs.umich.edu            } else {
12217381Sgblack@eecs.umich.edu                switch (size) {
12227379Sgblack@eecs.umich.edu                  case 1:
12237379Sgblack@eecs.umich.edu                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
12247379Sgblack@eecs.umich.edu                  case 2:
12257379Sgblack@eecs.umich.edu                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
12267379Sgblack@eecs.umich.edu                  default:
12277379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12287379Sgblack@eecs.umich.edu                }
12297379Sgblack@eecs.umich.edu            }
12307379Sgblack@eecs.umich.edu          case 0x3:
12317379Sgblack@eecs.umich.edu            if (u) {
12327379Sgblack@eecs.umich.edu                return new Unknown(machInst);
12337379Sgblack@eecs.umich.edu            } else {
12347382Sgblack@eecs.umich.edu                switch (size) {
12357379Sgblack@eecs.umich.edu                  case 1:
12367381Sgblack@eecs.umich.edu                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12377379Sgblack@eecs.umich.edu                  case 2:
12387381Sgblack@eecs.umich.edu                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12397379Sgblack@eecs.umich.edu                  default:
12407379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12417379Sgblack@eecs.umich.edu                }
12427379Sgblack@eecs.umich.edu            }
12437379Sgblack@eecs.umich.edu          case 0x7:
12447379Sgblack@eecs.umich.edu            if (u) {
12457379Sgblack@eecs.umich.edu                return new Unknown(machInst);
12467379Sgblack@eecs.umich.edu            } else {
12477379Sgblack@eecs.umich.edu                switch (size) {
12487379Sgblack@eecs.umich.edu                  case 1:
12497379Sgblack@eecs.umich.edu                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12507379Sgblack@eecs.umich.edu                  case 2:
12517382Sgblack@eecs.umich.edu                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12527379Sgblack@eecs.umich.edu                  default:
12537381Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12547379Sgblack@eecs.umich.edu                }
12557381Sgblack@eecs.umich.edu            }
12567379Sgblack@eecs.umich.edu          case 0x8:
12577379Sgblack@eecs.umich.edu            if (u) {
12587379Sgblack@eecs.umich.edu                switch (size) {
12597379Sgblack@eecs.umich.edu                  case 1:
12607379Sgblack@eecs.umich.edu                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
12617379Sgblack@eecs.umich.edu                  case 2:
12627379Sgblack@eecs.umich.edu                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
12637379Sgblack@eecs.umich.edu                  default:
12647379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12657379Sgblack@eecs.umich.edu                }
12667379Sgblack@eecs.umich.edu            } else {
12677379Sgblack@eecs.umich.edu                switch (size) {
12687379Sgblack@eecs.umich.edu                  case 1:
12697381Sgblack@eecs.umich.edu                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
12707380Sgblack@eecs.umich.edu                  case 2:
12717381Sgblack@eecs.umich.edu                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
12727379Sgblack@eecs.umich.edu                  default:
12737379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12747379Sgblack@eecs.umich.edu                }
12757379Sgblack@eecs.umich.edu            }
12767379Sgblack@eecs.umich.edu          case 0x9:
12777379Sgblack@eecs.umich.edu            if (u)
12787379Sgblack@eecs.umich.edu                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
12797379Sgblack@eecs.umich.edu            else
12807379Sgblack@eecs.umich.edu                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
12817379Sgblack@eecs.umich.edu          case 0xa:
12827379Sgblack@eecs.umich.edu            if (u) {
12837379Sgblack@eecs.umich.edu                switch (size) {
12847379Sgblack@eecs.umich.edu                  case 1:
12857381Sgblack@eecs.umich.edu                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
12867380Sgblack@eecs.umich.edu                  case 2:
12877381Sgblack@eecs.umich.edu                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
12887379Sgblack@eecs.umich.edu                  default:
12897379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12907379Sgblack@eecs.umich.edu                }
12917379Sgblack@eecs.umich.edu            } else {
12927379Sgblack@eecs.umich.edu                switch (size) {
12937379Sgblack@eecs.umich.edu                  case 1:
12947379Sgblack@eecs.umich.edu                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
12957379Sgblack@eecs.umich.edu                  case 2:
12967379Sgblack@eecs.umich.edu                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
12977379Sgblack@eecs.umich.edu                  default:
12987379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12997379Sgblack@eecs.umich.edu                }
13007379Sgblack@eecs.umich.edu            }
13017381Sgblack@eecs.umich.edu          case 0xb:
13027379Sgblack@eecs.umich.edu            if (u) {
13037381Sgblack@eecs.umich.edu                return new Unknown(machInst);
13047379Sgblack@eecs.umich.edu            } else {
13057379Sgblack@eecs.umich.edu                if (u) {
13067379Sgblack@eecs.umich.edu                    switch (size) {
13077379Sgblack@eecs.umich.edu                      case 1:
13087379Sgblack@eecs.umich.edu                        return new Vqdmulls<uint16_t>(
13097379Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13107379Sgblack@eecs.umich.edu                      case 2:
13117379Sgblack@eecs.umich.edu                        return new Vqdmulls<uint32_t>(
13127379Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13137379Sgblack@eecs.umich.edu                      default:
13147379Sgblack@eecs.umich.edu                        return new Unknown(machInst);
13157379Sgblack@eecs.umich.edu                    }
13167379Sgblack@eecs.umich.edu                } else {
13177381Sgblack@eecs.umich.edu                    switch (size) {
13187379Sgblack@eecs.umich.edu                      case 1:
13197381Sgblack@eecs.umich.edu                        return new Vqdmulls<int16_t>(
13207379Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13217379Sgblack@eecs.umich.edu                      case 2:
13227379Sgblack@eecs.umich.edu                        return new Vqdmulls<int32_t>(
13237379Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13247379Sgblack@eecs.umich.edu                      default:
13257379Sgblack@eecs.umich.edu                        return new Unknown(machInst);
13267379Sgblack@eecs.umich.edu                    }
13277379Sgblack@eecs.umich.edu                }
13287379Sgblack@eecs.umich.edu            }
13297379Sgblack@eecs.umich.edu          case 0xc:
13307379Sgblack@eecs.umich.edu            if (u) {
13317379Sgblack@eecs.umich.edu                switch (size) {
13327382Sgblack@eecs.umich.edu                  case 1:
13337379Sgblack@eecs.umich.edu                    return new VqdmulhsQ<int16_t>(
13347381Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13357379Sgblack@eecs.umich.edu                  case 2:
13367381Sgblack@eecs.umich.edu                    return new VqdmulhsQ<int32_t>(
13377379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13387379Sgblack@eecs.umich.edu                  default:
13397379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13407379Sgblack@eecs.umich.edu                }
13417379Sgblack@eecs.umich.edu            } else {
13427379Sgblack@eecs.umich.edu                switch (size) {
13437379Sgblack@eecs.umich.edu                  case 1:
13447379Sgblack@eecs.umich.edu                    return new VqdmulhsD<int16_t>(
13457379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13467379Sgblack@eecs.umich.edu                  case 2:
13477379Sgblack@eecs.umich.edu                    return new VqdmulhsD<int32_t>(
13487379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13497379Sgblack@eecs.umich.edu                  default:
13507382Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13517379Sgblack@eecs.umich.edu                }
13527381Sgblack@eecs.umich.edu            }
13537379Sgblack@eecs.umich.edu          case 0xd:
13547381Sgblack@eecs.umich.edu            if (u) {
13557379Sgblack@eecs.umich.edu                switch (size) {
13567379Sgblack@eecs.umich.edu                  case 1:
13577379Sgblack@eecs.umich.edu                    return new VqrdmulhsQ<int16_t>(
13587379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13597379Sgblack@eecs.umich.edu                  case 2:
13607379Sgblack@eecs.umich.edu                    return new VqrdmulhsQ<int32_t>(
13617379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13627379Sgblack@eecs.umich.edu                  default:
13637379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13647379Sgblack@eecs.umich.edu                }
13657379Sgblack@eecs.umich.edu            } else {
13667379Sgblack@eecs.umich.edu                switch (size) {
13677379Sgblack@eecs.umich.edu                  case 1:
13687382Sgblack@eecs.umich.edu                    return new VqrdmulhsD<int16_t>(
13697379Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13707381Sgblack@eecs.umich.edu                  case 2:
13717379Sgblack@eecs.umich.edu                    return new VqrdmulhsD<int32_t>(
13727381Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13737379Sgblack@eecs.umich.edu                  default:
13747379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13757379Sgblack@eecs.umich.edu                }
13767379Sgblack@eecs.umich.edu            }
13777379Sgblack@eecs.umich.edu        }
13787379Sgblack@eecs.umich.edu        return new Unknown(machInst);
13797379Sgblack@eecs.umich.edu    }
13807379Sgblack@eecs.umich.edu
13817379Sgblack@eecs.umich.edu    static StaticInstPtr
13827379Sgblack@eecs.umich.edu    decodeNeonTwoRegMisc(ExtMachInst machInst)
13837379Sgblack@eecs.umich.edu    {
13847379Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 17, 16);
13857379Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 10, 6);
13867382Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
13877379Sgblack@eecs.umich.edu        const IntRegIndex vd =
13887381Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
13897379Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
13907381Sgblack@eecs.umich.edu        const IntRegIndex vm =
13917379Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
13927379Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
13937379Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 19, 18);
13947379Sgblack@eecs.umich.edu        switch (a) {
13957379Sgblack@eecs.umich.edu          case 0x0:
13967379Sgblack@eecs.umich.edu            switch (bits(b, 4, 1)) {
13977379Sgblack@eecs.umich.edu              case 0x0:
13987379Sgblack@eecs.umich.edu                switch (size) {
13997379Sgblack@eecs.umich.edu                  case 0:
14007379Sgblack@eecs.umich.edu                    if (q) {
14017379Sgblack@eecs.umich.edu                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
14027379Sgblack@eecs.umich.edu                    } else {
14037379Sgblack@eecs.umich.edu                        return new NVrev64D<uint8_t>(machInst, vd, vm);
14047379Sgblack@eecs.umich.edu                    }
14057381Sgblack@eecs.umich.edu                  case 1:
14067379Sgblack@eecs.umich.edu                    if (q) {
14077381Sgblack@eecs.umich.edu                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
14087379Sgblack@eecs.umich.edu                    } else {
14097379Sgblack@eecs.umich.edu                        return new NVrev64D<uint16_t>(machInst, vd, vm);
14107379Sgblack@eecs.umich.edu                    }
14117379Sgblack@eecs.umich.edu                  case 2:
14127379Sgblack@eecs.umich.edu                    if (q) {
14137379Sgblack@eecs.umich.edu                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
14147379Sgblack@eecs.umich.edu                    } else {
14157379Sgblack@eecs.umich.edu                        return new NVrev64D<uint32_t>(machInst, vd, vm);
14167379Sgblack@eecs.umich.edu                    }
14177379Sgblack@eecs.umich.edu                  default:
14187379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
14197379Sgblack@eecs.umich.edu                }
14207379Sgblack@eecs.umich.edu              case 0x1:
14217379Sgblack@eecs.umich.edu                switch (size) {
14227381Sgblack@eecs.umich.edu                  case 0:
14237379Sgblack@eecs.umich.edu                    if (q) {
14247381Sgblack@eecs.umich.edu                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
14257379Sgblack@eecs.umich.edu                    } else {
14267379Sgblack@eecs.umich.edu                        return new NVrev32D<uint8_t>(machInst, vd, vm);
14277379Sgblack@eecs.umich.edu                    }
14287379Sgblack@eecs.umich.edu                  case 1:
14297379Sgblack@eecs.umich.edu                    if (q) {
14307379Sgblack@eecs.umich.edu                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
14317379Sgblack@eecs.umich.edu                    } else {
14327379Sgblack@eecs.umich.edu                        return new NVrev32D<uint16_t>(machInst, vd, vm);
14337379Sgblack@eecs.umich.edu                    }
14347379Sgblack@eecs.umich.edu                  default:
14357379Sgblack@eecs.umich.edu                    return new Unknown(machInst);
14367379Sgblack@eecs.umich.edu                }
14377379Sgblack@eecs.umich.edu              case 0x2:
14387379Sgblack@eecs.umich.edu                if (size != 0) {
14397381Sgblack@eecs.umich.edu                    return new Unknown(machInst);
14407379Sgblack@eecs.umich.edu                } else if (q) {
14417381Sgblack@eecs.umich.edu                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
14427379Sgblack@eecs.umich.edu                } else {
14437379Sgblack@eecs.umich.edu                    return new NVrev16D<uint8_t>(machInst, vd, vm);
14447379Sgblack@eecs.umich.edu                }
14457379Sgblack@eecs.umich.edu              case 0x4:
14467379Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14477379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14487379Sgblack@eecs.umich.edu              case 0x5:
14497379Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14507379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14517379Sgblack@eecs.umich.edu              case 0x8:
14527379Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
14537379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14547379Sgblack@eecs.umich.edu              case 0x9:
14557379Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
14567381Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14577379Sgblack@eecs.umich.edu              case 0xa:
14587381Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
14597379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14607379Sgblack@eecs.umich.edu              case 0xb:
14617379Sgblack@eecs.umich.edu                if (q)
14627379Sgblack@eecs.umich.edu                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
14637379Sgblack@eecs.umich.edu                else
14647379Sgblack@eecs.umich.edu                    return new NVmvnD<uint64_t>(machInst, vd, vm);
14657379Sgblack@eecs.umich.edu              case 0xc:
14667379Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
14677379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14687379Sgblack@eecs.umich.edu              case 0xd:
14697379Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
14707379Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
1471              case 0xe:
1472                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1473                        q, size, machInst, vd, vm);
1474              case 0xf:
1475                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1476                        q, size, machInst, vd, vm);
1477              default:
1478                return new Unknown(machInst);
1479            }
1480          case 0x1:
1481            switch (bits(b, 3, 1)) {
1482              case 0x0:
1483                if (bits(b, 4)) {
1484                    if (q) {
1485                        return new NVcgtQFp<float>(machInst, vd, vm);
1486                    } else {
1487                        return new NVcgtDFp<float>(machInst, vd, vm);
1488                    }
1489                } else {
1490                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1491                            q, size, machInst, vd, vm);
1492                }
1493              case 0x1:
1494                if (bits(b, 4)) {
1495                    if (q) {
1496                        return new NVcgeQFp<float>(machInst, vd, vm);
1497                    } else {
1498                        return new NVcgeDFp<float>(machInst, vd, vm);
1499                    }
1500                } else {
1501                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1502                            q, size, machInst, vd, vm);
1503                }
1504              case 0x2:
1505                if (bits(b, 4)) {
1506                    if (q) {
1507                        return new NVceqQFp<float>(machInst, vd, vm);
1508                    } else {
1509                        return new NVceqDFp<float>(machInst, vd, vm);
1510                    }
1511                } else {
1512                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1513                            q, size, machInst, vd, vm);
1514                }
1515              case 0x3:
1516                if (bits(b, 4)) {
1517                    if (q) {
1518                        return new NVcleQFp<float>(machInst, vd, vm);
1519                    } else {
1520                        return new NVcleDFp<float>(machInst, vd, vm);
1521                    }
1522                } else {
1523                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1524                            q, size, machInst, vd, vm);
1525                }
1526              case 0x4:
1527                if (bits(b, 4)) {
1528                    if (q) {
1529                        return new NVcltQFp<float>(machInst, vd, vm);
1530                    } else {
1531                        return new NVcltDFp<float>(machInst, vd, vm);
1532                    }
1533                } else {
1534                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1535                            q, size, machInst, vd, vm);
1536                }
1537              case 0x6:
1538                if (bits(machInst, 10)) {
1539                    if (q)
1540                        return new NVabsQFp<float>(machInst, vd, vm);
1541                    else
1542                        return new NVabsDFp<float>(machInst, vd, vm);
1543                } else {
1544                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1545                            q, size, machInst, vd, vm);
1546                }
1547              case 0x7:
1548                if (bits(machInst, 10)) {
1549                    if (q)
1550                        return new NVnegQFp<float>(machInst, vd, vm);
1551                    else
1552                        return new NVnegDFp<float>(machInst, vd, vm);
1553                } else {
1554                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1555                            q, size, machInst, vd, vm);
1556                }
1557              default:
1558                return new Unknown64(machInst);
1559            }
1560          case 0x2:
1561            switch (bits(b, 4, 1)) {
1562              case 0x0:
1563                if (q)
1564                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1565                else
1566                    return new NVswpD<uint64_t>(machInst, vd, vm);
1567              case 0x1:
1568                return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1569                        q, size, machInst, vd, vm);
1570              case 0x2:
1571                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1572                        q, size, machInst, vd, vm);
1573              case 0x3:
1574                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1575                        q, size, machInst, vd, vm);
1576              case 0x4:
1577                if (b == 0x8) {
1578                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1579                            size, machInst, vd, vm);
1580                } else {
1581                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1582                            size, machInst, vd, vm);
1583                }
1584              case 0x5:
1585                if (q) {
1586                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1587                            size, machInst, vd, vm);
1588                } else {
1589                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1590                            size, machInst, vd, vm);
1591                }
1592              case 0x6:
1593                if (b == 0xc) {
1594                    return decodeNeonSTwoShiftUSReg<NVshll>(
1595                            size, machInst, vd, vm, 8 << size);
1596                } else {
1597                    return new Unknown(machInst);
1598                }
1599              case 0xc:
1600              case 0xe:
1601                if (b == 0x18) {
1602                    if (size != 1 || (vm % 2))
1603                        return new Unknown(machInst);
1604                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1605                } else if (b == 0x1c) {
1606                    if (size != 1 || (vd % 2))
1607                        return new Unknown(machInst);
1608                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1609                } else {
1610                    return new Unknown(machInst);
1611                }
1612              default:
1613                return new Unknown(machInst);
1614            }
1615          case 0x3:
1616            if (bits(b, 4, 3) == 0x3) {
1617                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1618                    return new Unknown(machInst);
1619                } else {
1620                    if (bits(b, 2)) {
1621                        if (bits(b, 1)) {
1622                            if (q) {
1623                                return new NVcvt2ufxQ<float>(
1624                                        machInst, vd, vm, 0);
1625                            } else {
1626                                return new NVcvt2ufxD<float>(
1627                                        machInst, vd, vm, 0);
1628                            }
1629                        } else {
1630                            if (q) {
1631                                return new NVcvt2sfxQ<float>(
1632                                        machInst, vd, vm, 0);
1633                            } else {
1634                                return new NVcvt2sfxD<float>(
1635                                        machInst, vd, vm, 0);
1636                            }
1637                        }
1638                    } else {
1639                        if (bits(b, 1)) {
1640                            if (q) {
1641                                return new NVcvtu2fpQ<float>(
1642                                        machInst, vd, vm, 0);
1643                            } else {
1644                                return new NVcvtu2fpD<float>(
1645                                        machInst, vd, vm, 0);
1646                            }
1647                        } else {
1648                            if (q) {
1649                                return new NVcvts2fpQ<float>(
1650                                        machInst, vd, vm, 0);
1651                            } else {
1652                                return new NVcvts2fpD<float>(
1653                                        machInst, vd, vm, 0);
1654                            }
1655                        }
1656                    }
1657                }
1658            } else if ((b & 0x1a) == 0x10) {
1659                if (bits(b, 2)) {
1660                    if (q) {
1661                        return new NVrecpeQFp<float>(machInst, vd, vm);
1662                    } else {
1663                        return new NVrecpeDFp<float>(machInst, vd, vm);
1664                    }
1665                } else {
1666                    if (q) {
1667                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1668                    } else {
1669                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1670                    }
1671                }
1672            } else if ((b & 0x1a) == 0x12) {
1673                if (bits(b, 2)) {
1674                    if (q) {
1675                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1676                    } else {
1677                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1678                    }
1679                } else {
1680                    if (q) {
1681                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1682                    } else {
1683                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1684                    }
1685                }
1686            } else {
1687                return new Unknown(machInst);
1688            }
1689        }
1690        return new Unknown(machInst);
1691    }
1692
1693    StaticInstPtr
1694    decodeNeonData(ExtMachInst machInst)
1695    {
1696        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1697        const uint32_t a = bits(machInst, 23, 19);
1698        const uint32_t b = bits(machInst, 11, 8);
1699        const uint32_t c = bits(machInst, 7, 4);
1700        if (bits(a, 4) == 0) {
1701            return decodeNeonThreeRegistersSameLength(machInst);
1702        } else if ((c & 0x9) == 1) {
1703            if ((a & 0x7) == 0) {
1704                return decodeNeonOneRegModImm(machInst);
1705            } else {
1706                return decodeNeonTwoRegAndShift(machInst);
1707            }
1708        } else if ((c & 0x9) == 9) {
1709            return decodeNeonTwoRegAndShift(machInst);
1710        } else if (bits(a, 2, 1) != 0x3) {
1711            if ((c & 0x5) == 0) {
1712                return decodeNeonThreeRegDiffLengths(machInst);
1713            } else if ((c & 0x5) == 4) {
1714                return decodeNeonTwoRegScalar(machInst);
1715            }
1716        } else if ((a & 0x16) == 0x16) {
1717            const IntRegIndex vd =
1718                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1719                                   (bits(machInst, 22) << 4)));
1720            const IntRegIndex vn =
1721                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1722                                   (bits(machInst, 7) << 4)));
1723            const IntRegIndex vm =
1724                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1725                                   (bits(machInst, 5) << 4)));
1726            if (!u) {
1727                if (bits(c, 0) == 0) {
1728                    unsigned imm4 = bits(machInst, 11, 8);
1729                    bool q = bits(machInst, 6);
1730                    if (imm4 >= 16 && !q)
1731                        return new Unknown(machInst);
1732                    if (q) {
1733                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1734                    } else {
1735                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1736                    }
1737                }
1738            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1739                return decodeNeonTwoRegMisc(machInst);
1740            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1741                unsigned length = bits(machInst, 9, 8) + 1;
1742                if ((uint32_t)vn / 2 + length > 32)
1743                    return new Unknown(machInst);
1744                if (bits(machInst, 6) == 0) {
1745                    switch (length) {
1746                      case 1:
1747                        return new NVtbl1(machInst, vd, vn, vm);
1748                      case 2:
1749                        return new NVtbl2(machInst, vd, vn, vm);
1750                      case 3:
1751                        return new NVtbl3(machInst, vd, vn, vm);
1752                      case 4:
1753                        return new NVtbl4(machInst, vd, vn, vm);
1754                    }
1755                } else {
1756                    switch (length) {
1757                      case 1:
1758                        return new NVtbx1(machInst, vd, vn, vm);
1759                      case 2:
1760                        return new NVtbx2(machInst, vd, vn, vm);
1761                      case 3:
1762                        return new NVtbx3(machInst, vd, vn, vm);
1763                      case 4:
1764                        return new NVtbx4(machInst, vd, vn, vm);
1765                    }
1766                }
1767            } else if (b == 0xc && (c & 0x9) == 0) {
1768                unsigned imm4 = bits(machInst, 19, 16);
1769                if (bits(imm4, 2, 0) == 0)
1770                    return new Unknown(machInst);
1771                unsigned size = 0;
1772                while ((imm4 & 0x1) == 0) {
1773                    size++;
1774                    imm4 >>= 1;
1775                }
1776                unsigned index = imm4 >> 1;
1777                const bool q = bits(machInst, 6);
1778                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1779                        q, size, machInst, vd, vm, index);
1780            }
1781        }
1782        return new Unknown(machInst);
1783    }
1784    '''
1785}};
1786
1787def format ThumbNeonMem() {{
1788    decode_block = '''
1789    return decodeNeonMem(machInst);
1790    '''
1791}};
1792
1793def format ThumbNeonData() {{
1794    decode_block = '''
1795    return decodeNeonData(machInst);
1796    '''
1797}};
1798
1799let {{
1800    header_output = '''
1801    StaticInstPtr
1802    decodeExtensionRegLoadStore(ExtMachInst machInst);
1803    '''
1804    decoder_output = '''
1805    StaticInstPtr
1806    decodeExtensionRegLoadStore(ExtMachInst machInst)
1807    {
1808        const uint32_t opcode = bits(machInst, 24, 20);
1809        const uint32_t offset = bits(machInst, 7, 0);
1810        const bool single = (bits(machInst, 8) == 0);
1811        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1812        RegIndex vd;
1813        if (single) {
1814            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1815                                      bits(machInst, 22));
1816        } else {
1817            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1818                                      (bits(machInst, 22) << 5));
1819        }
1820        switch (bits(opcode, 4, 3)) {
1821          case 0x0:
1822            if (bits(opcode, 4, 1) == 0x2 &&
1823                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1824                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1825                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1826                    break;
1827                }
1828                const IntRegIndex rt =
1829                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1830                const IntRegIndex rt2 =
1831                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1832                const bool op = bits(machInst, 20);
1833                uint32_t vm;
1834                if (single) {
1835                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1836                } else {
1837                    vm = (bits(machInst, 3, 0) << 1) |
1838                         (bits(machInst, 5) << 5);
1839                }
1840                if (op) {
1841                    return new Vmov2Core2Reg(machInst, rt, rt2,
1842                                             (IntRegIndex)vm);
1843                } else {
1844                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1845                                             rt, rt2);
1846                }
1847            }
1848            break;
1849          case 0x1:
1850            {
1851                if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1852                    break;
1853                }
1854                switch (bits(opcode, 1, 0)) {
1855                  case 0x0:
1856                    return new VLdmStm(machInst, rn, vd, single,
1857                                       true, false, false, offset);
1858                  case 0x1:
1859                    return new VLdmStm(machInst, rn, vd, single,
1860                                       true, false, true, offset);
1861                  case 0x2:
1862                    return new VLdmStm(machInst, rn, vd, single,
1863                                       true, true, false, offset);
1864                  case 0x3:
1865                    // If rn == sp, then this is called vpop.
1866                    return new VLdmStm(machInst, rn, vd, single,
1867                                       true, true, true, offset);
1868                  default:
1869                    M5_UNREACHABLE;
1870                }
1871            }
1872          case 0x2:
1873            if (bits(opcode, 1, 0) == 0x2) {
1874                // If rn == sp, then this is called vpush.
1875                return new VLdmStm(machInst, rn, vd, single,
1876                                   false, true, false, offset);
1877            } else if (bits(opcode, 1, 0) == 0x3) {
1878                return new VLdmStm(machInst, rn, vd, single,
1879                                   false, true, true, offset);
1880            }
1881            M5_FALLTHROUGH;
1882          case 0x3:
1883            const bool up = (bits(machInst, 23) == 1);
1884            const uint32_t imm = bits(machInst, 7, 0) << 2;
1885            if (single) {
1886                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1887                                          (bits(machInst, 22)));
1888            } else {
1889                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1890                                          (bits(machInst, 22) << 5));
1891            }
1892            if (bits(opcode, 1, 0) == 0x0) {
1893                if (single) {
1894                    if (up) {
1895                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1896                    } else {
1897                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1898                    }
1899                } else {
1900                    if (up) {
1901                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1902                                               rn, up, imm);
1903                    } else {
1904                        return new %(vstr_d)s(machInst, vd, vd + 1,
1905                                              rn, up, imm);
1906                    }
1907                }
1908            } else if (bits(opcode, 1, 0) == 0x1) {
1909                if (single) {
1910                    if (up) {
1911                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1912                    } else {
1913                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1914                    }
1915                } else {
1916                    if (up) {
1917                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1918                                               rn, up, imm);
1919                    } else {
1920                        return new %(vldr_d)s(machInst, vd, vd + 1,
1921                                              rn, up, imm);
1922                    }
1923                }
1924            }
1925        }
1926        return new Unknown(machInst);
1927    }
1928    ''' % {
1929        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1930        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1931        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1932        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1933        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1934        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1935        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1936        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1937    }
1938}};
1939
1940def format ExtensionRegLoadStore() {{
1941    decode_block = '''
1942    return decodeExtensionRegLoadStore(machInst);
1943    '''
1944}};
1945
1946let {{
1947    header_output = '''
1948    StaticInstPtr
1949    decodeShortFpTransfer(ExtMachInst machInst);
1950    '''
1951    decoder_output = '''
1952    StaticInstPtr
1953    decodeShortFpTransfer(ExtMachInst machInst)
1954    {
1955        const uint32_t l = bits(machInst, 20);
1956        const uint32_t c = bits(machInst, 8);
1957        const uint32_t a = bits(machInst, 23, 21);
1958        const uint32_t b = bits(machInst, 6, 5);
1959        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1960            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1961            // Determine if this is backported aarch64 FP instruction
1962            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
1963            const bool b23 = bits(machInst, 23);
1964            const bool b21_b18 = bits(machInst, 21, 18) == 0xE;
1965            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
1966            const bool sz = bits(machInst, 8);
1967            const bool b7_b6   = bits(machInst, 7, 6) == 0x1;
1968            const bool b6 = bits(machInst, 6) == 0x0;
1969            const bool b4 = bits(machInst, 4) == 0x0;
1970            if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) {
1971                  // VINT* Integer Rounding Instructon
1972                  const uint32_t rm = bits(machInst, 17, 16);
1973
1974                  if (sz) {
1975                      const IntRegIndex vd =
1976                          (IntRegIndex)((bits(machInst, 22) << 5) |
1977                                        (bits(machInst, 15, 12) << 1));
1978                      const IntRegIndex vm =
1979                          (IntRegIndex)((bits(machInst, 5) << 5) |
1980                                        (bits(machInst, 3, 0) << 1));
1981                      switch(rm) {
1982                        case 0x0:
1983                          return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
1984                                                            true);
1985                        case 0x1:
1986                          return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
1987                                                            true);
1988                        case 0x2:
1989                          return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
1990                                                            true);
1991                        case 0x3:
1992                          return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
1993                                                            true);
1994                        default: return new Unknown(machInst);
1995                      }
1996                  } else {
1997                      const IntRegIndex vd =
1998                          (IntRegIndex)(bits(machInst, 22) |
1999                                       (bits(machInst, 15, 12) << 1));
2000                      const IntRegIndex vm =
2001                          (IntRegIndex)(bits(machInst, 5) |
2002                                        (bits(machInst, 3, 0) << 1));
2003                      switch(rm) {
2004                        case 0x0:
2005                          return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
2006                                                            false);
2007                        case 0x1:
2008                          return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2009                                                            false);
2010                        case 0x2:
2011                          return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2012                                                            false);
2013                        case 0x3:
2014                          return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2015                                                            false);
2016                        default: return new Unknown(machInst);
2017                      }
2018                  }
2019            } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){
2020                // VSEL* floating point conditional select
2021
2022                ConditionCode cond;
2023                switch(bits(machInst, 21, 20)) {
2024                  case 0x0: cond = COND_EQ; break;
2025                  case 0x1: cond = COND_VS; break;
2026                  case 0x2: cond = COND_GE; break;
2027                  case 0x3: cond = COND_GT; break;
2028                }
2029
2030                if (sz) {
2031                      const IntRegIndex vd =
2032                          (IntRegIndex)((bits(machInst, 22) << 5) |
2033                                        (bits(machInst, 15, 12) << 1));
2034                      const IntRegIndex vm =
2035                          (IntRegIndex)((bits(machInst, 5) << 5) |
2036                                        (bits(machInst, 3, 0) << 1));
2037                      const IntRegIndex vn =
2038                          (IntRegIndex)((bits(machInst, 7) << 5) |
2039                                       (bits(machInst, 19, 16) << 1));
2040                    return new VselD(machInst, vd, vn, vm, cond);
2041                } else {
2042                      const IntRegIndex vd =
2043                          (IntRegIndex)(bits(machInst, 22) |
2044                                       (bits(machInst, 15, 12) << 1));
2045                      const IntRegIndex vm =
2046                          (IntRegIndex)(bits(machInst, 5) |
2047                                        (bits(machInst, 3, 0) << 1));
2048                      const IntRegIndex vn =
2049                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2050                                        bits(machInst, 7));
2051                      return new VselS(machInst, vd, vn, vm, cond);
2052                }
2053            } else {
2054                return new Unknown(machInst);
2055            }
2056        }
2057        if (l == 0 && c == 0) {
2058            if (a == 0) {
2059                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2060                                    bits(machInst, 7);
2061                const IntRegIndex rt =
2062                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2063                if (bits(machInst, 20) == 1) {
2064                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2065                } else {
2066                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2067                }
2068            } else if (a == 0x7) {
2069                const IntRegIndex rt =
2070                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2071                uint32_t reg = bits(machInst, 19, 16);
2072                uint32_t specReg;
2073                switch (reg) {
2074                  case 0:
2075                    specReg = MISCREG_FPSID;
2076                    break;
2077                  case 1:
2078                    specReg = MISCREG_FPSCR;
2079                    break;
2080                  case 6:
2081                    specReg = MISCREG_MVFR1;
2082                    break;
2083                  case 7:
2084                    specReg = MISCREG_MVFR0;
2085                    break;
2086                  case 8:
2087                    specReg = MISCREG_FPEXC;
2088                    break;
2089                  default:
2090                    return new Unknown(machInst);
2091                }
2092                if (specReg == MISCREG_FPSCR) {
2093                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2094                } else {
2095                    uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2096                        reg, a, bits(machInst, 7, 5));
2097                    return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2098                }
2099            }
2100        } else if (l == 0 && c == 1) {
2101            if (bits(a, 2) == 0) {
2102                uint32_t vd = (bits(machInst, 7) << 5) |
2103                              (bits(machInst, 19, 16) << 1);
2104                // Handle accessing each single precision half of the vector.
2105                vd += bits(machInst, 21);
2106                const IntRegIndex rt =
2107                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2108                if (bits(machInst, 22) == 1) {
2109                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2110                                            rt, bits(machInst, 6, 5));
2111                } else if (bits(machInst, 5) == 1) {
2112                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2113                                            rt, bits(machInst, 6));
2114                } else if (bits(machInst, 6) == 0) {
2115                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2116                } else {
2117                    return new Unknown(machInst);
2118                }
2119            } else if (bits(b, 1) == 0) {
2120                bool q = bits(machInst, 21);
2121                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2122                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2123                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2124                IntRegIndex rt = (IntRegIndex)(uint32_t)
2125                    bits(machInst, 15, 12);
2126                if (q) {
2127                    switch (be) {
2128                      case 0:
2129                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2130                      case 1:
2131                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2132                      case 2:
2133                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2134                      case 3:
2135                        return new Unknown(machInst);
2136                    }
2137                } else {
2138                    switch (be) {
2139                      case 0:
2140                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2141                      case 1:
2142                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2143                      case 2:
2144                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2145                      case 3:
2146                        return new Unknown(machInst);
2147                    }
2148                }
2149            }
2150        } else if (l == 1 && c == 0) {
2151            if (a == 0) {
2152                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2153                                    bits(machInst, 7);
2154                const IntRegIndex rt =
2155                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2156                if (bits(machInst, 20) == 1) {
2157                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2158                } else {
2159                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2160                }
2161            } else if (a == 7) {
2162                const IntRegIndex rt =
2163                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2164                uint32_t reg = bits(machInst, 19, 16);
2165                uint32_t specReg;
2166                switch (reg) {
2167                  case 0:
2168                    specReg = MISCREG_FPSID;
2169                    break;
2170                  case 1:
2171                    specReg = MISCREG_FPSCR;
2172                    break;
2173                  case 6:
2174                    specReg = MISCREG_MVFR1;
2175                    break;
2176                  case 7:
2177                    specReg = MISCREG_MVFR0;
2178                    break;
2179                  case 8:
2180                    specReg = MISCREG_FPEXC;
2181                    break;
2182                  default:
2183                    return new Unknown(machInst);
2184                }
2185                if (rt == 0xf) {
2186                    if (specReg == MISCREG_FPSCR) {
2187                        return new VmrsApsrFpscr(machInst);
2188                    } else {
2189                        return new Unknown(machInst);
2190                    }
2191                } else if (specReg == MISCREG_FPSCR) {
2192                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2193                } else {
2194                    uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2195                        reg, a, bits(machInst, 7, 5));
2196                    return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2197                }
2198            }
2199        } else {
2200            uint32_t vd = (bits(machInst, 7) << 5) |
2201                          (bits(machInst, 19, 16) << 1);
2202            // Handle indexing into each single precision half of the vector.
2203            vd += bits(machInst, 21);
2204            uint32_t index;
2205            const IntRegIndex rt =
2206                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2207            const bool u = (bits(machInst, 23) == 1);
2208            if (bits(machInst, 22) == 1) {
2209                index = bits(machInst, 6, 5);
2210                if (u) {
2211                    return new VmovRegCoreUB(machInst, rt,
2212                                             (IntRegIndex)vd, index);
2213                } else {
2214                    return new VmovRegCoreSB(machInst, rt,
2215                                             (IntRegIndex)vd, index);
2216                }
2217            } else if (bits(machInst, 5) == 1) {
2218                index = bits(machInst, 6);
2219                if (u) {
2220                    return new VmovRegCoreUH(machInst, rt,
2221                                             (IntRegIndex)vd, index);
2222                } else {
2223                    return new VmovRegCoreSH(machInst, rt,
2224                                             (IntRegIndex)vd, index);
2225                }
2226            } else if (bits(machInst, 6) == 0 && !u) {
2227                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2228            } else {
2229                return new Unknown(machInst);
2230            }
2231        }
2232        return new Unknown(machInst);
2233    }
2234    '''
2235}};
2236
2237def format ShortFpTransfer() {{
2238    decode_block = '''
2239    return decodeShortFpTransfer(machInst);
2240    '''
2241}};
2242
2243let {{
2244    header_output = '''
2245    StaticInstPtr
2246    decodeVfpData(ExtMachInst machInst);
2247    '''
2248    decoder_output = '''
2249    StaticInstPtr
2250    decodeVfpData(ExtMachInst machInst)
2251    {
2252        const uint32_t opc1 = bits(machInst, 23, 20);
2253        const uint32_t opc2 = bits(machInst, 19, 16);
2254        const uint32_t opc3 = bits(machInst, 7, 6);
2255        //const uint32_t opc4 = bits(machInst, 3, 0);
2256        const bool single = (bits(machInst, 8) == 0);
2257        // Used to select between vcmp and vcmpe.
2258        const bool e = (bits(machInst, 7) == 1);
2259        IntRegIndex vd;
2260        IntRegIndex vm;
2261        IntRegIndex vn;
2262        if (single) {
2263            vd = (IntRegIndex)(bits(machInst, 22) |
2264                    (bits(machInst, 15, 12) << 1));
2265            vm = (IntRegIndex)(bits(machInst, 5) |
2266                    (bits(machInst, 3, 0) << 1));
2267            vn = (IntRegIndex)(bits(machInst, 7) |
2268                    (bits(machInst, 19, 16) << 1));
2269        } else {
2270            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2271                    (bits(machInst, 15, 12) << 1));
2272            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2273                    (bits(machInst, 3, 0) << 1));
2274            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2275                    (bits(machInst, 19, 16) << 1));
2276        }
2277        switch (opc1 & 0xb /* 1011 */) {
2278          case 0x0:
2279            if (bits(machInst, 6) == 0) {
2280                if (single) {
2281                    return decodeVfpRegRegRegOp<VmlaS>(
2282                            machInst, vd, vn, vm, false);
2283                } else {
2284                    return decodeVfpRegRegRegOp<VmlaD>(
2285                            machInst, vd, vn, vm, true);
2286                }
2287            } else {
2288                if (single) {
2289                    return decodeVfpRegRegRegOp<VmlsS>(
2290                            machInst, vd, vn, vm, false);
2291                } else {
2292                    return decodeVfpRegRegRegOp<VmlsD>(
2293                            machInst, vd, vn, vm, true);
2294                }
2295            }
2296          case 0x1:
2297            if (bits(machInst, 6) == 1) {
2298                if (single) {
2299                    return decodeVfpRegRegRegOp<VnmlaS>(
2300                            machInst, vd, vn, vm, false);
2301                } else {
2302                    return decodeVfpRegRegRegOp<VnmlaD>(
2303                            machInst, vd, vn, vm, true);
2304                }
2305            } else {
2306                if (single) {
2307                    return decodeVfpRegRegRegOp<VnmlsS>(
2308                            machInst, vd, vn, vm, false);
2309                } else {
2310                    return decodeVfpRegRegRegOp<VnmlsD>(
2311                            machInst, vd, vn, vm, true);
2312                }
2313            }
2314          case 0x2:
2315            if ((opc3 & 0x1) == 0) {
2316                if (single) {
2317                    return decodeVfpRegRegRegOp<VmulS>(
2318                            machInst, vd, vn, vm, false);
2319                } else {
2320                    return decodeVfpRegRegRegOp<VmulD>(
2321                            machInst, vd, vn, vm, true);
2322                }
2323            } else {
2324                if (single) {
2325                    return decodeVfpRegRegRegOp<VnmulS>(
2326                            machInst, vd, vn, vm, false);
2327                } else {
2328                    return decodeVfpRegRegRegOp<VnmulD>(
2329                            machInst, vd, vn, vm, true);
2330                }
2331            }
2332          case 0x3:
2333            if ((opc3 & 0x1) == 0) {
2334                if (single) {
2335                    return decodeVfpRegRegRegOp<VaddS>(
2336                            machInst, vd, vn, vm, false);
2337                } else {
2338                    return decodeVfpRegRegRegOp<VaddD>(
2339                            machInst, vd, vn, vm, true);
2340                }
2341            } else {
2342                if (single) {
2343                    return decodeVfpRegRegRegOp<VsubS>(
2344                            machInst, vd, vn, vm, false);
2345                } else {
2346                    return decodeVfpRegRegRegOp<VsubD>(
2347                            machInst, vd, vn, vm, true);
2348                }
2349            }
2350          case 0x8:
2351            if ((opc3 & 0x1) == 0) {
2352                if (single) {
2353                    return decodeVfpRegRegRegOp<VdivS>(
2354                            machInst, vd, vn, vm, false);
2355                } else {
2356                    return decodeVfpRegRegRegOp<VdivD>(
2357                            machInst, vd, vn, vm, true);
2358                }
2359            }
2360            break;
2361          case 0x9:
2362            if ((opc3 & 0x1) == 0) {
2363                if (single) {
2364                    return decodeVfpRegRegRegOp<VfnmaS>(
2365                            machInst, vd, vn, vm, false);
2366                } else {
2367                    return decodeVfpRegRegRegOp<VfnmaD>(
2368                            machInst, vd, vn, vm, true);
2369                }
2370            } else {
2371                if (single) {
2372                    return decodeVfpRegRegRegOp<VfnmsS>(
2373                            machInst, vd, vn, vm, false);
2374                } else {
2375                    return decodeVfpRegRegRegOp<VfnmsD>(
2376                            machInst, vd, vn, vm, true);
2377                }
2378            }
2379            break;
2380          case 0xa:
2381            if ((opc3 & 0x1) == 0) {
2382                if (single) {
2383                    return decodeVfpRegRegRegOp<VfmaS>(
2384                            machInst, vd, vn, vm, false);
2385                } else {
2386                    return decodeVfpRegRegRegOp<VfmaD>(
2387                            machInst, vd, vn, vm, true);
2388                }
2389            } else {
2390                if (single) {
2391                    return decodeVfpRegRegRegOp<VfmsS>(
2392                            machInst, vd, vn, vm, false);
2393                } else {
2394                    return decodeVfpRegRegRegOp<VfmsD>(
2395                            machInst, vd, vn, vm, true);
2396                }
2397            }
2398            break;
2399          case 0xb:
2400            if ((opc3 & 0x1) == 0) {
2401                const uint32_t baseImm =
2402                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2403                if (single) {
2404                    uint32_t imm = vfp_modified_imm(baseImm, false);
2405                    return decodeVfpRegImmOp<VmovImmS>(
2406                            machInst, vd, imm, false);
2407                } else {
2408                    uint64_t imm = vfp_modified_imm(baseImm, true);
2409                    return decodeVfpRegImmOp<VmovImmD>(
2410                            machInst, vd, imm, true);
2411                }
2412            }
2413            switch (opc2) {
2414              case 0x0:
2415                if (opc3 == 1) {
2416                    if (single) {
2417                        return decodeVfpRegRegOp<VmovRegS>(
2418                                machInst, vd, vm, false);
2419                    } else {
2420                        return decodeVfpRegRegOp<VmovRegD>(
2421                                machInst, vd, vm, true);
2422                    }
2423                } else {
2424                    if (single) {
2425                        return decodeVfpRegRegOp<VabsS>(
2426                                machInst, vd, vm, false);
2427                    } else {
2428                        return decodeVfpRegRegOp<VabsD>(
2429                                machInst, vd, vm, true);
2430                    }
2431                }
2432              case 0x1:
2433                if (opc3 == 1) {
2434                    if (single) {
2435                        return decodeVfpRegRegOp<VnegS>(
2436                                machInst, vd, vm, false);
2437                    } else {
2438                        return decodeVfpRegRegOp<VnegD>(
2439                                machInst, vd, vm, true);
2440                    }
2441                } else {
2442                    if (single) {
2443                        return decodeVfpRegRegOp<VsqrtS>(
2444                                machInst, vd, vm, false);
2445                    } else {
2446                        return decodeVfpRegRegOp<VsqrtD>(
2447                                machInst, vd, vm, true);
2448                    }
2449                }
2450              case 0x2:
2451              case 0x3:
2452                {
2453                    const bool toHalf = bits(machInst, 16);
2454                    const bool top = bits(machInst, 7);
2455                    if (top) {
2456                        if (toHalf) {
2457                            return new VcvtFpSFpHT(machInst, vd, vm);
2458                        } else {
2459                            return new VcvtFpHTFpS(machInst, vd, vm);
2460                        }
2461                    } else {
2462                        if (toHalf) {
2463                            return new VcvtFpSFpHB(machInst, vd, vm);
2464                        } else {
2465                            return new VcvtFpHBFpS(machInst, vd, vm);
2466                        }
2467                    }
2468                }
2469              case 0x4:
2470                if (single) {
2471                    if (e) {
2472                        return new VcmpeS(machInst, vd, vm);
2473                    } else {
2474                        return new VcmpS(machInst, vd, vm);
2475                    }
2476                } else {
2477                    if (e) {
2478                        return new VcmpeD(machInst, vd, vm);
2479                    } else {
2480                        return new VcmpD(machInst, vd, vm);
2481                    }
2482                }
2483              case 0x5:
2484                if (single) {
2485                    if (e) {
2486                        return new VcmpeZeroS(machInst, vd, 0);
2487                    } else {
2488                        return new VcmpZeroS(machInst, vd, 0);
2489                    }
2490                } else {
2491                    if (e) {
2492                        return new VcmpeZeroD(machInst, vd, 0);
2493                    } else {
2494                        return new VcmpZeroD(machInst, vd, 0);
2495                    }
2496                }
2497              case 0x7:
2498                if (opc3 == 0x3) {
2499                    if (single) {
2500                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2501                                (bits(machInst, 15, 12) << 1));
2502                        return new VcvtFpSFpD(machInst, vd, vm);
2503                    } else {
2504                        vd = (IntRegIndex)(bits(machInst, 22) |
2505                                (bits(machInst, 15, 12) << 1));
2506                        return new VcvtFpDFpS(machInst, vd, vm);
2507                    }
2508                }
2509                break;
2510              case 0x8:
2511                if (bits(machInst, 7) == 0) {
2512                    if (single) {
2513                        return new VcvtUIntFpS(machInst, vd, vm);
2514                    } else {
2515                        vm = (IntRegIndex)(bits(machInst, 5) |
2516                                (bits(machInst, 3, 0) << 1));
2517                        return new VcvtUIntFpD(machInst, vd, vm);
2518                    }
2519                } else {
2520                    if (single) {
2521                        return new VcvtSIntFpS(machInst, vd, vm);
2522                    } else {
2523                        vm = (IntRegIndex)(bits(machInst, 5) |
2524                                (bits(machInst, 3, 0) << 1));
2525                        return new VcvtSIntFpD(machInst, vd, vm);
2526                    }
2527                }
2528              case 0xa:
2529                {
2530                    const bool half = (bits(machInst, 7) == 0);
2531                    const uint32_t imm = bits(machInst, 5) |
2532                                         (bits(machInst, 3, 0) << 1);
2533                    const uint32_t size =
2534                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2535                    if (single) {
2536                        if (half) {
2537                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2538                        } else {
2539                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2540                        }
2541                    } else {
2542                        if (half) {
2543                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2544                        } else {
2545                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2546                        }
2547                    }
2548                }
2549              case 0xb:
2550                {
2551                    const bool half = (bits(machInst, 7) == 0);
2552                    const uint32_t imm = bits(machInst, 5) |
2553                                         (bits(machInst, 3, 0) << 1);
2554                    const uint32_t size =
2555                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2556                    if (single) {
2557                        if (half) {
2558                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2559                        } else {
2560                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2561                        }
2562                    } else {
2563                        if (half) {
2564                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2565                        } else {
2566                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2567                        }
2568                    }
2569                }
2570              case 0xc:
2571                if (bits(machInst, 7) == 0) {
2572                    if (single) {
2573                        return new VcvtFpUIntSR(machInst, vd, vm);
2574                    } else {
2575                        vd = (IntRegIndex)(bits(machInst, 22) |
2576                                (bits(machInst, 15, 12) << 1));
2577                        return new VcvtFpUIntDR(machInst, vd, vm);
2578                    }
2579                } else {
2580                    if (single) {
2581                        return new VcvtFpUIntS(machInst, vd, vm);
2582                    } else {
2583                        vd = (IntRegIndex)(bits(machInst, 22) |
2584                                (bits(machInst, 15, 12) << 1));
2585                        return new VcvtFpUIntD(machInst, vd, vm);
2586                    }
2587                }
2588              case 0xd:
2589                if (bits(machInst, 7) == 0) {
2590                    if (single) {
2591                        return new VcvtFpSIntSR(machInst, vd, vm);
2592                    } else {
2593                        vd = (IntRegIndex)(bits(machInst, 22) |
2594                                (bits(machInst, 15, 12) << 1));
2595                        return new VcvtFpSIntDR(machInst, vd, vm);
2596                    }
2597                } else {
2598                    if (single) {
2599                        return new VcvtFpSIntS(machInst, vd, vm);
2600                    } else {
2601                        vd = (IntRegIndex)(bits(machInst, 22) |
2602                                (bits(machInst, 15, 12) << 1));
2603                        return new VcvtFpSIntD(machInst, vd, vm);
2604                    }
2605                }
2606              case 0xe:
2607                {
2608                    const bool half = (bits(machInst, 7) == 0);
2609                    const uint32_t imm = bits(machInst, 5) |
2610                                         (bits(machInst, 3, 0) << 1);
2611                    const uint32_t size =
2612                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2613                    if (single) {
2614                        if (half) {
2615                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2616                        } else {
2617                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2618                        }
2619                    } else {
2620                        if (half) {
2621                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2622                        } else {
2623                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2624                        }
2625                    }
2626                }
2627              case 0xf:
2628                {
2629                    const bool half = (bits(machInst, 7) == 0);
2630                    const uint32_t imm = bits(machInst, 5) |
2631                                         (bits(machInst, 3, 0) << 1);
2632                    const uint32_t size =
2633                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2634                    if (single) {
2635                        if (half) {
2636                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2637                        } else {
2638                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2639                        }
2640                    } else {
2641                        if (half) {
2642                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2643                        } else {
2644                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2645                        }
2646                    }
2647                }
2648            }
2649            break;
2650        }
2651        return new Unknown(machInst);
2652    }
2653    '''
2654}};
2655
2656def format VfpData() {{
2657    decode_block = '''
2658    return decodeVfpData(machInst);
2659    '''
2660}};
2661