fp.isa revision 8301
16019Shines@cs.fsu.edu// -*- mode:c++ -*-
26019Shines@cs.fsu.edu
37178Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited
47178Sgblack@eecs.umich.edu// All rights reserved
57178Sgblack@eecs.umich.edu//
67178Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
77178Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
87178Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
97178Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
107178Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
117178Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
127178Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
137178Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
147178Sgblack@eecs.umich.edu//
156019Shines@cs.fsu.edu// Copyright (c) 2007-2008 The Florida State University
166019Shines@cs.fsu.edu// All rights reserved.
176019Shines@cs.fsu.edu//
186019Shines@cs.fsu.edu// Redistribution and use in source and binary forms, with or without
196019Shines@cs.fsu.edu// modification, are permitted provided that the following conditions are
206019Shines@cs.fsu.edu// met: redistributions of source code must retain the above copyright
216019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer;
226019Shines@cs.fsu.edu// redistributions in binary form must reproduce the above copyright
236019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer in the
246019Shines@cs.fsu.edu// documentation and/or other materials provided with the distribution;
256019Shines@cs.fsu.edu// neither the name of the copyright holders nor the names of its
266019Shines@cs.fsu.edu// contributors may be used to endorse or promote products derived from
276019Shines@cs.fsu.edu// this software without specific prior written permission.
286019Shines@cs.fsu.edu//
296019Shines@cs.fsu.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306019Shines@cs.fsu.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316019Shines@cs.fsu.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326019Shines@cs.fsu.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336019Shines@cs.fsu.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
346019Shines@cs.fsu.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356019Shines@cs.fsu.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366019Shines@cs.fsu.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
376019Shines@cs.fsu.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386019Shines@cs.fsu.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396019Shines@cs.fsu.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406019Shines@cs.fsu.edu//
416019Shines@cs.fsu.edu// Authors: Stephen Hines
426019Shines@cs.fsu.edu
436019Shines@cs.fsu.edu////////////////////////////////////////////////////////////////////
446019Shines@cs.fsu.edu//
456019Shines@cs.fsu.edu// Floating Point operate instructions
466019Shines@cs.fsu.edu//
476019Shines@cs.fsu.edu
487639Sgblack@eecs.umich.eduoutput header {{
497639Sgblack@eecs.umich.edu
507639Sgblack@eecs.umich.edu    template<template <typename T> class Base>
517639Sgblack@eecs.umich.edu    StaticInstPtr
527639Sgblack@eecs.umich.edu    newNeonMemInst(const unsigned size,
537639Sgblack@eecs.umich.edu                   const ExtMachInst &machInst,
547639Sgblack@eecs.umich.edu                   const RegIndex dest, const RegIndex ra,
557639Sgblack@eecs.umich.edu                   const uint32_t imm, const unsigned extraMemFlags)
567639Sgblack@eecs.umich.edu    {
577639Sgblack@eecs.umich.edu        switch (size) {
587639Sgblack@eecs.umich.edu          case 0:
597639Sgblack@eecs.umich.edu            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
607639Sgblack@eecs.umich.edu          case 1:
617639Sgblack@eecs.umich.edu            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
627639Sgblack@eecs.umich.edu          case 2:
637639Sgblack@eecs.umich.edu            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
647639Sgblack@eecs.umich.edu          case 3:
657639Sgblack@eecs.umich.edu            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
667639Sgblack@eecs.umich.edu          default:
677639Sgblack@eecs.umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
687639Sgblack@eecs.umich.edu        }
697639Sgblack@eecs.umich.edu    }
707639Sgblack@eecs.umich.edu
717639Sgblack@eecs.umich.edu    template<template <typename T> class Base>
727639Sgblack@eecs.umich.edu    StaticInstPtr
737639Sgblack@eecs.umich.edu    newNeonMixInst(const unsigned size,
747639Sgblack@eecs.umich.edu                   const ExtMachInst &machInst,
757639Sgblack@eecs.umich.edu                   const RegIndex dest, const RegIndex op1,
767639Sgblack@eecs.umich.edu                   const uint32_t step)
777639Sgblack@eecs.umich.edu    {
787639Sgblack@eecs.umich.edu        switch (size) {
797639Sgblack@eecs.umich.edu          case 0:
807639Sgblack@eecs.umich.edu            return new Base<uint8_t>(machInst, dest, op1, step);
817639Sgblack@eecs.umich.edu          case 1:
827639Sgblack@eecs.umich.edu            return new Base<uint16_t>(machInst, dest, op1, step);
837639Sgblack@eecs.umich.edu          case 2:
847639Sgblack@eecs.umich.edu            return new Base<uint32_t>(machInst, dest, op1, step);
857639Sgblack@eecs.umich.edu          case 3:
867639Sgblack@eecs.umich.edu            return new Base<uint64_t>(machInst, dest, op1, step);
877639Sgblack@eecs.umich.edu          default:
887639Sgblack@eecs.umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
897639Sgblack@eecs.umich.edu        }
907639Sgblack@eecs.umich.edu    }
917639Sgblack@eecs.umich.edu
927639Sgblack@eecs.umich.edu}};
937639Sgblack@eecs.umich.edu
947356Sgblack@eecs.umich.edulet {{
957356Sgblack@eecs.umich.edu    header_output = '''
967356Sgblack@eecs.umich.edu    StaticInstPtr
977435Sgblack@eecs.umich.edu    decodeNeonMem(ExtMachInst machInst);
987435Sgblack@eecs.umich.edu
997435Sgblack@eecs.umich.edu    StaticInstPtr
1007435Sgblack@eecs.umich.edu    decodeNeonData(ExtMachInst machInst);
1017435Sgblack@eecs.umich.edu    '''
1027435Sgblack@eecs.umich.edu
1037435Sgblack@eecs.umich.edu    decoder_output = '''
1047435Sgblack@eecs.umich.edu    StaticInstPtr
1057435Sgblack@eecs.umich.edu    decodeNeonMem(ExtMachInst machInst)
1067435Sgblack@eecs.umich.edu    {
1077435Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 11, 8);
1087639Sgblack@eecs.umich.edu        const bool single = bits(machInst, 23);
1097639Sgblack@eecs.umich.edu        const bool singleAll = single && (bits(b, 3, 2) == 3);
1107639Sgblack@eecs.umich.edu        const bool load = bits(machInst, 21);
1117435Sgblack@eecs.umich.edu
1127639Sgblack@eecs.umich.edu        unsigned width = 0;
1137639Sgblack@eecs.umich.edu
1147639Sgblack@eecs.umich.edu        if (single) {
1157639Sgblack@eecs.umich.edu            width = bits(b, 1, 0) + 1;
1167639Sgblack@eecs.umich.edu        } else {
1177639Sgblack@eecs.umich.edu            switch (bits(b, 3, 1)) {
1187639Sgblack@eecs.umich.edu              case 0x0: width = 4;
1197639Sgblack@eecs.umich.edu                break;
1207639Sgblack@eecs.umich.edu              case 0x1: width = (b & 0x1) ? 2 : 1;
1217639Sgblack@eecs.umich.edu                break;
1227639Sgblack@eecs.umich.edu              case 0x2: width = 3;
1237639Sgblack@eecs.umich.edu                break;
1247639Sgblack@eecs.umich.edu              case 0x3: width = 1;
1257639Sgblack@eecs.umich.edu                break;
1267639Sgblack@eecs.umich.edu              case 0x4: width = 2;
1277639Sgblack@eecs.umich.edu                break;
1287639Sgblack@eecs.umich.edu              case 0x5:
1297639Sgblack@eecs.umich.edu                if ((b & 0x1) == 0) {
1307639Sgblack@eecs.umich.edu                    width = 1;
1317639Sgblack@eecs.umich.edu                    break;
1327639Sgblack@eecs.umich.edu                }
1337639Sgblack@eecs.umich.edu                // Fall through on purpose.
1347639Sgblack@eecs.umich.edu              default:
1357639Sgblack@eecs.umich.edu                return new Unknown(machInst);
1367639Sgblack@eecs.umich.edu            }
1377639Sgblack@eecs.umich.edu        }
1387639Sgblack@eecs.umich.edu        assert(width > 0 && width <= 4);
1397639Sgblack@eecs.umich.edu
1407639Sgblack@eecs.umich.edu        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
1417639Sgblack@eecs.umich.edu        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
1427639Sgblack@eecs.umich.edu        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
1437639Sgblack@eecs.umich.edu                                                 bits(machInst, 22) << 4);
1447639Sgblack@eecs.umich.edu        const uint32_t type = bits(machInst, 11, 8);
1457639Sgblack@eecs.umich.edu        uint32_t size = 0;
1468144SAli.Saidi@ARM.com        uint32_t align = TLB::MustBeOne;
1477639Sgblack@eecs.umich.edu        unsigned inc = 1;
1487639Sgblack@eecs.umich.edu        unsigned regs = 1;
1497639Sgblack@eecs.umich.edu        unsigned lane = 0;
1507639Sgblack@eecs.umich.edu        if (single) {
1517639Sgblack@eecs.umich.edu            if (singleAll) {
1527639Sgblack@eecs.umich.edu                size = bits(machInst, 7, 6);
1537639Sgblack@eecs.umich.edu                bool t = bits(machInst, 5);
1547639Sgblack@eecs.umich.edu                unsigned eBytes = (1 << size);
1557639Sgblack@eecs.umich.edu                align = (eBytes - 1) | TLB::AllowUnaligned;
1567639Sgblack@eecs.umich.edu                if (width == 1) {
1577639Sgblack@eecs.umich.edu                    regs = t ? 2 : 1;
1587639Sgblack@eecs.umich.edu                    inc = 1;
1597639Sgblack@eecs.umich.edu                } else {
1607639Sgblack@eecs.umich.edu                    regs = width;
1617639Sgblack@eecs.umich.edu                    inc = t ? 2 : 1;
1627639Sgblack@eecs.umich.edu                }
1637639Sgblack@eecs.umich.edu                switch (width) {
1647639Sgblack@eecs.umich.edu                  case 1:
1657639Sgblack@eecs.umich.edu                  case 2:
1667639Sgblack@eecs.umich.edu                    if (bits(machInst, 4))
1677639Sgblack@eecs.umich.edu                        align = width * eBytes - 1;
1687639Sgblack@eecs.umich.edu                    break;
1697639Sgblack@eecs.umich.edu                  case 3:
1707639Sgblack@eecs.umich.edu                    break;
1717639Sgblack@eecs.umich.edu                  case 4:
1727639Sgblack@eecs.umich.edu                    if (size == 3) {
1737639Sgblack@eecs.umich.edu                        if (bits(machInst, 4) == 0)
1747639Sgblack@eecs.umich.edu                            return new Unknown(machInst);
1757639Sgblack@eecs.umich.edu                        size = 2;
1767639Sgblack@eecs.umich.edu                        align = 0xf;
1777639Sgblack@eecs.umich.edu                    } else if (size == 2) {
1787639Sgblack@eecs.umich.edu                        if (bits(machInst, 4))
1797639Sgblack@eecs.umich.edu                            align = 7;
1807639Sgblack@eecs.umich.edu                    } else {
1817639Sgblack@eecs.umich.edu                        if (bits(machInst, 4))
1827639Sgblack@eecs.umich.edu                            align = 4 * eBytes - 1;
1837591SAli.Saidi@ARM.com                    }
1847639Sgblack@eecs.umich.edu                    break;
1857435Sgblack@eecs.umich.edu                }
1867435Sgblack@eecs.umich.edu            } else {
1877639Sgblack@eecs.umich.edu                size = bits(machInst, 11, 10);
1887639Sgblack@eecs.umich.edu                unsigned eBytes = (1 << size);
1897639Sgblack@eecs.umich.edu                align = (eBytes - 1) | TLB::AllowUnaligned;
1907639Sgblack@eecs.umich.edu                regs = width;
1917639Sgblack@eecs.umich.edu                unsigned indexAlign = bits(machInst, 7, 4);
1927639Sgblack@eecs.umich.edu                // If width is 1, inc is always 1. That's overridden later.
1937639Sgblack@eecs.umich.edu                switch (size) {
1947639Sgblack@eecs.umich.edu                  case 0:
1957639Sgblack@eecs.umich.edu                    inc = 1;
1967639Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3, 1);
1977639Sgblack@eecs.umich.edu                    break;
1987639Sgblack@eecs.umich.edu                  case 1:
1997639Sgblack@eecs.umich.edu                    inc = bits(indexAlign, 1) ? 2 : 1;
2007639Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3, 2);
2017639Sgblack@eecs.umich.edu                    break;
2027639Sgblack@eecs.umich.edu                  case 2:
2037639Sgblack@eecs.umich.edu                    inc = bits(indexAlign, 2) ? 2 : 1;
2047639Sgblack@eecs.umich.edu                    lane = bits(indexAlign, 3);
2057639Sgblack@eecs.umich.edu                    break;
2067639Sgblack@eecs.umich.edu                }
2077639Sgblack@eecs.umich.edu                // Override inc for width of 1.
2087639Sgblack@eecs.umich.edu                if (width == 1) {
2097639Sgblack@eecs.umich.edu                    inc = 1;
2107639Sgblack@eecs.umich.edu                }
2117639Sgblack@eecs.umich.edu                switch (width) {
2127639Sgblack@eecs.umich.edu                  case 1:
2137639Sgblack@eecs.umich.edu                    switch (size) {
2147639Sgblack@eecs.umich.edu                      case 0:
2157639Sgblack@eecs.umich.edu                        break;
2167639Sgblack@eecs.umich.edu                      case 1:
2177639Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2187639Sgblack@eecs.umich.edu                            align = 1;
2197639Sgblack@eecs.umich.edu                        break;
2207639Sgblack@eecs.umich.edu                      case 2:
2217639Sgblack@eecs.umich.edu                        if (bits(indexAlign, 1, 0))
2227639Sgblack@eecs.umich.edu                            align = 3;
2237591SAli.Saidi@ARM.com                        break;
2247591SAli.Saidi@ARM.com                    }
2257639Sgblack@eecs.umich.edu                    break;
2267639Sgblack@eecs.umich.edu                  case 2:
2277639Sgblack@eecs.umich.edu                    if (bits(indexAlign, 0))
2287639Sgblack@eecs.umich.edu                        align = (2 * eBytes) - 1;
2297639Sgblack@eecs.umich.edu                    break;
2307639Sgblack@eecs.umich.edu                  case 3:
2317639Sgblack@eecs.umich.edu                    break;
2327639Sgblack@eecs.umich.edu                  case 4:
2337639Sgblack@eecs.umich.edu                    switch (size) {
2347639Sgblack@eecs.umich.edu                      case 0:
2357639Sgblack@eecs.umich.edu                      case 1:
2367639Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2377639Sgblack@eecs.umich.edu                            align = (4 * eBytes) - 1;
2387639Sgblack@eecs.umich.edu                        break;
2397639Sgblack@eecs.umich.edu                      case 2:
2407639Sgblack@eecs.umich.edu                        if (bits(indexAlign, 0))
2417639Sgblack@eecs.umich.edu                            align = (4 << bits(indexAlign, 1, 0)) - 1;
2427639Sgblack@eecs.umich.edu                        break;
2437639Sgblack@eecs.umich.edu                    }
2447639Sgblack@eecs.umich.edu                    break;
2457435Sgblack@eecs.umich.edu                }
2467435Sgblack@eecs.umich.edu            }
2477639Sgblack@eecs.umich.edu            if (size == 0x3) {
2487639Sgblack@eecs.umich.edu                return new Unknown(machInst);
2497639Sgblack@eecs.umich.edu            }
2507639Sgblack@eecs.umich.edu        } else {
2517639Sgblack@eecs.umich.edu            size = bits(machInst, 7, 6);
2527639Sgblack@eecs.umich.edu            align = bits(machInst, 5, 4);
2537639Sgblack@eecs.umich.edu            if (align == 0) {
2547639Sgblack@eecs.umich.edu                // @align wasn't specified, so alignment can be turned off.
2557639Sgblack@eecs.umich.edu                align = ((1 << size) - 1) | TLB::AllowUnaligned;
2567639Sgblack@eecs.umich.edu            } else {
2577639Sgblack@eecs.umich.edu                align = ((4 << align) - 1);
2587639Sgblack@eecs.umich.edu            }
2597639Sgblack@eecs.umich.edu            switch (width) {
2607639Sgblack@eecs.umich.edu              case 1:
2617639Sgblack@eecs.umich.edu                switch (type) {
2627639Sgblack@eecs.umich.edu                  case 0x7: regs = 1;
2637639Sgblack@eecs.umich.edu                    break;
2647639Sgblack@eecs.umich.edu                  case 0xa: regs = 2;
2657639Sgblack@eecs.umich.edu                    break;
2667639Sgblack@eecs.umich.edu                  case 0x6: regs = 3;
2677639Sgblack@eecs.umich.edu                    break;
2687639Sgblack@eecs.umich.edu                  case 0x2: regs = 4;
2697639Sgblack@eecs.umich.edu                    break;
2707639Sgblack@eecs.umich.edu                  default:
2717639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2727639Sgblack@eecs.umich.edu                }
2737639Sgblack@eecs.umich.edu                break;
2747639Sgblack@eecs.umich.edu              case 2:
2757639Sgblack@eecs.umich.edu                // Regs doesn't behave exactly as it does in the manual
2767639Sgblack@eecs.umich.edu                // because they loop over regs registers twice and we break
2777639Sgblack@eecs.umich.edu                // it down in the macroop.
2787639Sgblack@eecs.umich.edu                switch (type) {
2797639Sgblack@eecs.umich.edu                  case 0x8: regs = 2; inc = 1;
2807639Sgblack@eecs.umich.edu                    break;
2817639Sgblack@eecs.umich.edu                  case 0x9: regs = 2; inc = 2;
2827639Sgblack@eecs.umich.edu                    break;
2837639Sgblack@eecs.umich.edu                  case 0x3: regs = 4; inc = 2;
2847639Sgblack@eecs.umich.edu                    break;
2857639Sgblack@eecs.umich.edu                  default:
2867639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2877639Sgblack@eecs.umich.edu                }
2887639Sgblack@eecs.umich.edu                break;
2897639Sgblack@eecs.umich.edu              case 3:
2907639Sgblack@eecs.umich.edu                regs = 3;
2917639Sgblack@eecs.umich.edu                switch (type) {
2927639Sgblack@eecs.umich.edu                  case 0x4: inc = 1;
2937639Sgblack@eecs.umich.edu                    break;
2947639Sgblack@eecs.umich.edu                  case 0x5: inc = 2;;
2957639Sgblack@eecs.umich.edu                    break;
2967639Sgblack@eecs.umich.edu                  default:
2977639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2987639Sgblack@eecs.umich.edu                }
2997639Sgblack@eecs.umich.edu                break;
3007639Sgblack@eecs.umich.edu              case 4:
3017639Sgblack@eecs.umich.edu                regs = 4;
3027639Sgblack@eecs.umich.edu                switch (type) {
3037639Sgblack@eecs.umich.edu                  case 0: inc = 1;
3047639Sgblack@eecs.umich.edu                    break;
3057639Sgblack@eecs.umich.edu                  case 1: inc = 2;
3067639Sgblack@eecs.umich.edu                    break;
3077639Sgblack@eecs.umich.edu                  default:
3087639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3097639Sgblack@eecs.umich.edu                }
3107639Sgblack@eecs.umich.edu                break;
3117639Sgblack@eecs.umich.edu            }
3127639Sgblack@eecs.umich.edu        }
3137639Sgblack@eecs.umich.edu
3147639Sgblack@eecs.umich.edu        if (load) {
3157639Sgblack@eecs.umich.edu            // Load instructions.
3167639Sgblack@eecs.umich.edu            if (single) {
3177639Sgblack@eecs.umich.edu                return new VldSingle(machInst, singleAll, width, rn, vd,
3187639Sgblack@eecs.umich.edu                                     regs, inc, size, align, rm, lane);
3197639Sgblack@eecs.umich.edu            } else {
3207639Sgblack@eecs.umich.edu                return new VldMult(machInst, width, rn, vd,
3217639Sgblack@eecs.umich.edu                                   regs, inc, size, align, rm);
3227639Sgblack@eecs.umich.edu            }
3237435Sgblack@eecs.umich.edu        } else {
3247435Sgblack@eecs.umich.edu            // Store instructions.
3257639Sgblack@eecs.umich.edu            if (single) {
3267639Sgblack@eecs.umich.edu                if (singleAll) {
3277639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3287591SAli.Saidi@ARM.com                } else {
3297639Sgblack@eecs.umich.edu                    return new VstSingle(machInst, false, width, rn, vd,
3307639Sgblack@eecs.umich.edu                                         regs, inc, size, align, rm, lane);
3317435Sgblack@eecs.umich.edu                }
3327435Sgblack@eecs.umich.edu            } else {
3337639Sgblack@eecs.umich.edu                return new VstMult(machInst, width, rn, vd,
3347639Sgblack@eecs.umich.edu                                   regs, inc, size, align, rm);
3357435Sgblack@eecs.umich.edu            }
3367435Sgblack@eecs.umich.edu        }
3377591SAli.Saidi@ARM.com        return new Unknown(machInst);
3387435Sgblack@eecs.umich.edu    }
3397435Sgblack@eecs.umich.edu    '''
3407435Sgblack@eecs.umich.edu
3417435Sgblack@eecs.umich.edu    decoder_output += '''
3427435Sgblack@eecs.umich.edu    static StaticInstPtr
3437435Sgblack@eecs.umich.edu    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
3447435Sgblack@eecs.umich.edu    {
3457435Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
3467435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
3477435Sgblack@eecs.umich.edu        const bool b = bits(machInst, 4);
3487435Sgblack@eecs.umich.edu        const uint32_t c = bits(machInst, 21, 20);
3497639Sgblack@eecs.umich.edu        const IntRegIndex vd =
3507639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
3517639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
3527639Sgblack@eecs.umich.edu        const IntRegIndex vn =
3537639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
3547639Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
3557639Sgblack@eecs.umich.edu        const IntRegIndex vm =
3567639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
3577639Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
3587639Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
3597639Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
3607639Sgblack@eecs.umich.edu        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
3617639Sgblack@eecs.umich.edu            return new Unknown(machInst);
3627435Sgblack@eecs.umich.edu        switch (a) {
3637435Sgblack@eecs.umich.edu          case 0x0:
3647435Sgblack@eecs.umich.edu            if (b) {
3657639Sgblack@eecs.umich.edu                if (u) {
3667639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3677639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
3687435Sgblack@eecs.umich.edu                } else {
3697639Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
3707639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
3717435Sgblack@eecs.umich.edu                }
3727435Sgblack@eecs.umich.edu            } else {
3737639Sgblack@eecs.umich.edu                if (size == 3)
3747639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3757639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
3767639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
3777435Sgblack@eecs.umich.edu            }
3787435Sgblack@eecs.umich.edu          case 0x1:
3797435Sgblack@eecs.umich.edu            if (!b) {
3807639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
3817639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
3827435Sgblack@eecs.umich.edu            } else {
3837435Sgblack@eecs.umich.edu                if (u) {
3847435Sgblack@eecs.umich.edu                    switch (c) {
3857435Sgblack@eecs.umich.edu                      case 0:
3867639Sgblack@eecs.umich.edu                        if (q) {
3877639Sgblack@eecs.umich.edu                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
3887639Sgblack@eecs.umich.edu                        } else {
3897639Sgblack@eecs.umich.edu                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
3907639Sgblack@eecs.umich.edu                        }
3917435Sgblack@eecs.umich.edu                      case 1:
3927639Sgblack@eecs.umich.edu                        if (q) {
3937639Sgblack@eecs.umich.edu                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3947639Sgblack@eecs.umich.edu                        } else {
3957639Sgblack@eecs.umich.edu                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
3967639Sgblack@eecs.umich.edu                        }
3977435Sgblack@eecs.umich.edu                      case 2:
3987639Sgblack@eecs.umich.edu                        if (q) {
3997639Sgblack@eecs.umich.edu                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
4007639Sgblack@eecs.umich.edu                        } else {
4017639Sgblack@eecs.umich.edu                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
4027639Sgblack@eecs.umich.edu                        }
4037435Sgblack@eecs.umich.edu                      case 3:
4047639Sgblack@eecs.umich.edu                        if (q) {
4057639Sgblack@eecs.umich.edu                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
4067639Sgblack@eecs.umich.edu                        } else {
4077639Sgblack@eecs.umich.edu                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
4087639Sgblack@eecs.umich.edu                        }
4097435Sgblack@eecs.umich.edu                    }
4107435Sgblack@eecs.umich.edu                } else {
4117435Sgblack@eecs.umich.edu                    switch (c) {
4127435Sgblack@eecs.umich.edu                      case 0:
4137639Sgblack@eecs.umich.edu                        if (q) {
4147639Sgblack@eecs.umich.edu                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
4157639Sgblack@eecs.umich.edu                        } else {
4167639Sgblack@eecs.umich.edu                            return new VandD<uint64_t>(machInst, vd, vn, vm);
4177639Sgblack@eecs.umich.edu                        }
4187435Sgblack@eecs.umich.edu                      case 1:
4197639Sgblack@eecs.umich.edu                        if (q) {
4207639Sgblack@eecs.umich.edu                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
4217639Sgblack@eecs.umich.edu                        } else {
4227639Sgblack@eecs.umich.edu                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
4237639Sgblack@eecs.umich.edu                        }
4247435Sgblack@eecs.umich.edu                      case 2:
4257639Sgblack@eecs.umich.edu                        if (vn == vm) {
4267639Sgblack@eecs.umich.edu                            if (q) {
4277639Sgblack@eecs.umich.edu                                return new VmovQ<uint64_t>(
4287639Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4297435Sgblack@eecs.umich.edu                            } else {
4307639Sgblack@eecs.umich.edu                                return new VmovD<uint64_t>(
4317639Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4327639Sgblack@eecs.umich.edu                            }
4337639Sgblack@eecs.umich.edu                        } else {
4347639Sgblack@eecs.umich.edu                            if (q) {
4357639Sgblack@eecs.umich.edu                                return new VorrQ<uint64_t>(
4367639Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4377639Sgblack@eecs.umich.edu                            } else {
4387639Sgblack@eecs.umich.edu                                return new VorrD<uint64_t>(
4397639Sgblack@eecs.umich.edu                                        machInst, vd, vn, vm);
4407435Sgblack@eecs.umich.edu                            }
4417435Sgblack@eecs.umich.edu                        }
4427435Sgblack@eecs.umich.edu                      case 3:
4437639Sgblack@eecs.umich.edu                        if (q) {
4447639Sgblack@eecs.umich.edu                            return new VornQ<uint64_t>(
4457639Sgblack@eecs.umich.edu                                    machInst, vd, vn, vm);
4467639Sgblack@eecs.umich.edu                        } else {
4477639Sgblack@eecs.umich.edu                            return new VornD<uint64_t>(
4487639Sgblack@eecs.umich.edu                                    machInst, vd, vn, vm);
4497639Sgblack@eecs.umich.edu                        }
4507435Sgblack@eecs.umich.edu                    }
4517435Sgblack@eecs.umich.edu                }
4527435Sgblack@eecs.umich.edu            }
4537435Sgblack@eecs.umich.edu          case 0x2:
4547435Sgblack@eecs.umich.edu            if (b) {
4557639Sgblack@eecs.umich.edu                if (u) {
4567639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
4577639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4587639Sgblack@eecs.umich.edu                } else {
4597639Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
4607639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4617639Sgblack@eecs.umich.edu                }
4627435Sgblack@eecs.umich.edu            } else {
4637639Sgblack@eecs.umich.edu                if (size == 3)
4647639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
4657639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
4667639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4677435Sgblack@eecs.umich.edu            }
4687435Sgblack@eecs.umich.edu          case 0x3:
4697435Sgblack@eecs.umich.edu            if (b) {
4707639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
4717639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4727435Sgblack@eecs.umich.edu            } else {
4737639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
4747639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4757435Sgblack@eecs.umich.edu            }
4767435Sgblack@eecs.umich.edu          case 0x4:
4777435Sgblack@eecs.umich.edu            if (b) {
4787639Sgblack@eecs.umich.edu                if (u) {
4797639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
4807639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4817639Sgblack@eecs.umich.edu                } else {
4827639Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
4837639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4847639Sgblack@eecs.umich.edu                }
4857435Sgblack@eecs.umich.edu            } else {
4867639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VshlD, VshlQ>(
4877639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
4887435Sgblack@eecs.umich.edu            }
4897435Sgblack@eecs.umich.edu          case 0x5:
4907435Sgblack@eecs.umich.edu            if (b) {
4917639Sgblack@eecs.umich.edu                if (u) {
4927639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
4937639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4947639Sgblack@eecs.umich.edu                } else {
4957639Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
4967639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4977639Sgblack@eecs.umich.edu                }
4987435Sgblack@eecs.umich.edu            } else {
4997639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
5007639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
5017435Sgblack@eecs.umich.edu            }
5027435Sgblack@eecs.umich.edu          case 0x6:
5037435Sgblack@eecs.umich.edu            if (b) {
5047639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VminD, VminQ>(
5057639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5067435Sgblack@eecs.umich.edu            } else {
5077639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
5087639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5097435Sgblack@eecs.umich.edu            }
5107435Sgblack@eecs.umich.edu          case 0x7:
5117435Sgblack@eecs.umich.edu            if (b) {
5127639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabaD, VabaQ>(
5137639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5147435Sgblack@eecs.umich.edu            } else {
5157435Sgblack@eecs.umich.edu                if (bits(machInst, 23) == 1) {
5167639Sgblack@eecs.umich.edu                    if (q) {
5177435Sgblack@eecs.umich.edu                        return new Unknown(machInst);
5187435Sgblack@eecs.umich.edu                    } else {
5197639Sgblack@eecs.umich.edu                        return decodeNeonUSThreeUSReg<Vabdl>(
5207639Sgblack@eecs.umich.edu                                u, size, machInst, vd, vn, vm);
5217435Sgblack@eecs.umich.edu                    }
5227435Sgblack@eecs.umich.edu                } else {
5237639Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
5247639Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5257435Sgblack@eecs.umich.edu                }
5267435Sgblack@eecs.umich.edu            }
5277435Sgblack@eecs.umich.edu          case 0x8:
5287435Sgblack@eecs.umich.edu            if (b) {
5297435Sgblack@eecs.umich.edu                if (u) {
5307639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VceqD, VceqQ>(
5317639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5327435Sgblack@eecs.umich.edu                } else {
5337639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VtstD, VtstQ>(
5347639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5357435Sgblack@eecs.umich.edu                }
5367435Sgblack@eecs.umich.edu            } else {
5377435Sgblack@eecs.umich.edu                if (u) {
5387639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5397639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5407435Sgblack@eecs.umich.edu                } else {
5417639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
5427639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5437435Sgblack@eecs.umich.edu                }
5447435Sgblack@eecs.umich.edu            }
5457435Sgblack@eecs.umich.edu          case 0x9:
5467435Sgblack@eecs.umich.edu            if (b) {
5477435Sgblack@eecs.umich.edu                if (u) {
5487639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5497639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5507435Sgblack@eecs.umich.edu                } else {
5517639Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
5527639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5537435Sgblack@eecs.umich.edu                }
5547435Sgblack@eecs.umich.edu            } else {
5557435Sgblack@eecs.umich.edu                if (u) {
5567639Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
5577639Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5587435Sgblack@eecs.umich.edu                } else {
5597639Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
5607639Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5617435Sgblack@eecs.umich.edu                }
5627435Sgblack@eecs.umich.edu            }
5637435Sgblack@eecs.umich.edu          case 0xa:
5647435Sgblack@eecs.umich.edu            if (b) {
5657639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VpminD, VpminQ>(
5667639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5677435Sgblack@eecs.umich.edu            } else {
5687639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
5697639Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5707435Sgblack@eecs.umich.edu            }
5717435Sgblack@eecs.umich.edu          case 0xb:
5727435Sgblack@eecs.umich.edu            if (b) {
5737435Sgblack@eecs.umich.edu                if (u) {
5747435Sgblack@eecs.umich.edu                    return new Unknown(machInst);
5757435Sgblack@eecs.umich.edu                } else {
5767639Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
5777639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5787435Sgblack@eecs.umich.edu                }
5797435Sgblack@eecs.umich.edu            } else {
5807435Sgblack@eecs.umich.edu                if (u) {
5817639Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
5827639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5837435Sgblack@eecs.umich.edu                } else {
5847639Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
5857639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5867435Sgblack@eecs.umich.edu                }
5877435Sgblack@eecs.umich.edu            }
5887435Sgblack@eecs.umich.edu          case 0xc:
5897435Sgblack@eecs.umich.edu            return new Unknown(machInst);
5907435Sgblack@eecs.umich.edu          case 0xd:
5917435Sgblack@eecs.umich.edu            if (b) {
5927435Sgblack@eecs.umich.edu                if (u) {
5937435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
5947639Sgblack@eecs.umich.edu                        if (q) {
5957639Sgblack@eecs.umich.edu                            return new NVmulQFp<float>(machInst, vd, vn, vm);
5967639Sgblack@eecs.umich.edu                        } else {
5977639Sgblack@eecs.umich.edu                            return new NVmulDFp<float>(machInst, vd, vn, vm);
5987639Sgblack@eecs.umich.edu                        }
5997435Sgblack@eecs.umich.edu                    } else {
6007435Sgblack@eecs.umich.edu                        return new Unknown(machInst);
6017435Sgblack@eecs.umich.edu                    }
6027435Sgblack@eecs.umich.edu                } else {
6037435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6047639Sgblack@eecs.umich.edu                        if (q) {
6057639Sgblack@eecs.umich.edu                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6067639Sgblack@eecs.umich.edu                        } else {
6077639Sgblack@eecs.umich.edu                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
6087639Sgblack@eecs.umich.edu                        }
6097435Sgblack@eecs.umich.edu                    } else {
6107639Sgblack@eecs.umich.edu                        if (q) {
6117639Sgblack@eecs.umich.edu                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
6127639Sgblack@eecs.umich.edu                        } else {
6137639Sgblack@eecs.umich.edu                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
6147639Sgblack@eecs.umich.edu                        }
6157435Sgblack@eecs.umich.edu                    }
6167435Sgblack@eecs.umich.edu                }
6177435Sgblack@eecs.umich.edu            } else {
6187435Sgblack@eecs.umich.edu                if (u) {
6197435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6207639Sgblack@eecs.umich.edu                        if (q) {
6217639Sgblack@eecs.umich.edu                            return new VpaddQFp<float>(machInst, vd, vn, vm);
6227639Sgblack@eecs.umich.edu                        } else {
6237639Sgblack@eecs.umich.edu                            return new VpaddDFp<float>(machInst, vd, vn, vm);
6247639Sgblack@eecs.umich.edu                        }
6257435Sgblack@eecs.umich.edu                    } else {
6267639Sgblack@eecs.umich.edu                        if (q) {
6277639Sgblack@eecs.umich.edu                            return new VabdQFp<float>(machInst, vd, vn, vm);
6287639Sgblack@eecs.umich.edu                        } else {
6297639Sgblack@eecs.umich.edu                            return new VabdDFp<float>(machInst, vd, vn, vm);
6307639Sgblack@eecs.umich.edu                        }
6317435Sgblack@eecs.umich.edu                    }
6327435Sgblack@eecs.umich.edu                } else {
6337435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6347639Sgblack@eecs.umich.edu                        if (q) {
6357639Sgblack@eecs.umich.edu                            return new VaddQFp<float>(machInst, vd, vn, vm);
6367639Sgblack@eecs.umich.edu                        } else {
6377639Sgblack@eecs.umich.edu                            return new VaddDFp<float>(machInst, vd, vn, vm);
6387639Sgblack@eecs.umich.edu                        }
6397435Sgblack@eecs.umich.edu                    } else {
6407639Sgblack@eecs.umich.edu                        if (q) {
6417639Sgblack@eecs.umich.edu                            return new VsubQFp<float>(machInst, vd, vn, vm);
6427639Sgblack@eecs.umich.edu                        } else {
6437639Sgblack@eecs.umich.edu                            return new VsubDFp<float>(machInst, vd, vn, vm);
6447639Sgblack@eecs.umich.edu                        }
6457435Sgblack@eecs.umich.edu                    }
6467435Sgblack@eecs.umich.edu                }
6477435Sgblack@eecs.umich.edu            }
6487435Sgblack@eecs.umich.edu          case 0xe:
6497435Sgblack@eecs.umich.edu            if (b) {
6507435Sgblack@eecs.umich.edu                if (u) {
6517435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6527639Sgblack@eecs.umich.edu                        if (q) {
6537639Sgblack@eecs.umich.edu                            return new VacgeQFp<float>(machInst, vd, vn, vm);
6547639Sgblack@eecs.umich.edu                        } else {
6557639Sgblack@eecs.umich.edu                            return new VacgeDFp<float>(machInst, vd, vn, vm);
6567639Sgblack@eecs.umich.edu                        }
6577435Sgblack@eecs.umich.edu                    } else {
6587639Sgblack@eecs.umich.edu                        if (q) {
6597639Sgblack@eecs.umich.edu                            return new VacgtQFp<float>(machInst, vd, vn, vm);
6607639Sgblack@eecs.umich.edu                        } else {
6617639Sgblack@eecs.umich.edu                            return new VacgtDFp<float>(machInst, vd, vn, vm);
6627639Sgblack@eecs.umich.edu                        }
6637435Sgblack@eecs.umich.edu                    }
6647435Sgblack@eecs.umich.edu                } else {
6657435Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6667435Sgblack@eecs.umich.edu                }
6677435Sgblack@eecs.umich.edu            } else {
6687435Sgblack@eecs.umich.edu                if (u) {
6697435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6707639Sgblack@eecs.umich.edu                        if (q) {
6717639Sgblack@eecs.umich.edu                            return new VcgeQFp<float>(machInst, vd, vn, vm);
6727639Sgblack@eecs.umich.edu                        } else {
6737639Sgblack@eecs.umich.edu                            return new VcgeDFp<float>(machInst, vd, vn, vm);
6747639Sgblack@eecs.umich.edu                        }
6757435Sgblack@eecs.umich.edu                    } else {
6767639Sgblack@eecs.umich.edu                        if (q) {
6777639Sgblack@eecs.umich.edu                            return new VcgtQFp<float>(machInst, vd, vn, vm);
6787639Sgblack@eecs.umich.edu                        } else {
6797639Sgblack@eecs.umich.edu                            return new VcgtDFp<float>(machInst, vd, vn, vm);
6807639Sgblack@eecs.umich.edu                        }
6817435Sgblack@eecs.umich.edu                    }
6827435Sgblack@eecs.umich.edu                } else {
6837435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
6847639Sgblack@eecs.umich.edu                        if (q) {
6857639Sgblack@eecs.umich.edu                            return new VceqQFp<float>(machInst, vd, vn, vm);
6867639Sgblack@eecs.umich.edu                        } else {
6877639Sgblack@eecs.umich.edu                            return new VceqDFp<float>(machInst, vd, vn, vm);
6887639Sgblack@eecs.umich.edu                        }
6897435Sgblack@eecs.umich.edu                    } else {
6907435Sgblack@eecs.umich.edu                        return new Unknown(machInst);
6917435Sgblack@eecs.umich.edu                    }
6927435Sgblack@eecs.umich.edu                }
6937435Sgblack@eecs.umich.edu            }
6947435Sgblack@eecs.umich.edu          case 0xf:
6957435Sgblack@eecs.umich.edu            if (b) {
6967435Sgblack@eecs.umich.edu                if (u) {
6977435Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6987435Sgblack@eecs.umich.edu                } else {
6997435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7007639Sgblack@eecs.umich.edu                        if (q) {
7017639Sgblack@eecs.umich.edu                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
7027639Sgblack@eecs.umich.edu                        } else {
7037639Sgblack@eecs.umich.edu                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
7047639Sgblack@eecs.umich.edu                        }
7057435Sgblack@eecs.umich.edu                    } else {
7067639Sgblack@eecs.umich.edu                        if (q) {
7077639Sgblack@eecs.umich.edu                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
7087639Sgblack@eecs.umich.edu                        } else {
7097639Sgblack@eecs.umich.edu                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
7107639Sgblack@eecs.umich.edu                        }
7117435Sgblack@eecs.umich.edu                    }
7127435Sgblack@eecs.umich.edu                }
7137435Sgblack@eecs.umich.edu            } else {
7147435Sgblack@eecs.umich.edu                if (u) {
7157435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7167639Sgblack@eecs.umich.edu                        if (q) {
7177639Sgblack@eecs.umich.edu                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
7187639Sgblack@eecs.umich.edu                        } else {
7197639Sgblack@eecs.umich.edu                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
7207639Sgblack@eecs.umich.edu                        }
7217435Sgblack@eecs.umich.edu                    } else {
7227639Sgblack@eecs.umich.edu                        if (q) {
7237639Sgblack@eecs.umich.edu                            return new VpminQFp<float>(machInst, vd, vn, vm);
7247639Sgblack@eecs.umich.edu                        } else {
7257639Sgblack@eecs.umich.edu                            return new VpminDFp<float>(machInst, vd, vn, vm);
7267639Sgblack@eecs.umich.edu                        }
7277435Sgblack@eecs.umich.edu                    }
7287435Sgblack@eecs.umich.edu                } else {
7297435Sgblack@eecs.umich.edu                    if (bits(c, 1) == 0) {
7307639Sgblack@eecs.umich.edu                        if (q) {
7317639Sgblack@eecs.umich.edu                            return new VmaxQFp<float>(machInst, vd, vn, vm);
7327639Sgblack@eecs.umich.edu                        } else {
7337639Sgblack@eecs.umich.edu                            return new VmaxDFp<float>(machInst, vd, vn, vm);
7347639Sgblack@eecs.umich.edu                        }
7357435Sgblack@eecs.umich.edu                    } else {
7367639Sgblack@eecs.umich.edu                        if (q) {
7377639Sgblack@eecs.umich.edu                            return new VminQFp<float>(machInst, vd, vn, vm);
7387639Sgblack@eecs.umich.edu                        } else {
7397639Sgblack@eecs.umich.edu                            return new VminDFp<float>(machInst, vd, vn, vm);
7407639Sgblack@eecs.umich.edu                        }
7417435Sgblack@eecs.umich.edu                    }
7427435Sgblack@eecs.umich.edu                }
7437435Sgblack@eecs.umich.edu            }
7447435Sgblack@eecs.umich.edu        }
7457435Sgblack@eecs.umich.edu        return new Unknown(machInst);
7467435Sgblack@eecs.umich.edu    }
7477435Sgblack@eecs.umich.edu
7487435Sgblack@eecs.umich.edu    static StaticInstPtr
7497435Sgblack@eecs.umich.edu    decodeNeonOneRegModImm(ExtMachInst machInst)
7507435Sgblack@eecs.umich.edu    {
7517639Sgblack@eecs.umich.edu        const IntRegIndex vd =
7527639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
7537639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
7547639Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
7557435Sgblack@eecs.umich.edu        const bool op = bits(machInst, 5);
7567639Sgblack@eecs.umich.edu        const uint8_t cmode = bits(machInst, 11, 8);
7577639Sgblack@eecs.umich.edu        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
7587639Sgblack@eecs.umich.edu                                      bits(machInst, 24)) << 7) |
7597639Sgblack@eecs.umich.edu                            (bits(machInst, 18, 16) << 4) |
7607639Sgblack@eecs.umich.edu                            (bits(machInst, 3, 0) << 0);
7617853SMatt.Horsnell@ARM.com
7627853SMatt.Horsnell@ARM.com        // Check for invalid immediate encodings and return an unknown op
7637853SMatt.Horsnell@ARM.com        // if it happens
7647853SMatt.Horsnell@ARM.com        bool immValid = true;
7657853SMatt.Horsnell@ARM.com        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
7667853SMatt.Horsnell@ARM.com        if (!immValid) {
7677853SMatt.Horsnell@ARM.com            return new Unknown(machInst);
7687853SMatt.Horsnell@ARM.com        }
7697853SMatt.Horsnell@ARM.com
7707435Sgblack@eecs.umich.edu        if (op) {
7717435Sgblack@eecs.umich.edu            if (bits(cmode, 3) == 0) {
7727435Sgblack@eecs.umich.edu                if (bits(cmode, 0) == 0) {
7737639Sgblack@eecs.umich.edu                    if (q)
7747639Sgblack@eecs.umich.edu                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7757639Sgblack@eecs.umich.edu                    else
7767639Sgblack@eecs.umich.edu                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7777435Sgblack@eecs.umich.edu                } else {
7787639Sgblack@eecs.umich.edu                    if (q)
7797639Sgblack@eecs.umich.edu                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
7807639Sgblack@eecs.umich.edu                    else
7817639Sgblack@eecs.umich.edu                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
7827435Sgblack@eecs.umich.edu                }
7837435Sgblack@eecs.umich.edu            } else {
7847435Sgblack@eecs.umich.edu                if (bits(cmode, 2) == 1) {
7857639Sgblack@eecs.umich.edu                    switch (bits(cmode, 1, 0)) {
7867639Sgblack@eecs.umich.edu                      case 0:
7877639Sgblack@eecs.umich.edu                      case 1:
7887639Sgblack@eecs.umich.edu                        if (q)
7897639Sgblack@eecs.umich.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7907639Sgblack@eecs.umich.edu                        else
7917639Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7927639Sgblack@eecs.umich.edu                      case 2:
7937639Sgblack@eecs.umich.edu                        if (q)
7947639Sgblack@eecs.umich.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
7957639Sgblack@eecs.umich.edu                        else
7967639Sgblack@eecs.umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
7977639Sgblack@eecs.umich.edu                      case 3:
7987639Sgblack@eecs.umich.edu                        if (q)
7997639Sgblack@eecs.umich.edu                            return new Unknown(machInst);
8007639Sgblack@eecs.umich.edu                        else
8017639Sgblack@eecs.umich.edu                            return new Unknown(machInst);
8027639Sgblack@eecs.umich.edu                    }
8037435Sgblack@eecs.umich.edu                } else {
8047435Sgblack@eecs.umich.edu                    if (bits(cmode, 0) == 0) {
8057639Sgblack@eecs.umich.edu                        if (q)
8067639Sgblack@eecs.umich.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
8077639Sgblack@eecs.umich.edu                        else
8087639Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8097435Sgblack@eecs.umich.edu                    } else {
8107639Sgblack@eecs.umich.edu                        if (q)
8117639Sgblack@eecs.umich.edu                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8127639Sgblack@eecs.umich.edu                        else
8137639Sgblack@eecs.umich.edu                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8147435Sgblack@eecs.umich.edu                    }
8157435Sgblack@eecs.umich.edu                }
8167435Sgblack@eecs.umich.edu            }
8177435Sgblack@eecs.umich.edu        } else {
8187435Sgblack@eecs.umich.edu            if (bits(cmode, 3) == 0) {
8197435Sgblack@eecs.umich.edu                if (bits(cmode, 0) == 0) {
8207639Sgblack@eecs.umich.edu                    if (q)
8217639Sgblack@eecs.umich.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8227639Sgblack@eecs.umich.edu                    else
8237639Sgblack@eecs.umich.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8247435Sgblack@eecs.umich.edu                } else {
8257639Sgblack@eecs.umich.edu                    if (q)
8267639Sgblack@eecs.umich.edu                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8277639Sgblack@eecs.umich.edu                    else
8287639Sgblack@eecs.umich.edu                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8297435Sgblack@eecs.umich.edu                }
8307435Sgblack@eecs.umich.edu            } else {
8317435Sgblack@eecs.umich.edu                if (bits(cmode, 2) == 1) {
8327639Sgblack@eecs.umich.edu                    if (q)
8337639Sgblack@eecs.umich.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8347639Sgblack@eecs.umich.edu                    else
8357639Sgblack@eecs.umich.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8367435Sgblack@eecs.umich.edu                } else {
8377435Sgblack@eecs.umich.edu                    if (bits(cmode, 0) == 0) {
8387639Sgblack@eecs.umich.edu                        if (q)
8397639Sgblack@eecs.umich.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8407639Sgblack@eecs.umich.edu                        else
8417639Sgblack@eecs.umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8427435Sgblack@eecs.umich.edu                    } else {
8437639Sgblack@eecs.umich.edu                        if (q)
8447639Sgblack@eecs.umich.edu                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8457639Sgblack@eecs.umich.edu                        else
8467639Sgblack@eecs.umich.edu                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
8477435Sgblack@eecs.umich.edu                    }
8487435Sgblack@eecs.umich.edu                }
8497435Sgblack@eecs.umich.edu            }
8507435Sgblack@eecs.umich.edu        }
8517435Sgblack@eecs.umich.edu        return new Unknown(machInst);
8527435Sgblack@eecs.umich.edu    }
8537435Sgblack@eecs.umich.edu
8547435Sgblack@eecs.umich.edu    static StaticInstPtr
8557435Sgblack@eecs.umich.edu    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8567435Sgblack@eecs.umich.edu    {
8577435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
8587435Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
8597435Sgblack@eecs.umich.edu        const bool b = bits(machInst, 6);
8607435Sgblack@eecs.umich.edu        const bool l = bits(machInst, 7);
8617639Sgblack@eecs.umich.edu        const IntRegIndex vd =
8627639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
8637639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
8647639Sgblack@eecs.umich.edu        const IntRegIndex vm =
8657639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
8667639Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
8677639Sgblack@eecs.umich.edu        unsigned imm6 = bits(machInst, 21, 16);
8687639Sgblack@eecs.umich.edu        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
8697639Sgblack@eecs.umich.edu        unsigned size = 3;
8707639Sgblack@eecs.umich.edu        unsigned lShiftAmt = 0;
8717639Sgblack@eecs.umich.edu        unsigned bitSel;
8727639Sgblack@eecs.umich.edu        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8737639Sgblack@eecs.umich.edu            if (bitSel & imm)
8747639Sgblack@eecs.umich.edu                break;
8757639Sgblack@eecs.umich.edu            else if (!size)
8767639Sgblack@eecs.umich.edu                return new Unknown(machInst);
8777639Sgblack@eecs.umich.edu            size--;
8787639Sgblack@eecs.umich.edu        }
8797639Sgblack@eecs.umich.edu        lShiftAmt = imm6 & ~bitSel;
8807639Sgblack@eecs.umich.edu        unsigned rShiftAmt = 0;
8817639Sgblack@eecs.umich.edu        if (a != 0xe && a != 0xf) {
8827639Sgblack@eecs.umich.edu            if (size > 2)
8837639Sgblack@eecs.umich.edu                rShiftAmt = 64 - imm6;
8847639Sgblack@eecs.umich.edu            else
8857639Sgblack@eecs.umich.edu                rShiftAmt = 2 * (8 << size) - imm6;
8867639Sgblack@eecs.umich.edu        }
8877435Sgblack@eecs.umich.edu
8887435Sgblack@eecs.umich.edu        switch (a) {
8897435Sgblack@eecs.umich.edu          case 0x0:
8907639Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
8917639Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8927435Sgblack@eecs.umich.edu          case 0x1:
8937639Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
8947639Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8957435Sgblack@eecs.umich.edu          case 0x2:
8967639Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
8977639Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8987435Sgblack@eecs.umich.edu          case 0x3:
8997639Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
9007639Sgblack@eecs.umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9017435Sgblack@eecs.umich.edu          case 0x4:
9027435Sgblack@eecs.umich.edu            if (u) {
9037639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
9047639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9057435Sgblack@eecs.umich.edu            } else {
9067435Sgblack@eecs.umich.edu                return new Unknown(machInst);
9077435Sgblack@eecs.umich.edu            }
9087435Sgblack@eecs.umich.edu          case 0x5:
9097435Sgblack@eecs.umich.edu            if (u) {
9107639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9117639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9127435Sgblack@eecs.umich.edu            } else {
9137639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9147639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9157435Sgblack@eecs.umich.edu            }
9167435Sgblack@eecs.umich.edu          case 0x6:
9177435Sgblack@eecs.umich.edu          case 0x7:
9187639Sgblack@eecs.umich.edu            if (u) {
9197639Sgblack@eecs.umich.edu                if (a == 0x6) {
9207639Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9217639Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9227639Sgblack@eecs.umich.edu                } else {
9237639Sgblack@eecs.umich.edu                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
9247639Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9257639Sgblack@eecs.umich.edu                }
9267639Sgblack@eecs.umich.edu            } else {
9277639Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9287639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9297639Sgblack@eecs.umich.edu            }
9307435Sgblack@eecs.umich.edu          case 0x8:
9317435Sgblack@eecs.umich.edu            if (l) {
9327435Sgblack@eecs.umich.edu                return new Unknown(machInst);
9337435Sgblack@eecs.umich.edu            } else if (u) {
9347639Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9357639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9367435Sgblack@eecs.umich.edu            } else {
9377639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
9387639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9397435Sgblack@eecs.umich.edu            }
9407435Sgblack@eecs.umich.edu          case 0x9:
9417435Sgblack@eecs.umich.edu            if (l) {
9427435Sgblack@eecs.umich.edu                return new Unknown(machInst);
9437639Sgblack@eecs.umich.edu            } else if (u) {
9447639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
9457639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9467435Sgblack@eecs.umich.edu            } else {
9477639Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
9487639Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9497435Sgblack@eecs.umich.edu            }
9507435Sgblack@eecs.umich.edu          case 0xa:
9517435Sgblack@eecs.umich.edu            if (l || b) {
9527435Sgblack@eecs.umich.edu                return new Unknown(machInst);
9537435Sgblack@eecs.umich.edu            } else {
9547639Sgblack@eecs.umich.edu                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9557639Sgblack@eecs.umich.edu                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9567435Sgblack@eecs.umich.edu            }
9577435Sgblack@eecs.umich.edu          case 0xe:
9587639Sgblack@eecs.umich.edu            if (l) {
9597639Sgblack@eecs.umich.edu                return new Unknown(machInst);
9607639Sgblack@eecs.umich.edu            } else {
9617639Sgblack@eecs.umich.edu                if (bits(imm6, 5) == 0)
9627639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
9637639Sgblack@eecs.umich.edu                if (u) {
9647639Sgblack@eecs.umich.edu                    if (b) {
9657639Sgblack@eecs.umich.edu                        return new NVcvtu2fpQ<float>(
9667639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9677639Sgblack@eecs.umich.edu                    } else {
9687639Sgblack@eecs.umich.edu                        return new NVcvtu2fpD<float>(
9697639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9707639Sgblack@eecs.umich.edu                    }
9717639Sgblack@eecs.umich.edu                } else {
9727639Sgblack@eecs.umich.edu                    if (b) {
9737639Sgblack@eecs.umich.edu                        return new NVcvts2fpQ<float>(
9747639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9757639Sgblack@eecs.umich.edu                    } else {
9767639Sgblack@eecs.umich.edu                        return new NVcvts2fpD<float>(
9777639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9787639Sgblack@eecs.umich.edu                    }
9797639Sgblack@eecs.umich.edu                }
9807639Sgblack@eecs.umich.edu            }
9817435Sgblack@eecs.umich.edu          case 0xf:
9827435Sgblack@eecs.umich.edu            if (l) {
9837435Sgblack@eecs.umich.edu                return new Unknown(machInst);
9847639Sgblack@eecs.umich.edu            } else {
9857639Sgblack@eecs.umich.edu                if (bits(imm6, 5) == 0)
9867639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
9877639Sgblack@eecs.umich.edu                if (u) {
9887639Sgblack@eecs.umich.edu                    if (b) {
9897639Sgblack@eecs.umich.edu                        return new NVcvt2ufxQ<float>(
9907639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9917639Sgblack@eecs.umich.edu                    } else {
9927639Sgblack@eecs.umich.edu                        return new NVcvt2ufxD<float>(
9937639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9947639Sgblack@eecs.umich.edu                    }
9957639Sgblack@eecs.umich.edu                } else {
9967639Sgblack@eecs.umich.edu                    if (b) {
9977639Sgblack@eecs.umich.edu                        return new NVcvt2sfxQ<float>(
9987639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9997639Sgblack@eecs.umich.edu                    } else {
10007639Sgblack@eecs.umich.edu                        return new NVcvt2sfxD<float>(
10017639Sgblack@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
10027639Sgblack@eecs.umich.edu                    }
10037639Sgblack@eecs.umich.edu                }
10047435Sgblack@eecs.umich.edu            }
10057435Sgblack@eecs.umich.edu        }
10067435Sgblack@eecs.umich.edu        return new Unknown(machInst);
10077435Sgblack@eecs.umich.edu    }
10087435Sgblack@eecs.umich.edu
10097435Sgblack@eecs.umich.edu    static StaticInstPtr
10107435Sgblack@eecs.umich.edu    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
10117435Sgblack@eecs.umich.edu    {
10127435Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10137435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
10147639Sgblack@eecs.umich.edu        const IntRegIndex vd =
10157639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
10167639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
10177639Sgblack@eecs.umich.edu        const IntRegIndex vn =
10187639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
10197639Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
10207639Sgblack@eecs.umich.edu        const IntRegIndex vm =
10217639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10227639Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
10237639Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
10247435Sgblack@eecs.umich.edu        switch (a) {
10257435Sgblack@eecs.umich.edu          case 0x0:
10267639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vaddl>(
10277639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10287435Sgblack@eecs.umich.edu          case 0x1:
10297639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vaddw>(
10307639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10317435Sgblack@eecs.umich.edu          case 0x2:
10327639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vsubl>(
10337639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10347435Sgblack@eecs.umich.edu          case 0x3:
10357639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vsubw>(
10367639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10377435Sgblack@eecs.umich.edu          case 0x4:
10387435Sgblack@eecs.umich.edu            if (u) {
10397639Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vraddhn>(
10407639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10417435Sgblack@eecs.umich.edu            } else {
10427639Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vaddhn>(
10437639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10447435Sgblack@eecs.umich.edu            }
10457435Sgblack@eecs.umich.edu          case 0x5:
10467639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vabal>(
10477639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10487435Sgblack@eecs.umich.edu          case 0x6:
10497435Sgblack@eecs.umich.edu            if (u) {
10507639Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vrsubhn>(
10517639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10527435Sgblack@eecs.umich.edu            } else {
10537639Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vsubhn>(
10547639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10557435Sgblack@eecs.umich.edu            }
10567435Sgblack@eecs.umich.edu          case 0x7:
10577435Sgblack@eecs.umich.edu            if (bits(machInst, 23)) {
10587639Sgblack@eecs.umich.edu                return decodeNeonUSThreeUSReg<Vabdl>(
10597639Sgblack@eecs.umich.edu                        u, size, machInst, vd, vn, vm);
10607435Sgblack@eecs.umich.edu            } else {
10617639Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabdD, VabdQ>(
10627639Sgblack@eecs.umich.edu                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
10637435Sgblack@eecs.umich.edu            }
10647435Sgblack@eecs.umich.edu          case 0x8:
10657639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmlal>(
10667639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10677435Sgblack@eecs.umich.edu          case 0xa:
10687639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmlsl>(
10697639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10707435Sgblack@eecs.umich.edu          case 0x9:
10717639Sgblack@eecs.umich.edu            if (u) {
10727639Sgblack@eecs.umich.edu                return new Unknown(machInst);
10737435Sgblack@eecs.umich.edu            } else {
10747639Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmlal>(
10757639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10767435Sgblack@eecs.umich.edu            }
10777435Sgblack@eecs.umich.edu          case 0xb:
10787639Sgblack@eecs.umich.edu            if (u) {
10797435Sgblack@eecs.umich.edu                return new Unknown(machInst);
10807435Sgblack@eecs.umich.edu            } else {
10817639Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmlsl>(
10827639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10837435Sgblack@eecs.umich.edu            }
10847435Sgblack@eecs.umich.edu          case 0xc:
10857639Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vmull>(
10867639Sgblack@eecs.umich.edu                    u, size, machInst, vd, vn, vm);
10877435Sgblack@eecs.umich.edu          case 0xd:
10887639Sgblack@eecs.umich.edu            if (u) {
10897435Sgblack@eecs.umich.edu                return new Unknown(machInst);
10907435Sgblack@eecs.umich.edu            } else {
10917639Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmull>(
10927639Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10937435Sgblack@eecs.umich.edu            }
10947435Sgblack@eecs.umich.edu          case 0xe:
10957639Sgblack@eecs.umich.edu            return decodeNeonUThreeUSReg<Vmullp>(
10967639Sgblack@eecs.umich.edu                    size, machInst, vd, vn, vm);
10977435Sgblack@eecs.umich.edu        }
10987435Sgblack@eecs.umich.edu        return new Unknown(machInst);
10997435Sgblack@eecs.umich.edu    }
11007435Sgblack@eecs.umich.edu
11017435Sgblack@eecs.umich.edu    static StaticInstPtr
11027435Sgblack@eecs.umich.edu    decodeNeonTwoRegScalar(ExtMachInst machInst)
11037435Sgblack@eecs.umich.edu    {
11047435Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
11057435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
11067639Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
11077639Sgblack@eecs.umich.edu        const IntRegIndex vd =
11087639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11097639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
11107639Sgblack@eecs.umich.edu        const IntRegIndex vn =
11117639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11127639Sgblack@eecs.umich.edu                               (bits(machInst, 7) << 4)));
11137639Sgblack@eecs.umich.edu        const IntRegIndex vm = (size == 2) ?
11147639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
11157639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * bits(machInst, 2, 0));
11167639Sgblack@eecs.umich.edu        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11177639Sgblack@eecs.umich.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11187435Sgblack@eecs.umich.edu        switch (a) {
11197435Sgblack@eecs.umich.edu          case 0x0:
11207639Sgblack@eecs.umich.edu            if (u) {
11217639Sgblack@eecs.umich.edu                switch (size) {
11227639Sgblack@eecs.umich.edu                  case 1:
11237639Sgblack@eecs.umich.edu                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
11247639Sgblack@eecs.umich.edu                  case 2:
11257639Sgblack@eecs.umich.edu                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
11267639Sgblack@eecs.umich.edu                  default:
11277639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11287639Sgblack@eecs.umich.edu                }
11297639Sgblack@eecs.umich.edu            } else {
11307639Sgblack@eecs.umich.edu                switch (size) {
11317639Sgblack@eecs.umich.edu                  case 1:
11327639Sgblack@eecs.umich.edu                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
11337639Sgblack@eecs.umich.edu                  case 2:
11347639Sgblack@eecs.umich.edu                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
11357639Sgblack@eecs.umich.edu                  default:
11367639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11377639Sgblack@eecs.umich.edu                }
11387639Sgblack@eecs.umich.edu            }
11397435Sgblack@eecs.umich.edu          case 0x1:
11407639Sgblack@eecs.umich.edu            if (u)
11417639Sgblack@eecs.umich.edu                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
11427639Sgblack@eecs.umich.edu            else
11437639Sgblack@eecs.umich.edu                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
11447435Sgblack@eecs.umich.edu          case 0x4:
11457639Sgblack@eecs.umich.edu            if (u) {
11467639Sgblack@eecs.umich.edu                switch (size) {
11477639Sgblack@eecs.umich.edu                  case 1:
11487639Sgblack@eecs.umich.edu                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11497639Sgblack@eecs.umich.edu                  case 2:
11507639Sgblack@eecs.umich.edu                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11517639Sgblack@eecs.umich.edu                  default:
11527639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11537639Sgblack@eecs.umich.edu                }
11547639Sgblack@eecs.umich.edu            } else {
11557639Sgblack@eecs.umich.edu                switch (size) {
11567639Sgblack@eecs.umich.edu                  case 1:
11577639Sgblack@eecs.umich.edu                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
11587639Sgblack@eecs.umich.edu                  case 2:
11597639Sgblack@eecs.umich.edu                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11607639Sgblack@eecs.umich.edu                  default:
11617639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11627639Sgblack@eecs.umich.edu                }
11637639Sgblack@eecs.umich.edu            }
11647435Sgblack@eecs.umich.edu          case 0x5:
11657639Sgblack@eecs.umich.edu            if (u)
11667639Sgblack@eecs.umich.edu                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
11677639Sgblack@eecs.umich.edu            else
11687639Sgblack@eecs.umich.edu                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
11697435Sgblack@eecs.umich.edu          case 0x2:
11707639Sgblack@eecs.umich.edu            if (u) {
11717639Sgblack@eecs.umich.edu                switch (size) {
11727639Sgblack@eecs.umich.edu                  case 1:
11737639Sgblack@eecs.umich.edu                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11747639Sgblack@eecs.umich.edu                  case 2:
11757639Sgblack@eecs.umich.edu                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11767639Sgblack@eecs.umich.edu                  default:
11777639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11787639Sgblack@eecs.umich.edu                }
11797639Sgblack@eecs.umich.edu            } else {
11807639Sgblack@eecs.umich.edu                switch (size) {
11817639Sgblack@eecs.umich.edu                  case 1:
11827639Sgblack@eecs.umich.edu                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
11837639Sgblack@eecs.umich.edu                  case 2:
11847639Sgblack@eecs.umich.edu                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
11857639Sgblack@eecs.umich.edu                  default:
11867639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11877639Sgblack@eecs.umich.edu                }
11887639Sgblack@eecs.umich.edu            }
11897435Sgblack@eecs.umich.edu          case 0x6:
11907639Sgblack@eecs.umich.edu            if (u) {
11917639Sgblack@eecs.umich.edu                switch (size) {
11927639Sgblack@eecs.umich.edu                  case 1:
11937639Sgblack@eecs.umich.edu                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
11947639Sgblack@eecs.umich.edu                  case 2:
11957639Sgblack@eecs.umich.edu                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
11967639Sgblack@eecs.umich.edu                  default:
11977639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11987639Sgblack@eecs.umich.edu                }
11997639Sgblack@eecs.umich.edu            } else {
12007639Sgblack@eecs.umich.edu                switch (size) {
12017639Sgblack@eecs.umich.edu                  case 1:
12027639Sgblack@eecs.umich.edu                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
12037639Sgblack@eecs.umich.edu                  case 2:
12047639Sgblack@eecs.umich.edu                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
12057639Sgblack@eecs.umich.edu                  default:
12067639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12077639Sgblack@eecs.umich.edu                }
12087639Sgblack@eecs.umich.edu            }
12097435Sgblack@eecs.umich.edu          case 0x3:
12107435Sgblack@eecs.umich.edu            if (u) {
12117435Sgblack@eecs.umich.edu                return new Unknown(machInst);
12127435Sgblack@eecs.umich.edu            } else {
12137639Sgblack@eecs.umich.edu                switch (size) {
12147639Sgblack@eecs.umich.edu                  case 1:
12157639Sgblack@eecs.umich.edu                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12167639Sgblack@eecs.umich.edu                  case 2:
12177639Sgblack@eecs.umich.edu                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12187639Sgblack@eecs.umich.edu                  default:
12197639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12207639Sgblack@eecs.umich.edu                }
12217435Sgblack@eecs.umich.edu            }
12227435Sgblack@eecs.umich.edu          case 0x7:
12237435Sgblack@eecs.umich.edu            if (u) {
12247435Sgblack@eecs.umich.edu                return new Unknown(machInst);
12257435Sgblack@eecs.umich.edu            } else {
12267639Sgblack@eecs.umich.edu                switch (size) {
12277639Sgblack@eecs.umich.edu                  case 1:
12287639Sgblack@eecs.umich.edu                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12297639Sgblack@eecs.umich.edu                  case 2:
12307639Sgblack@eecs.umich.edu                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12317639Sgblack@eecs.umich.edu                  default:
12327639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12337639Sgblack@eecs.umich.edu                }
12347435Sgblack@eecs.umich.edu            }
12357435Sgblack@eecs.umich.edu          case 0x8:
12367639Sgblack@eecs.umich.edu            if (u) {
12377639Sgblack@eecs.umich.edu                switch (size) {
12387639Sgblack@eecs.umich.edu                  case 1:
12397639Sgblack@eecs.umich.edu                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
12407639Sgblack@eecs.umich.edu                  case 2:
12417639Sgblack@eecs.umich.edu                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
12427639Sgblack@eecs.umich.edu                  default:
12437639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12447639Sgblack@eecs.umich.edu                }
12457639Sgblack@eecs.umich.edu            } else {
12467639Sgblack@eecs.umich.edu                switch (size) {
12477639Sgblack@eecs.umich.edu                  case 1:
12487639Sgblack@eecs.umich.edu                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
12497639Sgblack@eecs.umich.edu                  case 2:
12507639Sgblack@eecs.umich.edu                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
12517639Sgblack@eecs.umich.edu                  default:
12527639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12537639Sgblack@eecs.umich.edu                }
12547639Sgblack@eecs.umich.edu            }
12557435Sgblack@eecs.umich.edu          case 0x9:
12567639Sgblack@eecs.umich.edu            if (u)
12577639Sgblack@eecs.umich.edu                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
12587639Sgblack@eecs.umich.edu            else
12597639Sgblack@eecs.umich.edu                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
12607435Sgblack@eecs.umich.edu          case 0xa:
12617639Sgblack@eecs.umich.edu            if (u) {
12627639Sgblack@eecs.umich.edu                switch (size) {
12637639Sgblack@eecs.umich.edu                  case 1:
12647639Sgblack@eecs.umich.edu                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
12657639Sgblack@eecs.umich.edu                  case 2:
12667639Sgblack@eecs.umich.edu                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
12677639Sgblack@eecs.umich.edu                  default:
12687639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12697639Sgblack@eecs.umich.edu                }
12707639Sgblack@eecs.umich.edu            } else {
12717639Sgblack@eecs.umich.edu                switch (size) {
12727639Sgblack@eecs.umich.edu                  case 1:
12737639Sgblack@eecs.umich.edu                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
12747639Sgblack@eecs.umich.edu                  case 2:
12757639Sgblack@eecs.umich.edu                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
12767639Sgblack@eecs.umich.edu                  default:
12777639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12787639Sgblack@eecs.umich.edu                }
12797639Sgblack@eecs.umich.edu            }
12807435Sgblack@eecs.umich.edu          case 0xb:
12817435Sgblack@eecs.umich.edu            if (u) {
12827435Sgblack@eecs.umich.edu                return new Unknown(machInst);
12837435Sgblack@eecs.umich.edu            } else {
12847639Sgblack@eecs.umich.edu                if (u) {
12857639Sgblack@eecs.umich.edu                    switch (size) {
12867639Sgblack@eecs.umich.edu                      case 1:
12877639Sgblack@eecs.umich.edu                        return new Vqdmulls<uint16_t>(
12887639Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
12897639Sgblack@eecs.umich.edu                      case 2:
12907639Sgblack@eecs.umich.edu                        return new Vqdmulls<uint32_t>(
12917639Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
12927639Sgblack@eecs.umich.edu                      default:
12937639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
12947639Sgblack@eecs.umich.edu                    }
12957639Sgblack@eecs.umich.edu                } else {
12967639Sgblack@eecs.umich.edu                    switch (size) {
12977639Sgblack@eecs.umich.edu                      case 1:
12987639Sgblack@eecs.umich.edu                        return new Vqdmulls<int16_t>(
12997639Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13007639Sgblack@eecs.umich.edu                      case 2:
13017639Sgblack@eecs.umich.edu                        return new Vqdmulls<int32_t>(
13027639Sgblack@eecs.umich.edu                                machInst, vd, vn, vm, index);
13037639Sgblack@eecs.umich.edu                      default:
13047639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
13057639Sgblack@eecs.umich.edu                    }
13067639Sgblack@eecs.umich.edu                }
13077435Sgblack@eecs.umich.edu            }
13087435Sgblack@eecs.umich.edu          case 0xc:
13097639Sgblack@eecs.umich.edu            if (u) {
13107639Sgblack@eecs.umich.edu                switch (size) {
13117639Sgblack@eecs.umich.edu                  case 1:
13127639Sgblack@eecs.umich.edu                    return new VqdmulhsQ<int16_t>(
13137639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13147639Sgblack@eecs.umich.edu                  case 2:
13157639Sgblack@eecs.umich.edu                    return new VqdmulhsQ<int32_t>(
13167639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13177639Sgblack@eecs.umich.edu                  default:
13187639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13197639Sgblack@eecs.umich.edu                }
13207639Sgblack@eecs.umich.edu            } else {
13217639Sgblack@eecs.umich.edu                switch (size) {
13227639Sgblack@eecs.umich.edu                  case 1:
13237639Sgblack@eecs.umich.edu                    return new VqdmulhsD<int16_t>(
13247639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13257639Sgblack@eecs.umich.edu                  case 2:
13267639Sgblack@eecs.umich.edu                    return new VqdmulhsD<int32_t>(
13277639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13287639Sgblack@eecs.umich.edu                  default:
13297639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13307639Sgblack@eecs.umich.edu                }
13317639Sgblack@eecs.umich.edu            }
13327435Sgblack@eecs.umich.edu          case 0xd:
13337639Sgblack@eecs.umich.edu            if (u) {
13347639Sgblack@eecs.umich.edu                switch (size) {
13357639Sgblack@eecs.umich.edu                  case 1:
13367639Sgblack@eecs.umich.edu                    return new VqrdmulhsQ<int16_t>(
13377639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13387639Sgblack@eecs.umich.edu                  case 2:
13397639Sgblack@eecs.umich.edu                    return new VqrdmulhsQ<int32_t>(
13407639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13417639Sgblack@eecs.umich.edu                  default:
13427639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13437639Sgblack@eecs.umich.edu                }
13447639Sgblack@eecs.umich.edu            } else {
13457639Sgblack@eecs.umich.edu                switch (size) {
13467639Sgblack@eecs.umich.edu                  case 1:
13477639Sgblack@eecs.umich.edu                    return new VqrdmulhsD<int16_t>(
13487639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13497639Sgblack@eecs.umich.edu                  case 2:
13507639Sgblack@eecs.umich.edu                    return new VqrdmulhsD<int32_t>(
13517639Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, index);
13527639Sgblack@eecs.umich.edu                  default:
13537639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13547639Sgblack@eecs.umich.edu                }
13557639Sgblack@eecs.umich.edu            }
13567435Sgblack@eecs.umich.edu        }
13577435Sgblack@eecs.umich.edu        return new Unknown(machInst);
13587435Sgblack@eecs.umich.edu    }
13597435Sgblack@eecs.umich.edu
13607435Sgblack@eecs.umich.edu    static StaticInstPtr
13617435Sgblack@eecs.umich.edu    decodeNeonTwoRegMisc(ExtMachInst machInst)
13627435Sgblack@eecs.umich.edu    {
13637435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 17, 16);
13647435Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 10, 6);
13657639Sgblack@eecs.umich.edu        const bool q = bits(machInst, 6);
13667639Sgblack@eecs.umich.edu        const IntRegIndex vd =
13677639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
13687639Sgblack@eecs.umich.edu                               (bits(machInst, 22) << 4)));
13697639Sgblack@eecs.umich.edu        const IntRegIndex vm =
13707639Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
13717639Sgblack@eecs.umich.edu                               (bits(machInst, 5) << 4)));
13727639Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 19, 18);
13737435Sgblack@eecs.umich.edu        switch (a) {
13747435Sgblack@eecs.umich.edu          case 0x0:
13757435Sgblack@eecs.umich.edu            switch (bits(b, 4, 1)) {
13767435Sgblack@eecs.umich.edu              case 0x0:
13777639Sgblack@eecs.umich.edu                switch (size) {
13787639Sgblack@eecs.umich.edu                  case 0:
13797639Sgblack@eecs.umich.edu                    if (q) {
13807639Sgblack@eecs.umich.edu                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
13817639Sgblack@eecs.umich.edu                    } else {
13827639Sgblack@eecs.umich.edu                        return new NVrev64D<uint8_t>(machInst, vd, vm);
13837639Sgblack@eecs.umich.edu                    }
13847639Sgblack@eecs.umich.edu                  case 1:
13857639Sgblack@eecs.umich.edu                    if (q) {
13867639Sgblack@eecs.umich.edu                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
13877639Sgblack@eecs.umich.edu                    } else {
13887639Sgblack@eecs.umich.edu                        return new NVrev64D<uint16_t>(machInst, vd, vm);
13897639Sgblack@eecs.umich.edu                    }
13907639Sgblack@eecs.umich.edu                  case 2:
13917639Sgblack@eecs.umich.edu                    if (q) {
13927639Sgblack@eecs.umich.edu                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
13937639Sgblack@eecs.umich.edu                    } else {
13947639Sgblack@eecs.umich.edu                        return new NVrev64D<uint32_t>(machInst, vd, vm);
13957639Sgblack@eecs.umich.edu                    }
13967639Sgblack@eecs.umich.edu                  default:
13977639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
13987639Sgblack@eecs.umich.edu                }
13997435Sgblack@eecs.umich.edu              case 0x1:
14007639Sgblack@eecs.umich.edu                switch (size) {
14017639Sgblack@eecs.umich.edu                  case 0:
14027639Sgblack@eecs.umich.edu                    if (q) {
14037639Sgblack@eecs.umich.edu                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
14047639Sgblack@eecs.umich.edu                    } else {
14057639Sgblack@eecs.umich.edu                        return new NVrev32D<uint8_t>(machInst, vd, vm);
14067639Sgblack@eecs.umich.edu                    }
14077639Sgblack@eecs.umich.edu                  case 1:
14087639Sgblack@eecs.umich.edu                    if (q) {
14097639Sgblack@eecs.umich.edu                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
14107639Sgblack@eecs.umich.edu                    } else {
14117639Sgblack@eecs.umich.edu                        return new NVrev32D<uint16_t>(machInst, vd, vm);
14127639Sgblack@eecs.umich.edu                    }
14137639Sgblack@eecs.umich.edu                  default:
14147639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
14157639Sgblack@eecs.umich.edu                }
14167435Sgblack@eecs.umich.edu              case 0x2:
14177639Sgblack@eecs.umich.edu                if (size != 0) {
14187639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
14197639Sgblack@eecs.umich.edu                } else if (q) {
14207639Sgblack@eecs.umich.edu                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
14217639Sgblack@eecs.umich.edu                } else {
14227639Sgblack@eecs.umich.edu                    return new NVrev16D<uint8_t>(machInst, vd, vm);
14237639Sgblack@eecs.umich.edu                }
14247435Sgblack@eecs.umich.edu              case 0x4:
14257639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14267639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14277435Sgblack@eecs.umich.edu              case 0x5:
14287639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14297639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14307435Sgblack@eecs.umich.edu              case 0x8:
14317639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
14327639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14337435Sgblack@eecs.umich.edu              case 0x9:
14347639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
14357639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14367435Sgblack@eecs.umich.edu              case 0xa:
14377639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
14387639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14397435Sgblack@eecs.umich.edu              case 0xb:
14407639Sgblack@eecs.umich.edu                if (q)
14417639Sgblack@eecs.umich.edu                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
14427639Sgblack@eecs.umich.edu                else
14437639Sgblack@eecs.umich.edu                    return new NVmvnD<uint64_t>(machInst, vd, vm);
14447435Sgblack@eecs.umich.edu              case 0xc:
14457639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
14467639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14477435Sgblack@eecs.umich.edu              case 0xd:
14487639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
14497639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14507435Sgblack@eecs.umich.edu              case 0xe:
14517639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
14527639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14537435Sgblack@eecs.umich.edu              case 0xf:
14547639Sgblack@eecs.umich.edu                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
14557639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14567435Sgblack@eecs.umich.edu              default:
14577435Sgblack@eecs.umich.edu                return new Unknown(machInst);
14587435Sgblack@eecs.umich.edu            }
14597435Sgblack@eecs.umich.edu          case 0x1:
14607435Sgblack@eecs.umich.edu            switch (bits(b, 3, 1)) {
14617435Sgblack@eecs.umich.edu              case 0x0:
14627639Sgblack@eecs.umich.edu                if (bits(b, 4)) {
14637639Sgblack@eecs.umich.edu                    if (q) {
14647639Sgblack@eecs.umich.edu                        return new NVcgtQFp<float>(machInst, vd, vm);
14657639Sgblack@eecs.umich.edu                    } else {
14667639Sgblack@eecs.umich.edu                        return new NVcgtDFp<float>(machInst, vd, vm);
14677639Sgblack@eecs.umich.edu                    }
14687639Sgblack@eecs.umich.edu                } else {
14697639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
14707639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
14717639Sgblack@eecs.umich.edu                }
14727435Sgblack@eecs.umich.edu              case 0x1:
14737639Sgblack@eecs.umich.edu                if (bits(b, 4)) {
14747639Sgblack@eecs.umich.edu                    if (q) {
14757639Sgblack@eecs.umich.edu                        return new NVcgeQFp<float>(machInst, vd, vm);
14767639Sgblack@eecs.umich.edu                    } else {
14777639Sgblack@eecs.umich.edu                        return new NVcgeDFp<float>(machInst, vd, vm);
14787639Sgblack@eecs.umich.edu                    }
14797639Sgblack@eecs.umich.edu                } else {
14807639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
14817639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
14827639Sgblack@eecs.umich.edu                }
14837435Sgblack@eecs.umich.edu              case 0x2:
14847639Sgblack@eecs.umich.edu                if (bits(b, 4)) {
14857639Sgblack@eecs.umich.edu                    if (q) {
14867639Sgblack@eecs.umich.edu                        return new NVceqQFp<float>(machInst, vd, vm);
14877639Sgblack@eecs.umich.edu                    } else {
14887639Sgblack@eecs.umich.edu                        return new NVceqDFp<float>(machInst, vd, vm);
14897639Sgblack@eecs.umich.edu                    }
14907639Sgblack@eecs.umich.edu                } else {
14917639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
14927639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
14937639Sgblack@eecs.umich.edu                }
14947435Sgblack@eecs.umich.edu              case 0x3:
14957639Sgblack@eecs.umich.edu                if (bits(b, 4)) {
14967639Sgblack@eecs.umich.edu                    if (q) {
14977639Sgblack@eecs.umich.edu                        return new NVcleQFp<float>(machInst, vd, vm);
14987639Sgblack@eecs.umich.edu                    } else {
14997639Sgblack@eecs.umich.edu                        return new NVcleDFp<float>(machInst, vd, vm);
15007639Sgblack@eecs.umich.edu                    }
15017639Sgblack@eecs.umich.edu                } else {
15027639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
15037639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
15047639Sgblack@eecs.umich.edu                }
15057435Sgblack@eecs.umich.edu              case 0x4:
15067639Sgblack@eecs.umich.edu                if (bits(b, 4)) {
15077639Sgblack@eecs.umich.edu                    if (q) {
15087639Sgblack@eecs.umich.edu                        return new NVcltQFp<float>(machInst, vd, vm);
15097639Sgblack@eecs.umich.edu                    } else {
15107639Sgblack@eecs.umich.edu                        return new NVcltDFp<float>(machInst, vd, vm);
15117639Sgblack@eecs.umich.edu                    }
15127639Sgblack@eecs.umich.edu                } else {
15137639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
15147639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
15157639Sgblack@eecs.umich.edu                }
15167435Sgblack@eecs.umich.edu              case 0x6:
15177639Sgblack@eecs.umich.edu                if (bits(machInst, 10)) {
15187639Sgblack@eecs.umich.edu                    if (q)
15197639Sgblack@eecs.umich.edu                        return new NVabsQFp<float>(machInst, vd, vm);
15207639Sgblack@eecs.umich.edu                    else
15217639Sgblack@eecs.umich.edu                        return new NVabsDFp<float>(machInst, vd, vm);
15227639Sgblack@eecs.umich.edu                } else {
15237639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
15247639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
15257639Sgblack@eecs.umich.edu                }
15267435Sgblack@eecs.umich.edu              case 0x7:
15277639Sgblack@eecs.umich.edu                if (bits(machInst, 10)) {
15287639Sgblack@eecs.umich.edu                    if (q)
15297639Sgblack@eecs.umich.edu                        return new NVnegQFp<float>(machInst, vd, vm);
15307639Sgblack@eecs.umich.edu                    else
15317639Sgblack@eecs.umich.edu                        return new NVnegDFp<float>(machInst, vd, vm);
15327639Sgblack@eecs.umich.edu                } else {
15337639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
15347639Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm);
15357639Sgblack@eecs.umich.edu                }
15367435Sgblack@eecs.umich.edu            }
15377435Sgblack@eecs.umich.edu          case 0x2:
15387435Sgblack@eecs.umich.edu            switch (bits(b, 4, 1)) {
15397435Sgblack@eecs.umich.edu              case 0x0:
15407639Sgblack@eecs.umich.edu                if (q)
15417639Sgblack@eecs.umich.edu                    return new NVswpQ<uint64_t>(machInst, vd, vm);
15427639Sgblack@eecs.umich.edu                else
15437639Sgblack@eecs.umich.edu                    return new NVswpD<uint64_t>(machInst, vd, vm);
15447435Sgblack@eecs.umich.edu              case 0x1:
15457639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
15467639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
15477435Sgblack@eecs.umich.edu              case 0x2:
15487639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
15497639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
15507435Sgblack@eecs.umich.edu              case 0x3:
15517639Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
15527639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
15537435Sgblack@eecs.umich.edu              case 0x4:
15547435Sgblack@eecs.umich.edu                if (b == 0x8) {
15557639Sgblack@eecs.umich.edu                    return decodeNeonUTwoMiscUSReg<NVmovn>(
15567639Sgblack@eecs.umich.edu                            size, machInst, vd, vm);
15577435Sgblack@eecs.umich.edu                } else {
15587639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
15597639Sgblack@eecs.umich.edu                            size, machInst, vd, vm);
15607435Sgblack@eecs.umich.edu                }
15617435Sgblack@eecs.umich.edu              case 0x5:
15627639Sgblack@eecs.umich.edu                if (q) {
15637639Sgblack@eecs.umich.edu                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
15647639Sgblack@eecs.umich.edu                            size, machInst, vd, vm);
15657639Sgblack@eecs.umich.edu                } else {
15667639Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
15677639Sgblack@eecs.umich.edu                            size, machInst, vd, vm);
15687639Sgblack@eecs.umich.edu                }
15697435Sgblack@eecs.umich.edu              case 0x6:
15707435Sgblack@eecs.umich.edu                if (b == 0xc) {
15717639Sgblack@eecs.umich.edu                    const IntRegIndex vd =
15727639Sgblack@eecs.umich.edu                        (IntRegIndex)(2 * (bits(machInst, 15, 12) |
15737639Sgblack@eecs.umich.edu                                           (bits(machInst, 22) << 4)));
15747639Sgblack@eecs.umich.edu                    const IntRegIndex vm =
15757639Sgblack@eecs.umich.edu                        (IntRegIndex)(2 * (bits(machInst, 3, 0) |
15767639Sgblack@eecs.umich.edu                                           (bits(machInst, 5) << 4)));
15777639Sgblack@eecs.umich.edu                    unsigned size = bits(machInst, 19, 18);
15787639Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftUSReg<NVshll>(
15797639Sgblack@eecs.umich.edu                            size, machInst, vd, vm, 8 << size);
15807435Sgblack@eecs.umich.edu                } else {
15817435Sgblack@eecs.umich.edu                    return new Unknown(machInst);
15827435Sgblack@eecs.umich.edu                }
15837435Sgblack@eecs.umich.edu              case 0xc:
15847435Sgblack@eecs.umich.edu              case 0xe:
15857435Sgblack@eecs.umich.edu                if (b == 0x18) {
15867639Sgblack@eecs.umich.edu                    if (size != 1 || (vm % 2))
15877639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
15887639Sgblack@eecs.umich.edu                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
15897435Sgblack@eecs.umich.edu                } else if (b == 0x1c) {
15907639Sgblack@eecs.umich.edu                    if (size != 1 || (vd % 2))
15917639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
15927639Sgblack@eecs.umich.edu                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
15937435Sgblack@eecs.umich.edu                } else {
15947435Sgblack@eecs.umich.edu                    return new Unknown(machInst);
15957435Sgblack@eecs.umich.edu                }
15967435Sgblack@eecs.umich.edu              default:
15977435Sgblack@eecs.umich.edu                return new Unknown(machInst);
15987435Sgblack@eecs.umich.edu            }
15997435Sgblack@eecs.umich.edu          case 0x3:
16007435Sgblack@eecs.umich.edu            if (bits(b, 4, 3) == 0x3) {
16017639Sgblack@eecs.umich.edu                if ((q && (vd % 2 || vm % 2)) || size != 2) {
16027639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
16037639Sgblack@eecs.umich.edu                } else {
16047639Sgblack@eecs.umich.edu                    if (bits(b, 2)) {
16057639Sgblack@eecs.umich.edu                        if (bits(b, 1)) {
16067639Sgblack@eecs.umich.edu                            if (q) {
16077639Sgblack@eecs.umich.edu                                return new NVcvt2ufxQ<float>(
16087639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16097639Sgblack@eecs.umich.edu                            } else {
16107639Sgblack@eecs.umich.edu                                return new NVcvt2ufxD<float>(
16117639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16127639Sgblack@eecs.umich.edu                            }
16137639Sgblack@eecs.umich.edu                        } else {
16147639Sgblack@eecs.umich.edu                            if (q) {
16157639Sgblack@eecs.umich.edu                                return new NVcvt2sfxQ<float>(
16167639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16177639Sgblack@eecs.umich.edu                            } else {
16187639Sgblack@eecs.umich.edu                                return new NVcvt2sfxD<float>(
16197639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16207639Sgblack@eecs.umich.edu                            }
16217639Sgblack@eecs.umich.edu                        }
16227639Sgblack@eecs.umich.edu                    } else {
16237639Sgblack@eecs.umich.edu                        if (bits(b, 1)) {
16247639Sgblack@eecs.umich.edu                            if (q) {
16257639Sgblack@eecs.umich.edu                                return new NVcvtu2fpQ<float>(
16267639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16277639Sgblack@eecs.umich.edu                            } else {
16287639Sgblack@eecs.umich.edu                                return new NVcvtu2fpD<float>(
16297639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16307639Sgblack@eecs.umich.edu                            }
16317639Sgblack@eecs.umich.edu                        } else {
16327639Sgblack@eecs.umich.edu                            if (q) {
16337639Sgblack@eecs.umich.edu                                return new NVcvts2fpQ<float>(
16347639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16357639Sgblack@eecs.umich.edu                            } else {
16367639Sgblack@eecs.umich.edu                                return new NVcvts2fpD<float>(
16377639Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16387639Sgblack@eecs.umich.edu                            }
16397639Sgblack@eecs.umich.edu                        }
16407639Sgblack@eecs.umich.edu                    }
16417639Sgblack@eecs.umich.edu                }
16427435Sgblack@eecs.umich.edu            } else if ((b & 0x1a) == 0x10) {
16437639Sgblack@eecs.umich.edu                if (bits(b, 2)) {
16447639Sgblack@eecs.umich.edu                    if (q) {
16457639Sgblack@eecs.umich.edu                        return new NVrecpeQFp<float>(machInst, vd, vm);
16467639Sgblack@eecs.umich.edu                    } else {
16477639Sgblack@eecs.umich.edu                        return new NVrecpeDFp<float>(machInst, vd, vm);
16487639Sgblack@eecs.umich.edu                    }
16497639Sgblack@eecs.umich.edu                } else {
16507639Sgblack@eecs.umich.edu                    if (q) {
16517639Sgblack@eecs.umich.edu                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
16527639Sgblack@eecs.umich.edu                    } else {
16537639Sgblack@eecs.umich.edu                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
16547639Sgblack@eecs.umich.edu                    }
16557639Sgblack@eecs.umich.edu                }
16567435Sgblack@eecs.umich.edu            } else if ((b & 0x1a) == 0x12) {
16577639Sgblack@eecs.umich.edu                if (bits(b, 2)) {
16587639Sgblack@eecs.umich.edu                    if (q) {
16597639Sgblack@eecs.umich.edu                        return new NVrsqrteQFp<float>(machInst, vd, vm);
16607639Sgblack@eecs.umich.edu                    } else {
16617639Sgblack@eecs.umich.edu                        return new NVrsqrteDFp<float>(machInst, vd, vm);
16627639Sgblack@eecs.umich.edu                    }
16637639Sgblack@eecs.umich.edu                } else {
16647639Sgblack@eecs.umich.edu                    if (q) {
16657639Sgblack@eecs.umich.edu                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
16667639Sgblack@eecs.umich.edu                    } else {
16677639Sgblack@eecs.umich.edu                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
16687639Sgblack@eecs.umich.edu                    }
16697639Sgblack@eecs.umich.edu                }
16707435Sgblack@eecs.umich.edu            } else {
16717435Sgblack@eecs.umich.edu                return new Unknown(machInst);
16727435Sgblack@eecs.umich.edu            }
16737435Sgblack@eecs.umich.edu        }
16747435Sgblack@eecs.umich.edu        return new Unknown(machInst);
16757435Sgblack@eecs.umich.edu    }
16767435Sgblack@eecs.umich.edu
16777435Sgblack@eecs.umich.edu    StaticInstPtr
16787435Sgblack@eecs.umich.edu    decodeNeonData(ExtMachInst machInst)
16797435Sgblack@eecs.umich.edu    {
16807435Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
16817435Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 23, 19);
16827435Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 11, 8);
16837435Sgblack@eecs.umich.edu        const uint32_t c = bits(machInst, 7, 4);
16847435Sgblack@eecs.umich.edu        if (bits(a, 4) == 0) {
16857435Sgblack@eecs.umich.edu            return decodeNeonThreeRegistersSameLength(machInst);
16867435Sgblack@eecs.umich.edu        } else if ((c & 0x9) == 1) {
16877435Sgblack@eecs.umich.edu            if ((a & 0x7) == 0) {
16887435Sgblack@eecs.umich.edu                return decodeNeonOneRegModImm(machInst);
16897435Sgblack@eecs.umich.edu            } else {
16907435Sgblack@eecs.umich.edu                return decodeNeonTwoRegAndShift(machInst);
16917435Sgblack@eecs.umich.edu            }
16927435Sgblack@eecs.umich.edu        } else if ((c & 0x9) == 9) {
16937435Sgblack@eecs.umich.edu            return decodeNeonTwoRegAndShift(machInst);
16947639Sgblack@eecs.umich.edu        } else if (bits(a, 2, 1) != 0x3) {
16957639Sgblack@eecs.umich.edu            if ((c & 0x5) == 0) {
16967435Sgblack@eecs.umich.edu                return decodeNeonThreeRegDiffLengths(machInst);
16977639Sgblack@eecs.umich.edu            } else if ((c & 0x5) == 4) {
16987435Sgblack@eecs.umich.edu                return decodeNeonTwoRegScalar(machInst);
16997435Sgblack@eecs.umich.edu            }
17007435Sgblack@eecs.umich.edu        } else if ((a & 0x16) == 0x16) {
17017639Sgblack@eecs.umich.edu            const IntRegIndex vd =
17027639Sgblack@eecs.umich.edu                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
17037639Sgblack@eecs.umich.edu                                   (bits(machInst, 22) << 4)));
17047639Sgblack@eecs.umich.edu            const IntRegIndex vn =
17057639Sgblack@eecs.umich.edu                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
17067639Sgblack@eecs.umich.edu                                   (bits(machInst, 7) << 4)));
17077639Sgblack@eecs.umich.edu            const IntRegIndex vm =
17087639Sgblack@eecs.umich.edu                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
17097639Sgblack@eecs.umich.edu                                   (bits(machInst, 5) << 4)));
17107435Sgblack@eecs.umich.edu            if (!u) {
17117435Sgblack@eecs.umich.edu                if (bits(c, 0) == 0) {
17127639Sgblack@eecs.umich.edu                    unsigned imm4 = bits(machInst, 11, 8);
17137639Sgblack@eecs.umich.edu                    bool q = bits(machInst, 6);
17147639Sgblack@eecs.umich.edu                    if (imm4 >= 16 && !q)
17157639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
17167639Sgblack@eecs.umich.edu                    if (q) {
17177639Sgblack@eecs.umich.edu                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
17187639Sgblack@eecs.umich.edu                    } else {
17197639Sgblack@eecs.umich.edu                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
17207639Sgblack@eecs.umich.edu                    }
17217435Sgblack@eecs.umich.edu                }
17227435Sgblack@eecs.umich.edu            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
17237435Sgblack@eecs.umich.edu                return decodeNeonTwoRegMisc(machInst);
17247435Sgblack@eecs.umich.edu            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
17257639Sgblack@eecs.umich.edu                unsigned length = bits(machInst, 9, 8) + 1;
17267639Sgblack@eecs.umich.edu                if ((uint32_t)vn / 2 + length > 32)
17277639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
17287435Sgblack@eecs.umich.edu                if (bits(machInst, 6) == 0) {
17297639Sgblack@eecs.umich.edu                    switch (length) {
17307639Sgblack@eecs.umich.edu                      case 1:
17317639Sgblack@eecs.umich.edu                        return new NVtbl1(machInst, vd, vn, vm);
17327639Sgblack@eecs.umich.edu                      case 2:
17337639Sgblack@eecs.umich.edu                        return new NVtbl2(machInst, vd, vn, vm);
17347639Sgblack@eecs.umich.edu                      case 3:
17357639Sgblack@eecs.umich.edu                        return new NVtbl3(machInst, vd, vn, vm);
17367639Sgblack@eecs.umich.edu                      case 4:
17377639Sgblack@eecs.umich.edu                        return new NVtbl4(machInst, vd, vn, vm);
17387639Sgblack@eecs.umich.edu                    }
17397435Sgblack@eecs.umich.edu                } else {
17407639Sgblack@eecs.umich.edu                    switch (length) {
17417639Sgblack@eecs.umich.edu                      case 1:
17427639Sgblack@eecs.umich.edu                        return new NVtbx1(machInst, vd, vn, vm);
17437639Sgblack@eecs.umich.edu                      case 2:
17447639Sgblack@eecs.umich.edu                        return new NVtbx2(machInst, vd, vn, vm);
17457639Sgblack@eecs.umich.edu                      case 3:
17467639Sgblack@eecs.umich.edu                        return new NVtbx3(machInst, vd, vn, vm);
17477639Sgblack@eecs.umich.edu                      case 4:
17487639Sgblack@eecs.umich.edu                        return new NVtbx4(machInst, vd, vn, vm);
17497639Sgblack@eecs.umich.edu                    }
17507435Sgblack@eecs.umich.edu                }
17517435Sgblack@eecs.umich.edu            } else if (b == 0xc && (c & 0x9) == 0) {
17527639Sgblack@eecs.umich.edu                unsigned imm4 = bits(machInst, 19, 16);
17537639Sgblack@eecs.umich.edu                if (bits(imm4, 2, 0) == 0)
17547639Sgblack@eecs.umich.edu                    return new Unknown(machInst);
17557639Sgblack@eecs.umich.edu                unsigned size = 0;
17567639Sgblack@eecs.umich.edu                while ((imm4 & 0x1) == 0) {
17577639Sgblack@eecs.umich.edu                    size++;
17587639Sgblack@eecs.umich.edu                    imm4 >>= 1;
17597639Sgblack@eecs.umich.edu                }
17607639Sgblack@eecs.umich.edu                unsigned index = imm4 >> 1;
17617639Sgblack@eecs.umich.edu                const bool q = bits(machInst, 6);
17627639Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
17637639Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm, index);
17647435Sgblack@eecs.umich.edu            }
17657435Sgblack@eecs.umich.edu        }
17667435Sgblack@eecs.umich.edu        return new Unknown(machInst);
17677435Sgblack@eecs.umich.edu    }
17687435Sgblack@eecs.umich.edu    '''
17697435Sgblack@eecs.umich.edu}};
17707435Sgblack@eecs.umich.edu
17717435Sgblack@eecs.umich.edudef format ThumbNeonMem() {{
17727435Sgblack@eecs.umich.edu    decode_block = '''
17737435Sgblack@eecs.umich.edu    return decodeNeonMem(machInst);
17747435Sgblack@eecs.umich.edu    '''
17757435Sgblack@eecs.umich.edu}};
17767435Sgblack@eecs.umich.edu
17777435Sgblack@eecs.umich.edudef format ThumbNeonData() {{
17787435Sgblack@eecs.umich.edu    decode_block = '''
17797639Sgblack@eecs.umich.edu    return decodeNeonData(machInst);
17807435Sgblack@eecs.umich.edu    '''
17817435Sgblack@eecs.umich.edu}};
17827435Sgblack@eecs.umich.edu
17837435Sgblack@eecs.umich.edulet {{
17847435Sgblack@eecs.umich.edu    header_output = '''
17857435Sgblack@eecs.umich.edu    StaticInstPtr
17867356Sgblack@eecs.umich.edu    decodeExtensionRegLoadStore(ExtMachInst machInst);
17877356Sgblack@eecs.umich.edu    '''
17887356Sgblack@eecs.umich.edu    decoder_output = '''
17897356Sgblack@eecs.umich.edu    StaticInstPtr
17907356Sgblack@eecs.umich.edu    decodeExtensionRegLoadStore(ExtMachInst machInst)
17917178Sgblack@eecs.umich.edu    {
17927178Sgblack@eecs.umich.edu        const uint32_t opcode = bits(machInst, 24, 20);
17937178Sgblack@eecs.umich.edu        const uint32_t offset = bits(machInst, 7, 0);
17947337Sgblack@eecs.umich.edu        const bool single = (bits(machInst, 8) == 0);
17957178Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
17967178Sgblack@eecs.umich.edu        RegIndex vd;
17977178Sgblack@eecs.umich.edu        if (single) {
17987178Sgblack@eecs.umich.edu            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
17997178Sgblack@eecs.umich.edu                                      bits(machInst, 22));
18007178Sgblack@eecs.umich.edu        } else {
18017178Sgblack@eecs.umich.edu            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
18027178Sgblack@eecs.umich.edu                                      (bits(machInst, 22) << 5));
18037178Sgblack@eecs.umich.edu        }
18047178Sgblack@eecs.umich.edu        switch (bits(opcode, 4, 3)) {
18057178Sgblack@eecs.umich.edu          case 0x0:
18067335Sgblack@eecs.umich.edu            if (bits(opcode, 4, 1) == 0x2 &&
18077335Sgblack@eecs.umich.edu                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
18087335Sgblack@eecs.umich.edu                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
18097335Sgblack@eecs.umich.edu                if ((bits(machInst, 7, 4) & 0xd) != 1) {
18107335Sgblack@eecs.umich.edu                    break;
18117335Sgblack@eecs.umich.edu                }
18127335Sgblack@eecs.umich.edu                const IntRegIndex rt =
18137335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
18147335Sgblack@eecs.umich.edu                const IntRegIndex rt2 =
18157335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
18167335Sgblack@eecs.umich.edu                const bool op = bits(machInst, 20);
18177335Sgblack@eecs.umich.edu                uint32_t vm;
18187337Sgblack@eecs.umich.edu                if (single) {
18197335Sgblack@eecs.umich.edu                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
18207335Sgblack@eecs.umich.edu                } else {
18217335Sgblack@eecs.umich.edu                    vm = (bits(machInst, 3, 0) << 1) |
18227335Sgblack@eecs.umich.edu                         (bits(machInst, 5) << 5);
18237335Sgblack@eecs.umich.edu                }
18247335Sgblack@eecs.umich.edu                if (op) {
18257335Sgblack@eecs.umich.edu                    return new Vmov2Core2Reg(machInst, rt, rt2,
18267335Sgblack@eecs.umich.edu                                             (IntRegIndex)vm);
18277335Sgblack@eecs.umich.edu                } else {
18287335Sgblack@eecs.umich.edu                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
18297335Sgblack@eecs.umich.edu                                             rt, rt2);
18307335Sgblack@eecs.umich.edu                }
18317178Sgblack@eecs.umich.edu            }
18327178Sgblack@eecs.umich.edu            break;
18337178Sgblack@eecs.umich.edu          case 0x1:
18347413Sgblack@eecs.umich.edu            {
18357639Sgblack@eecs.umich.edu                if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
18367413Sgblack@eecs.umich.edu                    break;
18377413Sgblack@eecs.umich.edu                }
18387413Sgblack@eecs.umich.edu                switch (bits(opcode, 1, 0)) {
18397413Sgblack@eecs.umich.edu                  case 0x0:
18407413Sgblack@eecs.umich.edu                    return new VLdmStm(machInst, rn, vd, single,
18417413Sgblack@eecs.umich.edu                                       true, false, false, offset);
18427413Sgblack@eecs.umich.edu                  case 0x1:
18437413Sgblack@eecs.umich.edu                    return new VLdmStm(machInst, rn, vd, single,
18447413Sgblack@eecs.umich.edu                                       true, false, true, offset);
18457413Sgblack@eecs.umich.edu                  case 0x2:
18467413Sgblack@eecs.umich.edu                    return new VLdmStm(machInst, rn, vd, single,
18477413Sgblack@eecs.umich.edu                                       true, true, false, offset);
18487413Sgblack@eecs.umich.edu                  case 0x3:
18497413Sgblack@eecs.umich.edu                    // If rn == sp, then this is called vpop.
18507413Sgblack@eecs.umich.edu                    return new VLdmStm(machInst, rn, vd, single,
18517413Sgblack@eecs.umich.edu                                       true, true, true, offset);
18527413Sgblack@eecs.umich.edu                }
18537178Sgblack@eecs.umich.edu            }
18547178Sgblack@eecs.umich.edu          case 0x2:
18557178Sgblack@eecs.umich.edu            if (bits(opcode, 1, 0) == 0x2) {
18567178Sgblack@eecs.umich.edu                // If rn == sp, then this is called vpush.
18577178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
18587178Sgblack@eecs.umich.edu                                   false, true, false, offset);
18597178Sgblack@eecs.umich.edu            } else if (bits(opcode, 1, 0) == 0x3) {
18607178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
18617178Sgblack@eecs.umich.edu                                   false, true, true, offset);
18627178Sgblack@eecs.umich.edu            }
18637178Sgblack@eecs.umich.edu            // Fall through on purpose
18647178Sgblack@eecs.umich.edu          case 0x3:
18657346Sgblack@eecs.umich.edu            const bool up = (bits(machInst, 23) == 1);
18667346Sgblack@eecs.umich.edu            const uint32_t imm = bits(machInst, 7, 0) << 2;
18677346Sgblack@eecs.umich.edu            RegIndex vd;
18687346Sgblack@eecs.umich.edu            if (single) {
18697346Sgblack@eecs.umich.edu                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
18707346Sgblack@eecs.umich.edu                                          (bits(machInst, 22)));
18717346Sgblack@eecs.umich.edu            } else {
18727346Sgblack@eecs.umich.edu                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
18737346Sgblack@eecs.umich.edu                                          (bits(machInst, 22) << 5));
18747346Sgblack@eecs.umich.edu            }
18757178Sgblack@eecs.umich.edu            if (bits(opcode, 1, 0) == 0x0) {
18767346Sgblack@eecs.umich.edu                if (single) {
18777346Sgblack@eecs.umich.edu                    if (up) {
18787346Sgblack@eecs.umich.edu                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
18797346Sgblack@eecs.umich.edu                    } else {
18807346Sgblack@eecs.umich.edu                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
18817346Sgblack@eecs.umich.edu                    }
18827346Sgblack@eecs.umich.edu                } else {
18837346Sgblack@eecs.umich.edu                    if (up) {
18847346Sgblack@eecs.umich.edu                        return new %(vstr_ud)s(machInst, vd, vd + 1,
18857346Sgblack@eecs.umich.edu                                               rn, up, imm);
18867346Sgblack@eecs.umich.edu                    } else {
18877346Sgblack@eecs.umich.edu                        return new %(vstr_d)s(machInst, vd, vd + 1,
18887346Sgblack@eecs.umich.edu                                              rn, up, imm);
18897346Sgblack@eecs.umich.edu                    }
18907346Sgblack@eecs.umich.edu                }
18917178Sgblack@eecs.umich.edu            } else if (bits(opcode, 1, 0) == 0x1) {
18927337Sgblack@eecs.umich.edu                if (single) {
18937337Sgblack@eecs.umich.edu                    if (up) {
18947337Sgblack@eecs.umich.edu                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
18957337Sgblack@eecs.umich.edu                    } else {
18967337Sgblack@eecs.umich.edu                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
18977337Sgblack@eecs.umich.edu                    }
18987337Sgblack@eecs.umich.edu                } else {
18997337Sgblack@eecs.umich.edu                    if (up) {
19007337Sgblack@eecs.umich.edu                        return new %(vldr_ud)s(machInst, vd, vd + 1,
19017337Sgblack@eecs.umich.edu                                               rn, up, imm);
19027337Sgblack@eecs.umich.edu                    } else {
19037337Sgblack@eecs.umich.edu                        return new %(vldr_d)s(machInst, vd, vd + 1,
19047337Sgblack@eecs.umich.edu                                              rn, up, imm);
19057337Sgblack@eecs.umich.edu                    }
19067337Sgblack@eecs.umich.edu                }
19077178Sgblack@eecs.umich.edu            }
19087178Sgblack@eecs.umich.edu        }
19097178Sgblack@eecs.umich.edu        return new Unknown(machInst);
19107178Sgblack@eecs.umich.edu    }
19117337Sgblack@eecs.umich.edu    ''' % {
19127337Sgblack@eecs.umich.edu        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
19137337Sgblack@eecs.umich.edu        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
19147337Sgblack@eecs.umich.edu        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
19157346Sgblack@eecs.umich.edu        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
19167346Sgblack@eecs.umich.edu        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
19177346Sgblack@eecs.umich.edu        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
19187346Sgblack@eecs.umich.edu        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
19197346Sgblack@eecs.umich.edu        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
19207337Sgblack@eecs.umich.edu    }
19217178Sgblack@eecs.umich.edu}};
19227321Sgblack@eecs.umich.edu
19237356Sgblack@eecs.umich.edudef format ExtensionRegLoadStore() {{
19247321Sgblack@eecs.umich.edu    decode_block = '''
19257356Sgblack@eecs.umich.edu    return decodeExtensionRegLoadStore(machInst);
19267356Sgblack@eecs.umich.edu    '''
19277356Sgblack@eecs.umich.edu}};
19287356Sgblack@eecs.umich.edu
19297356Sgblack@eecs.umich.edulet {{
19307356Sgblack@eecs.umich.edu    header_output = '''
19317356Sgblack@eecs.umich.edu    StaticInstPtr
19327356Sgblack@eecs.umich.edu    decodeShortFpTransfer(ExtMachInst machInst);
19337356Sgblack@eecs.umich.edu    '''
19347356Sgblack@eecs.umich.edu    decoder_output = '''
19357356Sgblack@eecs.umich.edu    StaticInstPtr
19367356Sgblack@eecs.umich.edu    decodeShortFpTransfer(ExtMachInst machInst)
19377321Sgblack@eecs.umich.edu    {
19387321Sgblack@eecs.umich.edu        const uint32_t l = bits(machInst, 20);
19397321Sgblack@eecs.umich.edu        const uint32_t c = bits(machInst, 8);
19407321Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 23, 21);
19417321Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 6, 5);
19427321Sgblack@eecs.umich.edu        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
19437321Sgblack@eecs.umich.edu            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
19447321Sgblack@eecs.umich.edu            return new Unknown(machInst);
19457321Sgblack@eecs.umich.edu        }
19467321Sgblack@eecs.umich.edu        if (l == 0 && c == 0) {
19477321Sgblack@eecs.umich.edu            if (a == 0) {
19487335Sgblack@eecs.umich.edu                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
19497335Sgblack@eecs.umich.edu                                    bits(machInst, 7);
19507335Sgblack@eecs.umich.edu                const IntRegIndex rt =
19517335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
19527335Sgblack@eecs.umich.edu                if (bits(machInst, 20) == 1) {
19537335Sgblack@eecs.umich.edu                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
19547335Sgblack@eecs.umich.edu                } else {
19557335Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
19567335Sgblack@eecs.umich.edu                }
19577321Sgblack@eecs.umich.edu            } else if (a == 0x7) {
19587323Sgblack@eecs.umich.edu                const IntRegIndex rt =
19597323Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
19607323Sgblack@eecs.umich.edu                uint32_t specReg = bits(machInst, 19, 16);
19617323Sgblack@eecs.umich.edu                switch (specReg) {
19627323Sgblack@eecs.umich.edu                  case 0:
19637323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSID;
19647323Sgblack@eecs.umich.edu                    break;
19657323Sgblack@eecs.umich.edu                  case 1:
19667323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSCR;
19677323Sgblack@eecs.umich.edu                    break;
19687394Sgblack@eecs.umich.edu                  case 6:
19697394Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR1;
19707394Sgblack@eecs.umich.edu                    break;
19717394Sgblack@eecs.umich.edu                  case 7:
19727394Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR0;
19737394Sgblack@eecs.umich.edu                    break;
19747323Sgblack@eecs.umich.edu                  case 8:
19757323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPEXC;
19767323Sgblack@eecs.umich.edu                    break;
19777323Sgblack@eecs.umich.edu                  default:
19787323Sgblack@eecs.umich.edu                    return new Unknown(machInst);
19797323Sgblack@eecs.umich.edu                }
19807643Sgblack@eecs.umich.edu                if (specReg == MISCREG_FPSCR) {
19817643Sgblack@eecs.umich.edu                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
19827643Sgblack@eecs.umich.edu                } else {
19837643Sgblack@eecs.umich.edu                    return new Vmsr(machInst, (IntRegIndex)specReg, rt);
19847643Sgblack@eecs.umich.edu                }
19857321Sgblack@eecs.umich.edu            }
19867321Sgblack@eecs.umich.edu        } else if (l == 0 && c == 1) {
19877321Sgblack@eecs.umich.edu            if (bits(a, 2) == 0) {
19887335Sgblack@eecs.umich.edu                uint32_t vd = (bits(machInst, 7) << 5) |
19897335Sgblack@eecs.umich.edu                              (bits(machInst, 19, 16) << 1);
19907639Sgblack@eecs.umich.edu                // Handle accessing each single precision half of the vector.
19917639Sgblack@eecs.umich.edu                vd += bits(machInst, 21);
19927335Sgblack@eecs.umich.edu                const IntRegIndex rt =
19937335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
19947335Sgblack@eecs.umich.edu                if (bits(machInst, 22) == 1) {
19957639Sgblack@eecs.umich.edu                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
19967639Sgblack@eecs.umich.edu                                            rt, bits(machInst, 6, 5));
19977335Sgblack@eecs.umich.edu                } else if (bits(machInst, 5) == 1) {
19987639Sgblack@eecs.umich.edu                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
19997639Sgblack@eecs.umich.edu                                            rt, bits(machInst, 6));
20007335Sgblack@eecs.umich.edu                } else if (bits(machInst, 6) == 0) {
20017639Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
20027335Sgblack@eecs.umich.edu                } else {
20037335Sgblack@eecs.umich.edu                    return new Unknown(machInst);
20047335Sgblack@eecs.umich.edu                }
20057639Sgblack@eecs.umich.edu            } else if (bits(b, 1) == 0) {
20067639Sgblack@eecs.umich.edu                bool q = bits(machInst, 21);
20077639Sgblack@eecs.umich.edu                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
20087639Sgblack@eecs.umich.edu                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
20097639Sgblack@eecs.umich.edu                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
20107639Sgblack@eecs.umich.edu                IntRegIndex rt = (IntRegIndex)(uint32_t)
20117639Sgblack@eecs.umich.edu                    bits(machInst, 15, 12);
20127639Sgblack@eecs.umich.edu                if (q) {
20137639Sgblack@eecs.umich.edu                    switch (be) {
20147639Sgblack@eecs.umich.edu                      case 0:
20157639Sgblack@eecs.umich.edu                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
20167639Sgblack@eecs.umich.edu                      case 1:
20177639Sgblack@eecs.umich.edu                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
20187639Sgblack@eecs.umich.edu                      case 2:
20197639Sgblack@eecs.umich.edu                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
20207639Sgblack@eecs.umich.edu                      case 3:
20217639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
20227639Sgblack@eecs.umich.edu                    }
20237639Sgblack@eecs.umich.edu                } else {
20247639Sgblack@eecs.umich.edu                    switch (be) {
20257639Sgblack@eecs.umich.edu                      case 0:
20267639Sgblack@eecs.umich.edu                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
20277639Sgblack@eecs.umich.edu                      case 1:
20287639Sgblack@eecs.umich.edu                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
20297639Sgblack@eecs.umich.edu                      case 2:
20307639Sgblack@eecs.umich.edu                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
20317639Sgblack@eecs.umich.edu                      case 3:
20327639Sgblack@eecs.umich.edu                        return new Unknown(machInst);
20337639Sgblack@eecs.umich.edu                    }
20347335Sgblack@eecs.umich.edu                }
20357321Sgblack@eecs.umich.edu            }
20367321Sgblack@eecs.umich.edu        } else if (l == 1 && c == 0) {
20377321Sgblack@eecs.umich.edu            if (a == 0) {
20387335Sgblack@eecs.umich.edu                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
20397335Sgblack@eecs.umich.edu                                    bits(machInst, 7);
20407335Sgblack@eecs.umich.edu                const IntRegIndex rt =
20417335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
20427335Sgblack@eecs.umich.edu                if (bits(machInst, 20) == 1) {
20437335Sgblack@eecs.umich.edu                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
20447335Sgblack@eecs.umich.edu                } else {
20457335Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
20467335Sgblack@eecs.umich.edu                }
20477321Sgblack@eecs.umich.edu            } else if (a == 7) {
20487326Sgblack@eecs.umich.edu                const IntRegIndex rt =
20497326Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
20507326Sgblack@eecs.umich.edu                uint32_t specReg = bits(machInst, 19, 16);
20517326Sgblack@eecs.umich.edu                switch (specReg) {
20527326Sgblack@eecs.umich.edu                  case 0:
20537326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSID;
20547326Sgblack@eecs.umich.edu                    break;
20557326Sgblack@eecs.umich.edu                  case 1:
20567326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSCR;
20577326Sgblack@eecs.umich.edu                    break;
20587326Sgblack@eecs.umich.edu                  case 6:
20597326Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR1;
20607326Sgblack@eecs.umich.edu                    break;
20617326Sgblack@eecs.umich.edu                  case 7:
20627326Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR0;
20637326Sgblack@eecs.umich.edu                    break;
20647326Sgblack@eecs.umich.edu                  case 8:
20657326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPEXC;
20667326Sgblack@eecs.umich.edu                    break;
20677326Sgblack@eecs.umich.edu                  default:
20687326Sgblack@eecs.umich.edu                    return new Unknown(machInst);
20697326Sgblack@eecs.umich.edu                }
20707392Sgblack@eecs.umich.edu                if (rt == 0xf) {
20717392Sgblack@eecs.umich.edu                    CPSR cpsrMask = 0;
20727392Sgblack@eecs.umich.edu                    cpsrMask.n = 1;
20737392Sgblack@eecs.umich.edu                    cpsrMask.z = 1;
20747392Sgblack@eecs.umich.edu                    cpsrMask.c = 1;
20757392Sgblack@eecs.umich.edu                    cpsrMask.v = 1;
20767643Sgblack@eecs.umich.edu                    if (specReg == MISCREG_FPSCR) {
20778301SAli.Saidi@ARM.com                        return new VmrsApsrFpscr(machInst, INTREG_CONDCODES_F,
20787643Sgblack@eecs.umich.edu                                (IntRegIndex)specReg, (uint32_t)cpsrMask);
20797643Sgblack@eecs.umich.edu                    } else {
20808301SAli.Saidi@ARM.com                        return new Unknown(machInst);
20817643Sgblack@eecs.umich.edu                    }
20827643Sgblack@eecs.umich.edu                } else if (specReg == MISCREG_FPSCR) {
20837643Sgblack@eecs.umich.edu                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
20847392Sgblack@eecs.umich.edu                } else {
20857392Sgblack@eecs.umich.edu                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
20867392Sgblack@eecs.umich.edu                }
20877321Sgblack@eecs.umich.edu            }
20887321Sgblack@eecs.umich.edu        } else {
20897335Sgblack@eecs.umich.edu            uint32_t vd = (bits(machInst, 7) << 5) |
20907335Sgblack@eecs.umich.edu                          (bits(machInst, 19, 16) << 1);
20917639Sgblack@eecs.umich.edu            // Handle indexing into each single precision half of the vector.
20927639Sgblack@eecs.umich.edu            vd += bits(machInst, 21);
20937639Sgblack@eecs.umich.edu            uint32_t index;
20947335Sgblack@eecs.umich.edu            const IntRegIndex rt =
20957335Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
20967335Sgblack@eecs.umich.edu            const bool u = (bits(machInst, 23) == 1);
20977335Sgblack@eecs.umich.edu            if (bits(machInst, 22) == 1) {
20987639Sgblack@eecs.umich.edu                index = bits(machInst, 6, 5);
20997335Sgblack@eecs.umich.edu                if (u) {
21007335Sgblack@eecs.umich.edu                    return new VmovRegCoreUB(machInst, rt,
21017335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
21027335Sgblack@eecs.umich.edu                } else {
21037335Sgblack@eecs.umich.edu                    return new VmovRegCoreSB(machInst, rt,
21047335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
21057335Sgblack@eecs.umich.edu                }
21067639Sgblack@eecs.umich.edu            } else if (bits(machInst, 5) == 1) {
21077639Sgblack@eecs.umich.edu                index = bits(machInst, 6);
21087335Sgblack@eecs.umich.edu                if (u) {
21097335Sgblack@eecs.umich.edu                    return new VmovRegCoreUH(machInst, rt,
21107335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
21117335Sgblack@eecs.umich.edu                } else {
21127335Sgblack@eecs.umich.edu                    return new VmovRegCoreSH(machInst, rt,
21137335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
21147335Sgblack@eecs.umich.edu                }
21157639Sgblack@eecs.umich.edu            } else if (bits(machInst, 6) == 0 && !u) {
21167335Sgblack@eecs.umich.edu                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
21177639Sgblack@eecs.umich.edu            } else {
21187639Sgblack@eecs.umich.edu                return new Unknown(machInst);
21197335Sgblack@eecs.umich.edu            }
21207321Sgblack@eecs.umich.edu        }
21217321Sgblack@eecs.umich.edu        return new Unknown(machInst);
21227321Sgblack@eecs.umich.edu    }
21237321Sgblack@eecs.umich.edu    '''
21247321Sgblack@eecs.umich.edu}};
21257356Sgblack@eecs.umich.edu
21267356Sgblack@eecs.umich.edudef format ShortFpTransfer() {{
21277356Sgblack@eecs.umich.edu    decode_block = '''
21287356Sgblack@eecs.umich.edu    return decodeShortFpTransfer(machInst);
21297356Sgblack@eecs.umich.edu    '''
21307356Sgblack@eecs.umich.edu}};
21317363Sgblack@eecs.umich.edu
21327363Sgblack@eecs.umich.edulet {{
21337363Sgblack@eecs.umich.edu    header_output = '''
21347363Sgblack@eecs.umich.edu    StaticInstPtr
21357363Sgblack@eecs.umich.edu    decodeVfpData(ExtMachInst machInst);
21367363Sgblack@eecs.umich.edu    '''
21377363Sgblack@eecs.umich.edu    decoder_output = '''
21387363Sgblack@eecs.umich.edu    StaticInstPtr
21397363Sgblack@eecs.umich.edu    decodeVfpData(ExtMachInst machInst)
21407363Sgblack@eecs.umich.edu    {
21417363Sgblack@eecs.umich.edu        const uint32_t opc1 = bits(machInst, 23, 20);
21427363Sgblack@eecs.umich.edu        const uint32_t opc2 = bits(machInst, 19, 16);
21437363Sgblack@eecs.umich.edu        const uint32_t opc3 = bits(machInst, 7, 6);
21447363Sgblack@eecs.umich.edu        //const uint32_t opc4 = bits(machInst, 3, 0);
21457372Sgblack@eecs.umich.edu        const bool single = (bits(machInst, 8) == 0);
21467389Sgblack@eecs.umich.edu        // Used to select between vcmp and vcmpe.
21477389Sgblack@eecs.umich.edu        const bool e = (bits(machInst, 7) == 1);
21487372Sgblack@eecs.umich.edu        IntRegIndex vd;
21497372Sgblack@eecs.umich.edu        IntRegIndex vm;
21507372Sgblack@eecs.umich.edu        IntRegIndex vn;
21517372Sgblack@eecs.umich.edu        if (single) {
21527372Sgblack@eecs.umich.edu            vd = (IntRegIndex)(bits(machInst, 22) |
21537372Sgblack@eecs.umich.edu                    (bits(machInst, 15, 12) << 1));
21547372Sgblack@eecs.umich.edu            vm = (IntRegIndex)(bits(machInst, 5) |
21557372Sgblack@eecs.umich.edu                    (bits(machInst, 3, 0) << 1));
21567372Sgblack@eecs.umich.edu            vn = (IntRegIndex)(bits(machInst, 7) |
21577372Sgblack@eecs.umich.edu                    (bits(machInst, 19, 16) << 1));
21587372Sgblack@eecs.umich.edu        } else {
21597372Sgblack@eecs.umich.edu            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
21607372Sgblack@eecs.umich.edu                    (bits(machInst, 15, 12) << 1));
21617372Sgblack@eecs.umich.edu            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
21627372Sgblack@eecs.umich.edu                    (bits(machInst, 3, 0) << 1));
21637372Sgblack@eecs.umich.edu            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
21647372Sgblack@eecs.umich.edu                    (bits(machInst, 19, 16) << 1));
21657372Sgblack@eecs.umich.edu        }
21667363Sgblack@eecs.umich.edu        switch (opc1 & 0xb /* 1011 */) {
21677363Sgblack@eecs.umich.edu          case 0x0:
21687370Sgblack@eecs.umich.edu            if (bits(machInst, 6) == 0) {
21697372Sgblack@eecs.umich.edu                if (single) {
21707376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmlaS>(
21717376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
21727370Sgblack@eecs.umich.edu                } else {
21737376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmlaD>(
21747376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
21757370Sgblack@eecs.umich.edu                }
21767370Sgblack@eecs.umich.edu            } else {
21777372Sgblack@eecs.umich.edu                if (single) {
21787376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmlsS>(
21797376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
21807370Sgblack@eecs.umich.edu                } else {
21817376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmlsD>(
21827376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
21837370Sgblack@eecs.umich.edu                }
21847370Sgblack@eecs.umich.edu            }
21857371Sgblack@eecs.umich.edu          case 0x1:
21867371Sgblack@eecs.umich.edu            if (bits(machInst, 6) == 1) {
21877372Sgblack@eecs.umich.edu                if (single) {
21887376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmlaS>(
21897376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
21907371Sgblack@eecs.umich.edu                } else {
21917376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmlaD>(
21927376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
21937371Sgblack@eecs.umich.edu                }
21947371Sgblack@eecs.umich.edu            } else {
21957372Sgblack@eecs.umich.edu                if (single) {
21967376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmlsS>(
21977376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
21987371Sgblack@eecs.umich.edu                } else {
21997376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmlsD>(
22007376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22017371Sgblack@eecs.umich.edu                }
22027371Sgblack@eecs.umich.edu            }
22037363Sgblack@eecs.umich.edu          case 0x2:
22047363Sgblack@eecs.umich.edu            if ((opc3 & 0x1) == 0) {
22057372Sgblack@eecs.umich.edu                if (single) {
22067376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmulS>(
22077376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
22087364Sgblack@eecs.umich.edu                } else {
22097376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VmulD>(
22107376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22117364Sgblack@eecs.umich.edu                }
22127371Sgblack@eecs.umich.edu            } else {
22137372Sgblack@eecs.umich.edu                if (single) {
22147376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmulS>(
22157376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
22167371Sgblack@eecs.umich.edu                } else {
22177376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VnmulD>(
22187376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22197371Sgblack@eecs.umich.edu                }
22207363Sgblack@eecs.umich.edu            }
22217363Sgblack@eecs.umich.edu          case 0x3:
22227363Sgblack@eecs.umich.edu            if ((opc3 & 0x1) == 0) {
22237372Sgblack@eecs.umich.edu                if (single) {
22247376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VaddS>(
22257376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
22267367Sgblack@eecs.umich.edu                } else {
22277376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VaddD>(
22287376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22297367Sgblack@eecs.umich.edu                }
22307363Sgblack@eecs.umich.edu            } else {
22317372Sgblack@eecs.umich.edu                if (single) {
22327376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VsubS>(
22337376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
22347368Sgblack@eecs.umich.edu                } else {
22357376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VsubD>(
22367376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22377368Sgblack@eecs.umich.edu                }
22387363Sgblack@eecs.umich.edu            }
22397363Sgblack@eecs.umich.edu          case 0x8:
22407363Sgblack@eecs.umich.edu            if ((opc3 & 0x1) == 0) {
22417372Sgblack@eecs.umich.edu                if (single) {
22427376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VdivS>(
22437376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, false);
22447369Sgblack@eecs.umich.edu                } else {
22457376Sgblack@eecs.umich.edu                    return decodeVfpRegRegRegOp<VdivD>(
22467376Sgblack@eecs.umich.edu                            machInst, vd, vn, vm, true);
22477369Sgblack@eecs.umich.edu                }
22487363Sgblack@eecs.umich.edu            }
22497363Sgblack@eecs.umich.edu            break;
22507363Sgblack@eecs.umich.edu          case 0xb:
22517363Sgblack@eecs.umich.edu            if ((opc3 & 0x1) == 0) {
22527363Sgblack@eecs.umich.edu                const uint32_t baseImm =
22537363Sgblack@eecs.umich.edu                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
22547372Sgblack@eecs.umich.edu                if (single) {
22557363Sgblack@eecs.umich.edu                    uint32_t imm = vfp_modified_imm(baseImm, false);
22567376Sgblack@eecs.umich.edu                    return decodeVfpRegImmOp<VmovImmS>(
22577376Sgblack@eecs.umich.edu                            machInst, vd, imm, false);
22587363Sgblack@eecs.umich.edu                } else {
22597363Sgblack@eecs.umich.edu                    uint64_t imm = vfp_modified_imm(baseImm, true);
22607376Sgblack@eecs.umich.edu                    return decodeVfpRegImmOp<VmovImmD>(
22617376Sgblack@eecs.umich.edu                            machInst, vd, imm, true);
22627363Sgblack@eecs.umich.edu                }
22637363Sgblack@eecs.umich.edu            }
22647363Sgblack@eecs.umich.edu            switch (opc2) {
22657363Sgblack@eecs.umich.edu              case 0x0:
22667363Sgblack@eecs.umich.edu                if (opc3 == 1) {
22677372Sgblack@eecs.umich.edu                    if (single) {
22687376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VmovRegS>(
22697376Sgblack@eecs.umich.edu                                machInst, vd, vm, false);
22707363Sgblack@eecs.umich.edu                    } else {
22717376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VmovRegD>(
22727376Sgblack@eecs.umich.edu                                machInst, vd, vm, true);
22737363Sgblack@eecs.umich.edu                    }
22747363Sgblack@eecs.umich.edu                } else {
22757372Sgblack@eecs.umich.edu                    if (single) {
22767376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VabsS>(
22777376Sgblack@eecs.umich.edu                                machInst, vd, vm, false);
22787366Sgblack@eecs.umich.edu                    } else {
22797376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VabsD>(
22807376Sgblack@eecs.umich.edu                                machInst, vd, vm, true);
22817366Sgblack@eecs.umich.edu                    }
22827363Sgblack@eecs.umich.edu                }
22837363Sgblack@eecs.umich.edu              case 0x1:
22847363Sgblack@eecs.umich.edu                if (opc3 == 1) {
22857372Sgblack@eecs.umich.edu                    if (single) {
22867376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VnegS>(
22877376Sgblack@eecs.umich.edu                                machInst, vd, vm, false);
22887365Sgblack@eecs.umich.edu                    } else {
22897376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VnegD>(
22907376Sgblack@eecs.umich.edu                                machInst, vd, vm, true);
22917365Sgblack@eecs.umich.edu                    }
22927363Sgblack@eecs.umich.edu                } else {
22937372Sgblack@eecs.umich.edu                    if (single) {
22947376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VsqrtS>(
22957376Sgblack@eecs.umich.edu                                machInst, vd, vm, false);
22967369Sgblack@eecs.umich.edu                    } else {
22977376Sgblack@eecs.umich.edu                        return decodeVfpRegRegOp<VsqrtD>(
22987376Sgblack@eecs.umich.edu                                machInst, vd, vm, true);
22997369Sgblack@eecs.umich.edu                    }
23007363Sgblack@eecs.umich.edu                }
23017363Sgblack@eecs.umich.edu              case 0x2:
23027363Sgblack@eecs.umich.edu              case 0x3:
23037398Sgblack@eecs.umich.edu                {
23047398Sgblack@eecs.umich.edu                    const bool toHalf = bits(machInst, 16);
23057398Sgblack@eecs.umich.edu                    const bool top = bits(machInst, 7);
23067398Sgblack@eecs.umich.edu                    if (top) {
23077398Sgblack@eecs.umich.edu                        if (toHalf) {
23087398Sgblack@eecs.umich.edu                            return new VcvtFpSFpHT(machInst, vd, vm);
23097398Sgblack@eecs.umich.edu                        } else {
23107398Sgblack@eecs.umich.edu                            return new VcvtFpHTFpS(machInst, vd, vm);
23117398Sgblack@eecs.umich.edu                        }
23127398Sgblack@eecs.umich.edu                    } else {
23137398Sgblack@eecs.umich.edu                        if (toHalf) {
23147398Sgblack@eecs.umich.edu                            return new VcvtFpSFpHB(machInst, vd, vm);
23157398Sgblack@eecs.umich.edu                        } else {
23167398Sgblack@eecs.umich.edu                            return new VcvtFpHBFpS(machInst, vd, vm);
23177398Sgblack@eecs.umich.edu                        }
23187398Sgblack@eecs.umich.edu                    }
23197398Sgblack@eecs.umich.edu                }
23207363Sgblack@eecs.umich.edu              case 0x4:
23217377Sgblack@eecs.umich.edu                if (single) {
23227389Sgblack@eecs.umich.edu                    if (e) {
23237389Sgblack@eecs.umich.edu                        return new VcmpeS(machInst, vd, vm);
23247389Sgblack@eecs.umich.edu                    } else {
23257389Sgblack@eecs.umich.edu                        return new VcmpS(machInst, vd, vm);
23267389Sgblack@eecs.umich.edu                    }
23277377Sgblack@eecs.umich.edu                } else {
23287389Sgblack@eecs.umich.edu                    if (e) {
23297389Sgblack@eecs.umich.edu                        return new VcmpeD(machInst, vd, vm);
23307389Sgblack@eecs.umich.edu                    } else {
23317389Sgblack@eecs.umich.edu                        return new VcmpD(machInst, vd, vm);
23327389Sgblack@eecs.umich.edu                    }
23337377Sgblack@eecs.umich.edu                }
23347363Sgblack@eecs.umich.edu              case 0x5:
23357377Sgblack@eecs.umich.edu                if (single) {
23367389Sgblack@eecs.umich.edu                    if (e) {
23377389Sgblack@eecs.umich.edu                        return new VcmpeZeroS(machInst, vd, 0);
23387389Sgblack@eecs.umich.edu                    } else {
23397389Sgblack@eecs.umich.edu                        return new VcmpZeroS(machInst, vd, 0);
23407389Sgblack@eecs.umich.edu                    }
23417377Sgblack@eecs.umich.edu                } else {
23427389Sgblack@eecs.umich.edu                    if (e) {
23437389Sgblack@eecs.umich.edu                        return new VcmpeZeroD(machInst, vd, 0);
23447389Sgblack@eecs.umich.edu                    } else {
23457389Sgblack@eecs.umich.edu                        return new VcmpZeroD(machInst, vd, 0);
23467389Sgblack@eecs.umich.edu                    }
23477377Sgblack@eecs.umich.edu                }
23487363Sgblack@eecs.umich.edu              case 0x7:
23497363Sgblack@eecs.umich.edu                if (opc3 == 0x3) {
23507374Sgblack@eecs.umich.edu                    if (single) {
23518270SAli.Saidi@ARM.com                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
23528270SAli.Saidi@ARM.com                                (bits(machInst, 15, 12) << 1));
23537374Sgblack@eecs.umich.edu                        return new VcvtFpSFpD(machInst, vd, vm);
23547374Sgblack@eecs.umich.edu                    } else {
23557374Sgblack@eecs.umich.edu                        vd = (IntRegIndex)(bits(machInst, 22) |
23567374Sgblack@eecs.umich.edu                                (bits(machInst, 15, 12) << 1));
23577374Sgblack@eecs.umich.edu                        return new VcvtFpDFpS(machInst, vd, vm);
23587374Sgblack@eecs.umich.edu                    }
23597363Sgblack@eecs.umich.edu                }
23607363Sgblack@eecs.umich.edu                break;
23617363Sgblack@eecs.umich.edu              case 0x8:
23627373Sgblack@eecs.umich.edu                if (bits(machInst, 7) == 0) {
23637373Sgblack@eecs.umich.edu                    if (single) {
23647373Sgblack@eecs.umich.edu                        return new VcvtUIntFpS(machInst, vd, vm);
23657373Sgblack@eecs.umich.edu                    } else {
23667373Sgblack@eecs.umich.edu                        vm = (IntRegIndex)(bits(machInst, 5) |
23677373Sgblack@eecs.umich.edu                                (bits(machInst, 3, 0) << 1));
23687373Sgblack@eecs.umich.edu                        return new VcvtUIntFpD(machInst, vd, vm);
23697373Sgblack@eecs.umich.edu                    }
23707373Sgblack@eecs.umich.edu                } else {
23717373Sgblack@eecs.umich.edu                    if (single) {
23727373Sgblack@eecs.umich.edu                        return new VcvtSIntFpS(machInst, vd, vm);
23737373Sgblack@eecs.umich.edu                    } else {
23747373Sgblack@eecs.umich.edu                        vm = (IntRegIndex)(bits(machInst, 5) |
23757373Sgblack@eecs.umich.edu                                (bits(machInst, 3, 0) << 1));
23767373Sgblack@eecs.umich.edu                        return new VcvtSIntFpD(machInst, vd, vm);
23777373Sgblack@eecs.umich.edu                    }
23787373Sgblack@eecs.umich.edu                }
23797363Sgblack@eecs.umich.edu              case 0xa:
23807379Sgblack@eecs.umich.edu                {
23817379Sgblack@eecs.umich.edu                    const bool half = (bits(machInst, 7) == 0);
23827379Sgblack@eecs.umich.edu                    const uint32_t imm = bits(machInst, 5) |
23837379Sgblack@eecs.umich.edu                                         (bits(machInst, 3, 0) << 1);
23847379Sgblack@eecs.umich.edu                    const uint32_t size =
23857379Sgblack@eecs.umich.edu                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
23867379Sgblack@eecs.umich.edu                    if (single) {
23877379Sgblack@eecs.umich.edu                        if (half) {
23887379Sgblack@eecs.umich.edu                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
23897379Sgblack@eecs.umich.edu                        } else {
23907379Sgblack@eecs.umich.edu                            return new VcvtSFixedFpS(machInst, vd, vd, size);
23917379Sgblack@eecs.umich.edu                        }
23927379Sgblack@eecs.umich.edu                    } else {
23937379Sgblack@eecs.umich.edu                        if (half) {
23947379Sgblack@eecs.umich.edu                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
23957379Sgblack@eecs.umich.edu                        } else {
23967379Sgblack@eecs.umich.edu                            return new VcvtSFixedFpD(machInst, vd, vd, size);
23977379Sgblack@eecs.umich.edu                        }
23987379Sgblack@eecs.umich.edu                    }
23997379Sgblack@eecs.umich.edu                }
24007363Sgblack@eecs.umich.edu              case 0xb:
24017379Sgblack@eecs.umich.edu                {
24027379Sgblack@eecs.umich.edu                    const bool half = (bits(machInst, 7) == 0);
24037379Sgblack@eecs.umich.edu                    const uint32_t imm = bits(machInst, 5) |
24047379Sgblack@eecs.umich.edu                                         (bits(machInst, 3, 0) << 1);
24057379Sgblack@eecs.umich.edu                    const uint32_t size =
24067379Sgblack@eecs.umich.edu                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
24077379Sgblack@eecs.umich.edu                    if (single) {
24087379Sgblack@eecs.umich.edu                        if (half) {
24097379Sgblack@eecs.umich.edu                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
24107379Sgblack@eecs.umich.edu                        } else {
24117379Sgblack@eecs.umich.edu                            return new VcvtUFixedFpS(machInst, vd, vd, size);
24127379Sgblack@eecs.umich.edu                        }
24137379Sgblack@eecs.umich.edu                    } else {
24147379Sgblack@eecs.umich.edu                        if (half) {
24157379Sgblack@eecs.umich.edu                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
24167379Sgblack@eecs.umich.edu                        } else {
24177379Sgblack@eecs.umich.edu                            return new VcvtUFixedFpD(machInst, vd, vd, size);
24187379Sgblack@eecs.umich.edu                        }
24197379Sgblack@eecs.umich.edu                    }
24207379Sgblack@eecs.umich.edu                }
24217363Sgblack@eecs.umich.edu              case 0xc:
24227380Sgblack@eecs.umich.edu                if (bits(machInst, 7) == 0) {
24237380Sgblack@eecs.umich.edu                    if (single) {
24247380Sgblack@eecs.umich.edu                        return new VcvtFpUIntSR(machInst, vd, vm);
24257380Sgblack@eecs.umich.edu                    } else {
24267380Sgblack@eecs.umich.edu                        vd = (IntRegIndex)(bits(machInst, 22) |
24277380Sgblack@eecs.umich.edu                                (bits(machInst, 15, 12) << 1));
24287380Sgblack@eecs.umich.edu                        return new VcvtFpUIntDR(machInst, vd, vm);
24297380Sgblack@eecs.umich.edu                    }
24307373Sgblack@eecs.umich.edu                } else {
24317380Sgblack@eecs.umich.edu                    if (single) {
24327380Sgblack@eecs.umich.edu                        return new VcvtFpUIntS(machInst, vd, vm);
24337380Sgblack@eecs.umich.edu                    } else {
24347380Sgblack@eecs.umich.edu                        vd = (IntRegIndex)(bits(machInst, 22) |
24357380Sgblack@eecs.umich.edu                                (bits(machInst, 15, 12) << 1));
24367380Sgblack@eecs.umich.edu                        return new VcvtFpUIntD(machInst, vd, vm);
24377380Sgblack@eecs.umich.edu                    }
24387373Sgblack@eecs.umich.edu                }
24397363Sgblack@eecs.umich.edu              case 0xd:
24407380Sgblack@eecs.umich.edu                if (bits(machInst, 7) == 0) {
24417380Sgblack@eecs.umich.edu                    if (single) {
24427380Sgblack@eecs.umich.edu                        return new VcvtFpSIntSR(machInst, vd, vm);
24437380Sgblack@eecs.umich.edu                    } else {
24447380Sgblack@eecs.umich.edu                        vd = (IntRegIndex)(bits(machInst, 22) |
24457380Sgblack@eecs.umich.edu                                (bits(machInst, 15, 12) << 1));
24467380Sgblack@eecs.umich.edu                        return new VcvtFpSIntDR(machInst, vd, vm);
24477380Sgblack@eecs.umich.edu                    }
24487373Sgblack@eecs.umich.edu                } else {
24497380Sgblack@eecs.umich.edu                    if (single) {
24507380Sgblack@eecs.umich.edu                        return new VcvtFpSIntS(machInst, vd, vm);
24517380Sgblack@eecs.umich.edu                    } else {
24527380Sgblack@eecs.umich.edu                        vd = (IntRegIndex)(bits(machInst, 22) |
24537380Sgblack@eecs.umich.edu                                (bits(machInst, 15, 12) << 1));
24547380Sgblack@eecs.umich.edu                        return new VcvtFpSIntD(machInst, vd, vm);
24557380Sgblack@eecs.umich.edu                    }
24567373Sgblack@eecs.umich.edu                }
24577363Sgblack@eecs.umich.edu              case 0xe:
24587379Sgblack@eecs.umich.edu                {
24597379Sgblack@eecs.umich.edu                    const bool half = (bits(machInst, 7) == 0);
24607379Sgblack@eecs.umich.edu                    const uint32_t imm = bits(machInst, 5) |
24617379Sgblack@eecs.umich.edu                                         (bits(machInst, 3, 0) << 1);
24627379Sgblack@eecs.umich.edu                    const uint32_t size =
24637379Sgblack@eecs.umich.edu                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
24647379Sgblack@eecs.umich.edu                    if (single) {
24657379Sgblack@eecs.umich.edu                        if (half) {
24667379Sgblack@eecs.umich.edu                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
24677379Sgblack@eecs.umich.edu                        } else {
24687379Sgblack@eecs.umich.edu                            return new VcvtFpSFixedS(machInst, vd, vd, size);
24697379Sgblack@eecs.umich.edu                        }
24707379Sgblack@eecs.umich.edu                    } else {
24717379Sgblack@eecs.umich.edu                        if (half) {
24727379Sgblack@eecs.umich.edu                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
24737379Sgblack@eecs.umich.edu                        } else {
24747379Sgblack@eecs.umich.edu                            return new VcvtFpSFixedD(machInst, vd, vd, size);
24757379Sgblack@eecs.umich.edu                        }
24767379Sgblack@eecs.umich.edu                    }
24777379Sgblack@eecs.umich.edu                }
24787363Sgblack@eecs.umich.edu              case 0xf:
24797379Sgblack@eecs.umich.edu                {
24807379Sgblack@eecs.umich.edu                    const bool half = (bits(machInst, 7) == 0);
24817379Sgblack@eecs.umich.edu                    const uint32_t imm = bits(machInst, 5) |
24827379Sgblack@eecs.umich.edu                                         (bits(machInst, 3, 0) << 1);
24837379Sgblack@eecs.umich.edu                    const uint32_t size =
24847379Sgblack@eecs.umich.edu                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
24857379Sgblack@eecs.umich.edu                    if (single) {
24867379Sgblack@eecs.umich.edu                        if (half) {
24877379Sgblack@eecs.umich.edu                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
24887379Sgblack@eecs.umich.edu                        } else {
24897379Sgblack@eecs.umich.edu                            return new VcvtFpUFixedS(machInst, vd, vd, size);
24907379Sgblack@eecs.umich.edu                        }
24917379Sgblack@eecs.umich.edu                    } else {
24927379Sgblack@eecs.umich.edu                        if (half) {
24937379Sgblack@eecs.umich.edu                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
24947379Sgblack@eecs.umich.edu                        } else {
24957379Sgblack@eecs.umich.edu                            return new VcvtFpUFixedD(machInst, vd, vd, size);
24967379Sgblack@eecs.umich.edu                        }
24977379Sgblack@eecs.umich.edu                    }
24987379Sgblack@eecs.umich.edu                }
24997363Sgblack@eecs.umich.edu            }
25007363Sgblack@eecs.umich.edu            break;
25017363Sgblack@eecs.umich.edu        }
25027363Sgblack@eecs.umich.edu        return new Unknown(machInst);
25037363Sgblack@eecs.umich.edu    }
25047363Sgblack@eecs.umich.edu    '''
25057363Sgblack@eecs.umich.edu}};
25067363Sgblack@eecs.umich.edu
25077363Sgblack@eecs.umich.edudef format VfpData() {{
25087363Sgblack@eecs.umich.edu    decode_block = '''
25097363Sgblack@eecs.umich.edu    return decodeVfpData(machInst);
25107363Sgblack@eecs.umich.edu    '''
25117363Sgblack@eecs.umich.edu}};
2512