fp.isa revision 8303
19814Sandreas.hansson@arm.com// -*- mode:c++ -*-
22292SN/A
310333Smitch.hayenga@arm.com// Copyright (c) 2010 ARM Limited
410239Sbinhpham@cs.rutgers.edu// All rights reserved
57597Sminkyu.jeong@arm.com//
67597Sminkyu.jeong@arm.com// The license below extends only to copyright in the software and shall
77597Sminkyu.jeong@arm.com// not be construed as granting a license to any other intellectual
87597Sminkyu.jeong@arm.com// property including but not limited to intellectual property relating
97597Sminkyu.jeong@arm.com// to a hardware implementation of the functionality of the software
107597Sminkyu.jeong@arm.com// licensed hereunder.  You may use the software subject to the license
117597Sminkyu.jeong@arm.com// terms below provided that you ensure that this notice is replicated
127597Sminkyu.jeong@arm.com// unmodified and in its entirety in all distributions of the software,
137597Sminkyu.jeong@arm.com// modified or unmodified, in source code or in binary form.
147597Sminkyu.jeong@arm.com//
157597Sminkyu.jeong@arm.com// Copyright (c) 2007-2008 The Florida State University
162292SN/A// All rights reserved.
172292SN/A//
182292SN/A// Redistribution and use in source and binary forms, with or without
192292SN/A// modification, are permitted provided that the following conditions are
202292SN/A// met: redistributions of source code must retain the above copyright
212292SN/A// notice, this list of conditions and the following disclaimer;
222292SN/A// redistributions in binary form must reproduce the above copyright
232292SN/A// notice, this list of conditions and the following disclaimer in the
242292SN/A// documentation and/or other materials provided with the distribution;
252292SN/A// neither the name of the copyright holders nor the names of its
262292SN/A// contributors may be used to endorse or promote products derived from
272292SN/A// this software without specific prior written permission.
282292SN/A//
292292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382292SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392292SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402292SN/A//
412689Sktlim@umich.edu// Authors: Stephen Hines
422689Sktlim@umich.edu
432689Sktlim@umich.edu////////////////////////////////////////////////////////////////////
442292SN/A//
452292SN/A// Floating Point operate instructions
469944Smatt.horsnell@ARM.com//
479944Smatt.horsnell@ARM.com
489944Smatt.horsnell@ARM.comoutput header {{
498591Sgblack@eecs.umich.edu
503326Sktlim@umich.edu    template<template <typename T> class Base>
518229Snate@binkert.org    StaticInstPtr
526658Snate@binkert.org    newNeonMemInst(const unsigned size,
538887Sgeoffrey.blake@arm.com                   const ExtMachInst &machInst,
542907Sktlim@umich.edu                   const RegIndex dest, const RegIndex ra,
552292SN/A                   const uint32_t imm, const unsigned extraMemFlags)
568232Snate@binkert.org    {
578232Snate@binkert.org        switch (size) {
588232Snate@binkert.org          case 0:
599527SMatt.Horsnell@arm.com            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
602722Sktlim@umich.edu          case 1:
612669Sktlim@umich.edu            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
622292SN/A          case 2:
632669Sktlim@umich.edu            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
642678Sktlim@umich.edu          case 3:
652678Sktlim@umich.edu            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
668581Ssteve.reinhardt@amd.com          default:
678581Ssteve.reinhardt@amd.com            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
682292SN/A        }
692292SN/A    }
702292SN/A
712669Sktlim@umich.edu    template<template <typename T> class Base>
722292SN/A    StaticInstPtr
732678Sktlim@umich.edu    newNeonMixInst(const unsigned size,
742292SN/A                   const ExtMachInst &machInst,
759444SAndreas.Sandberg@ARM.com                   const RegIndex dest, const RegIndex op1,
769444SAndreas.Sandberg@ARM.com                   const uint32_t step)
779444SAndreas.Sandberg@ARM.com    {
784319Sktlim@umich.edu        switch (size) {
794319Sktlim@umich.edu          case 0:
804319Sktlim@umich.edu            return new Base<uint8_t>(machInst, dest, op1, step);
814319Sktlim@umich.edu          case 1:
824319Sktlim@umich.edu            return new Base<uint16_t>(machInst, dest, op1, step);
832678Sktlim@umich.edu          case 2:
842678Sktlim@umich.edu            return new Base<uint32_t>(machInst, dest, op1, step);
852292SN/A          case 3:
862678Sktlim@umich.edu            return new Base<uint64_t>(machInst, dest, op1, step);
872678Sktlim@umich.edu          default:
885336Shines@cs.fsu.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
892678Sktlim@umich.edu        }
904873Sstever@eecs.umich.edu    }
912678Sktlim@umich.edu
922292SN/A}};
932678Sktlim@umich.edu
942678Sktlim@umich.edulet {{
952678Sktlim@umich.edu    header_output = '''
962678Sktlim@umich.edu    StaticInstPtr
972678Sktlim@umich.edu    decodeNeonMem(ExtMachInst machInst);
982678Sktlim@umich.edu
997852SMatt.Horsnell@arm.com    StaticInstPtr
1007852SMatt.Horsnell@arm.com    decodeNeonData(ExtMachInst machInst);
1012344SN/A    '''
10210333Smitch.hayenga@arm.com
10310333Smitch.hayenga@arm.com    decoder_output = '''
10410333Smitch.hayenga@arm.com    StaticInstPtr
10510333Smitch.hayenga@arm.com    decodeNeonMem(ExtMachInst machInst)
10610333Smitch.hayenga@arm.com    {
10710333Smitch.hayenga@arm.com        const uint32_t b = bits(machInst, 11, 8);
10810333Smitch.hayenga@arm.com        const bool single = bits(machInst, 23);
10910333Smitch.hayenga@arm.com        const bool singleAll = single && (bits(b, 3, 2) == 3);
11010333Smitch.hayenga@arm.com        const bool load = bits(machInst, 21);
11110333Smitch.hayenga@arm.com
1122678Sktlim@umich.edu        unsigned width = 0;
1136974Stjones1@inf.ed.ac.uk
1146974Stjones1@inf.ed.ac.uk        if (single) {
1156974Stjones1@inf.ed.ac.uk            width = bits(b, 1, 0) + 1;
1166974Stjones1@inf.ed.ac.uk        } else {
1176974Stjones1@inf.ed.ac.uk            switch (bits(b, 3, 1)) {
1186974Stjones1@inf.ed.ac.uk              case 0x0: width = 4;
1196974Stjones1@inf.ed.ac.uk                break;
1209444SAndreas.Sandberg@ARM.com              case 0x1: width = (b & 0x1) ? 2 : 1;
12110327Smitch.hayenga@arm.com                break;
1222678Sktlim@umich.edu              case 0x2: width = 3;
1236974Stjones1@inf.ed.ac.uk                break;
1246974Stjones1@inf.ed.ac.uk              case 0x3: width = 1;
1256974Stjones1@inf.ed.ac.uk                break;
1266974Stjones1@inf.ed.ac.uk              case 0x4: width = 2;
1276974Stjones1@inf.ed.ac.uk                break;
1286974Stjones1@inf.ed.ac.uk              case 0x5:
1292678Sktlim@umich.edu                if ((b & 0x1) == 0) {
1302678Sktlim@umich.edu                    width = 1;
1312678Sktlim@umich.edu                    break;
1322678Sktlim@umich.edu                }
1332678Sktlim@umich.edu                // Fall through on purpose.
1342344SN/A              default:
1352307SN/A                return new Unknown(machInst);
1366974Stjones1@inf.ed.ac.uk            }
1376974Stjones1@inf.ed.ac.uk        }
1386974Stjones1@inf.ed.ac.uk        assert(width > 0 && width <= 4);
1396974Stjones1@inf.ed.ac.uk
14010020Smatt.horsnell@ARM.com        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
14110020Smatt.horsnell@ARM.com        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
14210023Smatt.horsnell@ARM.com        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
14310023Smatt.horsnell@ARM.com                                                 bits(machInst, 22) << 4);
1442678Sktlim@umich.edu        const uint32_t type = bits(machInst, 11, 8);
1454032Sktlim@umich.edu        uint32_t size = 0;
1462678Sktlim@umich.edu        uint32_t align = TLB::MustBeOne;
1472292SN/A        unsigned inc = 1;
1482292SN/A        unsigned regs = 1;
1492292SN/A        unsigned lane = 0;
1502292SN/A        if (single) {
1518545Ssaidi@eecs.umich.edu            if (singleAll) {
15210333Smitch.hayenga@arm.com                size = bits(machInst, 7, 6);
1532292SN/A                bool t = bits(machInst, 5);
1542292SN/A                unsigned eBytes = (1 << size);
1552292SN/A                align = (eBytes - 1) | TLB::AllowUnaligned;
1562292SN/A                if (width == 1) {
1572292SN/A                    regs = t ? 2 : 1;
1585529Snate@binkert.org                    inc = 1;
1595529Snate@binkert.org                } else {
1605529Snate@binkert.org                    regs = width;
1612292SN/A                    inc = t ? 2 : 1;
1624329Sktlim@umich.edu                }
1634329Sktlim@umich.edu                switch (width) {
1644329Sktlim@umich.edu                  case 1:
1652907Sktlim@umich.edu                  case 2:
1662907Sktlim@umich.edu                    if (bits(machInst, 4))
1672292SN/A                        align = width * eBytes - 1;
1682292SN/A                    break;
16910175SMitch.Hayenga@ARM.com                  case 3:
17010175SMitch.Hayenga@ARM.com                    break;
1712329SN/A                  case 4:
1722329SN/A                    if (size == 3) {
1732329SN/A                        if (bits(machInst, 4) == 0)
1742292SN/A                            return new Unknown(machInst);
1759936SFaissal.Sleiman@arm.com                        size = 2;
1769936SFaissal.Sleiman@arm.com                        align = 0xf;
1779936SFaissal.Sleiman@arm.com                    } else if (size == 2) {
1789936SFaissal.Sleiman@arm.com                        if (bits(machInst, 4))
1792292SN/A                            align = 7;
1802292SN/A                    } else {
1812292SN/A                        if (bits(machInst, 4))
1828199SAli.Saidi@ARM.com                            align = 4 * eBytes - 1;
1838199SAli.Saidi@ARM.com                    }
1849444SAndreas.Sandberg@ARM.com                    break;
1859444SAndreas.Sandberg@ARM.com                }
1869444SAndreas.Sandberg@ARM.com            } else {
1879444SAndreas.Sandberg@ARM.com                size = bits(machInst, 11, 10);
1889444SAndreas.Sandberg@ARM.com                unsigned eBytes = (1 << size);
1899444SAndreas.Sandberg@ARM.com                align = (eBytes - 1) | TLB::AllowUnaligned;
1909444SAndreas.Sandberg@ARM.com                regs = width;
1919444SAndreas.Sandberg@ARM.com                unsigned indexAlign = bits(machInst, 7, 4);
1929444SAndreas.Sandberg@ARM.com                // If width is 1, inc is always 1. That's overridden later.
1939444SAndreas.Sandberg@ARM.com                switch (size) {
1949444SAndreas.Sandberg@ARM.com                  case 0:
1959444SAndreas.Sandberg@ARM.com                    inc = 1;
1968199SAli.Saidi@ARM.com                    lane = bits(indexAlign, 3, 1);
1972292SN/A                    break;
1982292SN/A                  case 1:
1992292SN/A                    inc = bits(indexAlign, 1) ? 2 : 1;
2002292SN/A                    lane = bits(indexAlign, 3, 2);
2012292SN/A                    break;
2022292SN/A                  case 2:
2033492Sktlim@umich.edu                    inc = bits(indexAlign, 2) ? 2 : 1;
2042329SN/A                    lane = bits(indexAlign, 3);
2052292SN/A                    break;
2069444SAndreas.Sandberg@ARM.com                }
2079444SAndreas.Sandberg@ARM.com                // Override inc for width of 1.
2089814Sandreas.hansson@arm.com                if (width == 1) {
2092292SN/A                    inc = 1;
2102292SN/A                }
2112292SN/A                switch (width) {
2122292SN/A                  case 1:
2132292SN/A                    switch (size) {
2142292SN/A                      case 0:
2152292SN/A                        break;
2162292SN/A                      case 1:
2172292SN/A                        if (bits(indexAlign, 0))
2188247Snate@binkert.org                            align = 1;
2192292SN/A                        break;
2202292SN/A                      case 2:
2212292SN/A                        if (bits(indexAlign, 1, 0))
2222292SN/A                            align = 3;
2232292SN/A                        break;
2242727Sktlim@umich.edu                    }
2252727Sktlim@umich.edu                    break;
2262727Sktlim@umich.edu                  case 2:
2272727Sktlim@umich.edu                    if (bits(indexAlign, 0))
2282727Sktlim@umich.edu                        align = (2 * eBytes) - 1;
2292727Sktlim@umich.edu                    break;
2302727Sktlim@umich.edu                  case 3:
2312727Sktlim@umich.edu                    break;
2322727Sktlim@umich.edu                  case 4:
2332727Sktlim@umich.edu                    switch (size) {
2342727Sktlim@umich.edu                      case 0:
2352727Sktlim@umich.edu                      case 1:
2362727Sktlim@umich.edu                        if (bits(indexAlign, 0))
2372727Sktlim@umich.edu                            align = (4 * eBytes) - 1;
2382727Sktlim@umich.edu                        break;
2392727Sktlim@umich.edu                      case 2:
2402727Sktlim@umich.edu                        if (bits(indexAlign, 0))
2412727Sktlim@umich.edu                            align = (4 << bits(indexAlign, 1, 0)) - 1;
2422361SN/A                        break;
2432361SN/A                    }
2442361SN/A                    break;
2452361SN/A                }
2462727Sktlim@umich.edu            }
2472727Sktlim@umich.edu            if (size == 0x3) {
2482727Sktlim@umich.edu                return new Unknown(machInst);
2492727Sktlim@umich.edu            }
2502727Sktlim@umich.edu        } else {
2512727Sktlim@umich.edu            size = bits(machInst, 7, 6);
2522727Sktlim@umich.edu            align = bits(machInst, 5, 4);
2532727Sktlim@umich.edu            if (align == 0) {
2542727Sktlim@umich.edu                // @align wasn't specified, so alignment can be turned off.
2552727Sktlim@umich.edu                align = ((1 << size) - 1) | TLB::AllowUnaligned;
2562727Sktlim@umich.edu            } else {
2572727Sktlim@umich.edu                align = ((4 << align) - 1);
2582727Sktlim@umich.edu            }
2592727Sktlim@umich.edu            switch (width) {
2602727Sktlim@umich.edu              case 1:
2612727Sktlim@umich.edu                switch (type) {
2622727Sktlim@umich.edu                  case 0x7: regs = 1;
2632727Sktlim@umich.edu                    break;
2642727Sktlim@umich.edu                  case 0xa: regs = 2;
2652727Sktlim@umich.edu                    break;
2662727Sktlim@umich.edu                  case 0x6: regs = 3;
2672727Sktlim@umich.edu                    break;
2682727Sktlim@umich.edu                  case 0x2: regs = 4;
2698922Swilliam.wang@arm.com                    break;
2704329Sktlim@umich.edu                  default:
2714329Sktlim@umich.edu                    return new Unknown(machInst);
2724329Sktlim@umich.edu                }
2734329Sktlim@umich.edu                break;
2744329Sktlim@umich.edu              case 2:
2754329Sktlim@umich.edu                // Regs doesn't behave exactly as it does in the manual
2762292SN/A                // because they loop over regs registers twice and we break
2772292SN/A                // it down in the macroop.
2782292SN/A                switch (type) {
2792292SN/A                  case 0x8: regs = 2; inc = 1;
2802292SN/A                    break;
2812292SN/A                  case 0x9: regs = 2; inc = 2;
2822292SN/A                    break;
2832292SN/A                  case 0x3: regs = 4; inc = 2;
2842292SN/A                    break;
2852292SN/A                  default:
2862292SN/A                    return new Unknown(machInst);
2872292SN/A                }
2882292SN/A                break;
2892292SN/A              case 3:
2909444SAndreas.Sandberg@ARM.com                regs = 3;
2912307SN/A                switch (type) {
2929444SAndreas.Sandberg@ARM.com                  case 0x4: inc = 1;
2932367SN/A                    break;
2942307SN/A                  case 0x5: inc = 2;;
2952329SN/A                    break;
2969444SAndreas.Sandberg@ARM.com                  default:
2972307SN/A                    return new Unknown(machInst);
2982307SN/A                }
2992307SN/A                break;
3002307SN/A              case 4:
3012307SN/A                regs = 4;
3022307SN/A                switch (type) {
3039444SAndreas.Sandberg@ARM.com                  case 0: inc = 1;
3042307SN/A                    break;
3052307SN/A                  case 1: inc = 2;
3062307SN/A                    break;
3072307SN/A                  default:
3082292SN/A                    return new Unknown(machInst);
3092292SN/A                }
3102329SN/A                break;
3112329SN/A            }
3122292SN/A        }
3132329SN/A
3142329SN/A        if (load) {
3152292SN/A            // Load instructions.
3162292SN/A            if (single) {
3172292SN/A                return new VldSingle(machInst, singleAll, width, rn, vd,
3182292SN/A                                     regs, inc, size, align, rm, lane);
3192292SN/A            } else {
3202329SN/A                return new VldMult(machInst, width, rn, vd,
3212292SN/A                                   regs, inc, size, align, rm);
3222292SN/A            }
3239936SFaissal.Sleiman@arm.com        } else {
3242292SN/A            // Store instructions.
3252292SN/A            if (single) {
3262292SN/A                if (singleAll) {
3272292SN/A                    return new Unknown(machInst);
3282292SN/A                } else {
3292292SN/A                    return new VstSingle(machInst, false, width, rn, vd,
3302329SN/A                                         regs, inc, size, align, rm, lane);
3312329SN/A                }
3322329SN/A            } else {
3332292SN/A                return new VstMult(machInst, width, rn, vd,
3342292SN/A                                   regs, inc, size, align, rm);
3352292SN/A            }
3362292SN/A        }
3372292SN/A        return new Unknown(machInst);
3382329SN/A    }
3392292SN/A    '''
3409936SFaissal.Sleiman@arm.com
3419936SFaissal.Sleiman@arm.com    decoder_output += '''
3422292SN/A    static StaticInstPtr
3432292SN/A    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
3442292SN/A    {
3452292SN/A        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
3462292SN/A        const uint32_t a = bits(machInst, 11, 8);
3472292SN/A        const bool b = bits(machInst, 4);
3482292SN/A        const uint32_t c = bits(machInst, 21, 20);
3492292SN/A        const IntRegIndex vd =
3502292SN/A            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
3512292SN/A                               (bits(machInst, 22) << 4)));
3522292SN/A        const IntRegIndex vn =
3532292SN/A            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
3542292SN/A                               (bits(machInst, 7) << 4)));
3552292SN/A        const IntRegIndex vm =
3562292SN/A            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
3572292SN/A                               (bits(machInst, 5) << 4)));
3582292SN/A        const unsigned size = bits(machInst, 21, 20);
3592292SN/A        const bool q = bits(machInst, 6);
3602292SN/A        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
3612292SN/A            return new Unknown(machInst);
3622292SN/A        switch (a) {
3632292SN/A          case 0x0:
3642292SN/A            if (b) {
3652329SN/A                if (u) {
3662329SN/A                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3672292SN/A                            q, size, machInst, vd, vn, vm);
3687720Sgblack@eecs.umich.edu                } else {
3697720Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
3702292SN/A                            q, size, machInst, vd, vn, vm);
3712292SN/A                }
3722292SN/A            } else {
3732292SN/A                if (size == 3)
3742292SN/A                    return new Unknown(machInst);
3752292SN/A                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
3762292SN/A                        q, u, size, machInst, vd, vn, vm);
3772292SN/A            }
3782292SN/A          case 0x1:
3792292SN/A            if (!b) {
3802292SN/A                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
3812292SN/A                        q, u, size, machInst, vd, vn, vm);
3822292SN/A            } else {
3832292SN/A                if (u) {
3842292SN/A                    switch (c) {
3852292SN/A                      case 0:
3862292SN/A                        if (q) {
3872292SN/A                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
3882292SN/A                        } else {
3892292SN/A                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
3902292SN/A                        }
3912292SN/A                      case 1:
3922292SN/A                        if (q) {
3932292SN/A                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3947720Sgblack@eecs.umich.edu                        } else {
3957720Sgblack@eecs.umich.edu                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
3962292SN/A                        }
3972292SN/A                      case 2:
3982292SN/A                        if (q) {
3992292SN/A                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
4002292SN/A                        } else {
4012292SN/A                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
4022292SN/A                        }
4032292SN/A                      case 3:
4042292SN/A                        if (q) {
4052292SN/A                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
4062292SN/A                        } else {
4072292SN/A                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
4082292SN/A                        }
4092292SN/A                    }
4102292SN/A                } else {
4112292SN/A                    switch (c) {
4122292SN/A                      case 0:
4132292SN/A                        if (q) {
4142292SN/A                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
4152292SN/A                        } else {
4162292SN/A                            return new VandD<uint64_t>(machInst, vd, vn, vm);
4172292SN/A                        }
4182292SN/A                      case 1:
4192292SN/A                        if (q) {
42010239Sbinhpham@cs.rutgers.edu                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
4212292SN/A                        } else {
42210239Sbinhpham@cs.rutgers.edu                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
42310239Sbinhpham@cs.rutgers.edu                        }
42410239Sbinhpham@cs.rutgers.edu                      case 2:
42510239Sbinhpham@cs.rutgers.edu                        if (vn == vm) {
42610239Sbinhpham@cs.rutgers.edu                            if (q) {
4272292SN/A                                return new VmovQ<uint64_t>(
42810239Sbinhpham@cs.rutgers.edu                                        machInst, vd, vn, vm);
42910239Sbinhpham@cs.rutgers.edu                            } else {
43010239Sbinhpham@cs.rutgers.edu                                return new VmovD<uint64_t>(
43110239Sbinhpham@cs.rutgers.edu                                        machInst, vd, vn, vm);
43210239Sbinhpham@cs.rutgers.edu                            }
43310239Sbinhpham@cs.rutgers.edu                        } else {
43410239Sbinhpham@cs.rutgers.edu                            if (q) {
43510239Sbinhpham@cs.rutgers.edu                                return new VorrQ<uint64_t>(
43610239Sbinhpham@cs.rutgers.edu                                        machInst, vd, vn, vm);
43710239Sbinhpham@cs.rutgers.edu                            } else {
4382292SN/A                                return new VorrD<uint64_t>(
4392292SN/A                                        machInst, vd, vn, vm);
4408545Ssaidi@eecs.umich.edu                            }
4418545Ssaidi@eecs.umich.edu                        }
4428545Ssaidi@eecs.umich.edu                      case 3:
4438545Ssaidi@eecs.umich.edu                        if (q) {
44410030SAli.Saidi@ARM.com                            return new VornQ<uint64_t>(
4458545Ssaidi@eecs.umich.edu                                    machInst, vd, vn, vm);
4469383SAli.Saidi@ARM.com                        } else {
4479383SAli.Saidi@ARM.com                            return new VornD<uint64_t>(
4489383SAli.Saidi@ARM.com                                    machInst, vd, vn, vm);
4499383SAli.Saidi@ARM.com                        }
45010030SAli.Saidi@ARM.com                    }
4519383SAli.Saidi@ARM.com                }
4529383SAli.Saidi@ARM.com            }
4539383SAli.Saidi@ARM.com          case 0x2:
4549383SAli.Saidi@ARM.com            if (b) {
4559383SAli.Saidi@ARM.com                if (u) {
4569383SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
4579383SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
45810030SAli.Saidi@ARM.com                } else {
45910030SAli.Saidi@ARM.com                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
46010030SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
46110030SAli.Saidi@ARM.com                }
46210030SAli.Saidi@ARM.com            } else {
46310030SAli.Saidi@ARM.com                if (size == 3)
46410030SAli.Saidi@ARM.com                    return new Unknown(machInst);
46510030SAli.Saidi@ARM.com                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
46610030SAli.Saidi@ARM.com                        q, u, size, machInst, vd, vn, vm);
46710030SAli.Saidi@ARM.com            }
46810030SAli.Saidi@ARM.com          case 0x3:
4698545Ssaidi@eecs.umich.edu            if (b) {
4708545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
4718545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
47210030SAli.Saidi@ARM.com            } else {
4738545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
4748545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
47510149Smarco.elver@ed.ac.uk            }
47610149Smarco.elver@ed.ac.uk          case 0x4:
4778545Ssaidi@eecs.umich.edu            if (b) {
4788545Ssaidi@eecs.umich.edu                if (u) {
4798545Ssaidi@eecs.umich.edu                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
4809046SAli.Saidi@ARM.com                            q, size, machInst, vd, vm, vn);
4818545Ssaidi@eecs.umich.edu                } else {
4828545Ssaidi@eecs.umich.edu                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
4838545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4848545Ssaidi@eecs.umich.edu                }
4858545Ssaidi@eecs.umich.edu            } else {
4868545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VshlD, VshlQ>(
4878545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
4888545Ssaidi@eecs.umich.edu            }
48910149Smarco.elver@ed.ac.uk          case 0x5:
49010149Smarco.elver@ed.ac.uk            if (b) {
49110149Smarco.elver@ed.ac.uk                if (u) {
49210149Smarco.elver@ed.ac.uk                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
49310149Smarco.elver@ed.ac.uk                            q, size, machInst, vd, vm, vn);
49410149Smarco.elver@ed.ac.uk                } else {
49510149Smarco.elver@ed.ac.uk                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
49610149Smarco.elver@ed.ac.uk                            q, size, machInst, vd, vm, vn);
4978545Ssaidi@eecs.umich.edu                }
49810030SAli.Saidi@ARM.com            } else {
4998545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
5008545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
5018545Ssaidi@eecs.umich.edu            }
5028545Ssaidi@eecs.umich.edu          case 0x6:
50310030SAli.Saidi@ARM.com            if (b) {
50410030SAli.Saidi@ARM.com                return decodeNeonUSThreeReg<VminD, VminQ>(
50510030SAli.Saidi@ARM.com                        q, u, size, machInst, vd, vn, vm);
50610030SAli.Saidi@ARM.com            } else {
50710030SAli.Saidi@ARM.com                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
50810030SAli.Saidi@ARM.com                        q, u, size, machInst, vd, vn, vm);
50910030SAli.Saidi@ARM.com            }
51010030SAli.Saidi@ARM.com          case 0x7:
51110030SAli.Saidi@ARM.com            if (b) {
5128545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VabaD, VabaQ>(
5138545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5148545Ssaidi@eecs.umich.edu            } else {
5159046SAli.Saidi@ARM.com                if (bits(machInst, 23) == 1) {
5168545Ssaidi@eecs.umich.edu                    if (q) {
5178545Ssaidi@eecs.umich.edu                        return new Unknown(machInst);
5188545Ssaidi@eecs.umich.edu                    } else {
5198545Ssaidi@eecs.umich.edu                        return decodeNeonUSThreeUSReg<Vabdl>(
5208545Ssaidi@eecs.umich.edu                                u, size, machInst, vd, vn, vm);
5218545Ssaidi@eecs.umich.edu                    }
5228545Ssaidi@eecs.umich.edu                } else {
5238545Ssaidi@eecs.umich.edu                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
5242292SN/A                            q, u, size, machInst, vd, vn, vm);
5258199SAli.Saidi@ARM.com                }
5268199SAli.Saidi@ARM.com            }
5278199SAli.Saidi@ARM.com          case 0x8:
5288199SAli.Saidi@ARM.com            if (b) {
5298199SAli.Saidi@ARM.com                if (u) {
5308199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<VceqD, VceqQ>(
5318199SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
5328199SAli.Saidi@ARM.com                } else {
5338199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<VtstD, VtstQ>(
5348199SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
5358199SAli.Saidi@ARM.com                }
5368199SAli.Saidi@ARM.com            } else {
5379046SAli.Saidi@ARM.com                if (u) {
5388199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5398199SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
5408199SAli.Saidi@ARM.com                } else {
5418199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
5428199SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
5438199SAli.Saidi@ARM.com                }
5448199SAli.Saidi@ARM.com            }
5458199SAli.Saidi@ARM.com          case 0x9:
5468272SAli.Saidi@ARM.com            if (b) {
5478545Ssaidi@eecs.umich.edu                if (u) {
5488545Ssaidi@eecs.umich.edu                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5498545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5508545Ssaidi@eecs.umich.edu                } else {
5519046SAli.Saidi@ARM.com                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
5528545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5538545Ssaidi@eecs.umich.edu                }
5548545Ssaidi@eecs.umich.edu            } else {
5558592Sgblack@eecs.umich.edu                if (u) {
5568592Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
5578545Ssaidi@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5588199SAli.Saidi@ARM.com                } else {
5598545Ssaidi@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
5608199SAli.Saidi@ARM.com                            q, u, size, machInst, vd, vn, vm);
5618591Sgblack@eecs.umich.edu                }
5628591Sgblack@eecs.umich.edu            }
5638591Sgblack@eecs.umich.edu          case 0xa:
5648591Sgblack@eecs.umich.edu            if (b) {
5658545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VpminD, VpminQ>(
5668545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5678199SAli.Saidi@ARM.com            } else {
5688545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
5698545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5709046SAli.Saidi@ARM.com            }
5718545Ssaidi@eecs.umich.edu          case 0xb:
5728545Ssaidi@eecs.umich.edu            if (b) {
5738545Ssaidi@eecs.umich.edu                if (u) {
5748545Ssaidi@eecs.umich.edu                    return new Unknown(machInst);
5758545Ssaidi@eecs.umich.edu                } else {
5768545Ssaidi@eecs.umich.edu                    return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
5778545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5788545Ssaidi@eecs.umich.edu                }
5798545Ssaidi@eecs.umich.edu            } else {
5808545Ssaidi@eecs.umich.edu                if (u) {
5818592Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
5828592Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5838592Sgblack@eecs.umich.edu                } else {
5848545Ssaidi@eecs.umich.edu                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
5858545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5868545Ssaidi@eecs.umich.edu                }
5878545Ssaidi@eecs.umich.edu            }
5888591Sgblack@eecs.umich.edu          case 0xc:
5898591Sgblack@eecs.umich.edu            return new Unknown(machInst);
5908591Sgblack@eecs.umich.edu          case 0xd:
5918545Ssaidi@eecs.umich.edu            if (b) {
5928199SAli.Saidi@ARM.com                if (u) {
5938199SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
5948199SAli.Saidi@ARM.com                        if (q) {
5958199SAli.Saidi@ARM.com                            return new NVmulQFp<float>(machInst, vd, vn, vm);
5968199SAli.Saidi@ARM.com                        } else {
5978199SAli.Saidi@ARM.com                            return new NVmulDFp<float>(machInst, vd, vn, vm);
5988199SAli.Saidi@ARM.com                        }
5998199SAli.Saidi@ARM.com                    } else {
6008199SAli.Saidi@ARM.com                        return new Unknown(machInst);
6018199SAli.Saidi@ARM.com                    }
6028199SAli.Saidi@ARM.com                } else {
6038199SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
6042292SN/A                        if (q) {
6052292SN/A                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6064032Sktlim@umich.edu                        } else {
6072292SN/A                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
6082292SN/A                        }
6092292SN/A                    } else {
6107720Sgblack@eecs.umich.edu                        if (q) {
6117944SGiacomo.Gabrielli@arm.com                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
6122292SN/A                        } else {
6134032Sktlim@umich.edu                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
6144032Sktlim@umich.edu                        }
6152669Sktlim@umich.edu                    }
6162292SN/A                }
6177944SGiacomo.Gabrielli@arm.com            } else {
6187944SGiacomo.Gabrielli@arm.com                if (u) {
6197944SGiacomo.Gabrielli@arm.com                    if (bits(c, 1) == 0) {
6207944SGiacomo.Gabrielli@arm.com                        if (q) {
6217597Sminkyu.jeong@arm.com                            return new VpaddQFp<float>(machInst, vd, vn, vm);
6227597Sminkyu.jeong@arm.com                        } else {
62310231Ssteve.reinhardt@amd.com                            return new VpaddDFp<float>(machInst, vd, vn, vm);
6242329SN/A                        }
6252329SN/A                    } else {
6262367SN/A                        if (q) {
6272367SN/A                            return new VabdQFp<float>(machInst, vd, vn, vm);
62810231Ssteve.reinhardt@amd.com                        } else {
6297848SAli.Saidi@ARM.com                            return new VabdDFp<float>(machInst, vd, vn, vm);
6307600Sminkyu.jeong@arm.com                        }
6317600Sminkyu.jeong@arm.com                    }
6327600Sminkyu.jeong@arm.com                } else {
6334032Sktlim@umich.edu                    if (bits(c, 1) == 0) {
6343731Sktlim@umich.edu                        if (q) {
6352367SN/A                            return new VaddQFp<float>(machInst, vd, vn, vm);
6362367SN/A                        } else {
6372292SN/A                            return new VaddDFp<float>(machInst, vd, vn, vm);
6382292SN/A                        }
63910333Smitch.hayenga@arm.com                    } else {
6409046SAli.Saidi@ARM.com                        if (q) {
6414032Sktlim@umich.edu                            return new VsubQFp<float>(machInst, vd, vn, vm);
6424032Sktlim@umich.edu                        } else {
6434032Sktlim@umich.edu                            return new VsubDFp<float>(machInst, vd, vn, vm);
6448199SAli.Saidi@ARM.com                        }
6458199SAli.Saidi@ARM.com                    }
6462292SN/A                }
6472292SN/A            }
6482292SN/A          case 0xe:
6492292SN/A            if (b) {
6502292SN/A                if (u) {
6512292SN/A                    if (bits(c, 1) == 0) {
6522292SN/A                        if (q) {
6532292SN/A                            return new VacgeQFp<float>(machInst, vd, vn, vm);
6542292SN/A                        } else {
6552292SN/A                            return new VacgeDFp<float>(machInst, vd, vn, vm);
6562292SN/A                        }
6572292SN/A                    } else {
6582292SN/A                        if (q) {
6592292SN/A                            return new VacgtQFp<float>(machInst, vd, vn, vm);
6602292SN/A                        } else {
6617720Sgblack@eecs.umich.edu                            return new VacgtDFp<float>(machInst, vd, vn, vm);
6627720Sgblack@eecs.umich.edu                        }
6632292SN/A                    }
6644032Sktlim@umich.edu                } else {
6654032Sktlim@umich.edu                    return new Unknown(machInst);
6662292SN/A                }
6672292SN/A            } else {
6682292SN/A                if (u) {
6692292SN/A                    if (bits(c, 1) == 0) {
6702292SN/A                        if (q) {
6712292SN/A                            return new VcgeQFp<float>(machInst, vd, vn, vm);
6727944SGiacomo.Gabrielli@arm.com                        } else {
6737944SGiacomo.Gabrielli@arm.com                            return new VcgeDFp<float>(machInst, vd, vn, vm);
6747944SGiacomo.Gabrielli@arm.com                        }
6757944SGiacomo.Gabrielli@arm.com                    } else {
67610231Ssteve.reinhardt@amd.com                        if (q) {
6777848SAli.Saidi@ARM.com                            return new VcgtQFp<float>(machInst, vd, vn, vm);
6787848SAli.Saidi@ARM.com                        } else {
6792329SN/A                            return new VcgtDFp<float>(machInst, vd, vn, vm);
6807782Sminkyu.jeong@arm.com                        }
6817720Sgblack@eecs.umich.edu                    }
6822292SN/A                } else {
6832292SN/A                    if (bits(c, 1) == 0) {
68410231Ssteve.reinhardt@amd.com                        if (q) {
6857782Sminkyu.jeong@arm.com                            return new VceqQFp<float>(machInst, vd, vn, vm);
6867782Sminkyu.jeong@arm.com                        } else {
6877782Sminkyu.jeong@arm.com                            return new VceqDFp<float>(machInst, vd, vn, vm);
6882292SN/A                        }
6892292SN/A                    } else {
6902292SN/A                        return new Unknown(machInst);
6912292SN/A                    }
6922336SN/A                }
6932336SN/A            }
6942336SN/A          case 0xf:
6952329SN/A            if (b) {
6962292SN/A                if (u) {
6972329SN/A                    return new Unknown(machInst);
6982292SN/A                } else {
6992292SN/A                    if (bits(c, 1) == 0) {
7008199SAli.Saidi@ARM.com                        if (q) {
7012292SN/A                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
7022292SN/A                        } else {
7032292SN/A                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
7042292SN/A                        }
7052292SN/A                    } else {
7062292SN/A                        if (q) {
7072292SN/A                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
7082292SN/A                        } else {
7092292SN/A                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
7107720Sgblack@eecs.umich.edu                        }
7117720Sgblack@eecs.umich.edu                    }
7122292SN/A                }
7132292SN/A            } else {
7142292SN/A                if (u) {
7152292SN/A                    if (bits(c, 1) == 0) {
7162292SN/A                        if (q) {
7172292SN/A                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
7182292SN/A                        } else {
7192292SN/A                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
7202292SN/A                        }
7212292SN/A                    } else {
7222292SN/A                        if (q) {
7232292SN/A                            return new VpminQFp<float>(machInst, vd, vn, vm);
7242292SN/A                        } else {
7252292SN/A                            return new VpminDFp<float>(machInst, vd, vn, vm);
7262292SN/A                        }
7272292SN/A                    }
7282292SN/A                } else {
7292292SN/A                    if (bits(c, 1) == 0) {
7302292SN/A                        if (q) {
7312292SN/A                            return new VmaxQFp<float>(machInst, vd, vn, vm);
7322292SN/A                        } else {
7332292SN/A                            return new VmaxDFp<float>(machInst, vd, vn, vm);
7342292SN/A                        }
7352292SN/A                    } else {
7362292SN/A                        if (q) {
7372292SN/A                            return new VminQFp<float>(machInst, vd, vn, vm);
7382292SN/A                        } else {
7392292SN/A                            return new VminDFp<float>(machInst, vd, vn, vm);
7402292SN/A                        }
7412329SN/A                    }
7422329SN/A                }
7432292SN/A            }
7442292SN/A        }
7452292SN/A        return new Unknown(machInst);
7462292SN/A    }
7472292SN/A
7487720Sgblack@eecs.umich.edu    static StaticInstPtr
7497720Sgblack@eecs.umich.edu    decodeNeonOneRegModImm(ExtMachInst machInst)
7502292SN/A    {
7512292SN/A        const IntRegIndex vd =
7522292SN/A            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
7532292SN/A                               (bits(machInst, 22) << 4)));
7542292SN/A        const bool q = bits(machInst, 6);
7552292SN/A        const bool op = bits(machInst, 5);
7562292SN/A        const uint8_t cmode = bits(machInst, 11, 8);
7572292SN/A        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
7582292SN/A                                      bits(machInst, 24)) << 7) |
7592292SN/A                            (bits(machInst, 18, 16) << 4) |
7602292SN/A                            (bits(machInst, 3, 0) << 0);
7612292SN/A
7622292SN/A        // Check for invalid immediate encodings and return an unknown op
7636974Stjones1@inf.ed.ac.uk        // if it happens
7646974Stjones1@inf.ed.ac.uk        bool immValid = true;
7656974Stjones1@inf.ed.ac.uk        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
7666974Stjones1@inf.ed.ac.uk        if (!immValid) {
7676974Stjones1@inf.ed.ac.uk            return new Unknown(machInst);
7686974Stjones1@inf.ed.ac.uk        }
7696974Stjones1@inf.ed.ac.uk
7706974Stjones1@inf.ed.ac.uk        if (op) {
7716974Stjones1@inf.ed.ac.uk            if (bits(cmode, 3) == 0) {
7726974Stjones1@inf.ed.ac.uk                if (bits(cmode, 0) == 0) {
7736974Stjones1@inf.ed.ac.uk                    if (q)
7746974Stjones1@inf.ed.ac.uk                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7756974Stjones1@inf.ed.ac.uk                    else
7766974Stjones1@inf.ed.ac.uk                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7776974Stjones1@inf.ed.ac.uk                } else {
7786974Stjones1@inf.ed.ac.uk                    if (q)
7792292SN/A                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
7802292SN/A                    else
7816974Stjones1@inf.ed.ac.uk                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
7826974Stjones1@inf.ed.ac.uk                }
7836974Stjones1@inf.ed.ac.uk            } else {
7846974Stjones1@inf.ed.ac.uk                if (bits(cmode, 2) == 1) {
7856974Stjones1@inf.ed.ac.uk                    switch (bits(cmode, 1, 0)) {
7866974Stjones1@inf.ed.ac.uk                      case 0:
7872292SN/A                      case 1:
7882292SN/A                        if (q)
7892292SN/A                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7902292SN/A                        else
7918727Snilay@cs.wisc.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7922292SN/A                      case 2:
7932292SN/A                        if (q)
79410333Smitch.hayenga@arm.com                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
7952678Sktlim@umich.edu                        else
7962678Sktlim@umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
7972678Sktlim@umich.edu                      case 3:
7982678Sktlim@umich.edu                        if (q)
7992678Sktlim@umich.edu                            return new Unknown(machInst);
8002329SN/A                        else
8012329SN/A                            return new Unknown(machInst);
8022292SN/A                    }
8032292SN/A                } else {
8042292SN/A                    if (bits(cmode, 0) == 0) {
8052292SN/A                        if (q)
8062292SN/A                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
8072292SN/A                        else
8082292SN/A                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8092678Sktlim@umich.edu                    } else {
8102292SN/A                        if (q)
8112292SN/A                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8122292SN/A                        else
8132292SN/A                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8142292SN/A                    }
8152292SN/A                }
8162292SN/A            }
8172292SN/A        } else {
8182292SN/A            if (bits(cmode, 3) == 0) {
8192292SN/A                if (bits(cmode, 0) == 0) {
8202292SN/A                    if (q)
8216974Stjones1@inf.ed.ac.uk                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8226974Stjones1@inf.ed.ac.uk                    else
8236974Stjones1@inf.ed.ac.uk                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8246974Stjones1@inf.ed.ac.uk                } else {
8256974Stjones1@inf.ed.ac.uk                    if (q)
8262669Sktlim@umich.edu                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8272669Sktlim@umich.edu                    else
8282669Sktlim@umich.edu                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8298481Sgblack@eecs.umich.edu                }
8308481Sgblack@eecs.umich.edu            } else {
8318481Sgblack@eecs.umich.edu                if (bits(cmode, 2) == 1) {
8322292SN/A                    if (q)
8332292SN/A                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8342669Sktlim@umich.edu                    else
83510031SAli.Saidi@ARM.com                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8363772Sgblack@eecs.umich.edu                } else {
83710031SAli.Saidi@ARM.com                    if (bits(cmode, 0) == 0) {
83810031SAli.Saidi@ARM.com                        if (q)
83910031SAli.Saidi@ARM.com                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
84010031SAli.Saidi@ARM.com                        else
8412669Sktlim@umich.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8426974Stjones1@inf.ed.ac.uk                    } else {
8436974Stjones1@inf.ed.ac.uk                        if (q)
8442292SN/A                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8452678Sktlim@umich.edu                        else
8462678Sktlim@umich.edu                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
8472678Sktlim@umich.edu                    }
8482678Sktlim@umich.edu                }
8496974Stjones1@inf.ed.ac.uk            }
8506974Stjones1@inf.ed.ac.uk        }
8516974Stjones1@inf.ed.ac.uk        return new Unknown(machInst);
8526974Stjones1@inf.ed.ac.uk    }
85310342SCurtis.Dunham@arm.com
8546974Stjones1@inf.ed.ac.uk    static StaticInstPtr
8556974Stjones1@inf.ed.ac.uk    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8566974Stjones1@inf.ed.ac.uk    {
8576974Stjones1@inf.ed.ac.uk        const uint32_t a = bits(machInst, 11, 8);
85810342SCurtis.Dunham@arm.com        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
85910342SCurtis.Dunham@arm.com        const bool b = bits(machInst, 6);
8606974Stjones1@inf.ed.ac.uk        const bool l = bits(machInst, 7);
8616974Stjones1@inf.ed.ac.uk        const IntRegIndex vd =
8626974Stjones1@inf.ed.ac.uk            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
8636974Stjones1@inf.ed.ac.uk                               (bits(machInst, 22) << 4)));
8646974Stjones1@inf.ed.ac.uk        const IntRegIndex vm =
8656974Stjones1@inf.ed.ac.uk            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
8666974Stjones1@inf.ed.ac.uk                               (bits(machInst, 5) << 4)));
8676974Stjones1@inf.ed.ac.uk        unsigned imm6 = bits(machInst, 21, 16);
8686974Stjones1@inf.ed.ac.uk        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
8696974Stjones1@inf.ed.ac.uk        unsigned size = 3;
8706974Stjones1@inf.ed.ac.uk        unsigned lShiftAmt = 0;
8716974Stjones1@inf.ed.ac.uk        unsigned bitSel;
8726974Stjones1@inf.ed.ac.uk        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8736974Stjones1@inf.ed.ac.uk            if (bitSel & imm)
8742678Sktlim@umich.edu                break;
8757720Sgblack@eecs.umich.edu            else if (!size)
8762292SN/A                return new Unknown(machInst);
8777720Sgblack@eecs.umich.edu            size--;
8783797Sgblack@eecs.umich.edu        }
8793221Sktlim@umich.edu        lShiftAmt = imm6 & ~bitSel;
8802292SN/A        unsigned rShiftAmt = 0;
8812693Sktlim@umich.edu        if (a != 0xe && a != 0xf) {
8824350Sgblack@eecs.umich.edu            if (size > 2)
8836974Stjones1@inf.ed.ac.uk                rShiftAmt = 64 - imm6;
8843326Sktlim@umich.edu            else
8853326Sktlim@umich.edu                rShiftAmt = 2 * (8 << size) - imm6;
8863326Sktlim@umich.edu        }
8879046SAli.Saidi@ARM.com
88810030SAli.Saidi@ARM.com        switch (a) {
8899046SAli.Saidi@ARM.com          case 0x0:
8903326Sktlim@umich.edu            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
8913326Sktlim@umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8923326Sktlim@umich.edu          case 0x1:
8933326Sktlim@umich.edu            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
8943326Sktlim@umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8953326Sktlim@umich.edu          case 0x2:
8963326Sktlim@umich.edu            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
8977823Ssteve.reinhardt@amd.com                    b, u, size, machInst, vd, vm, rShiftAmt);
8988887Sgeoffrey.blake@arm.com          case 0x3:
8998887Sgeoffrey.blake@arm.com            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
9008887Sgeoffrey.blake@arm.com                    b, u, size, machInst, vd, vm, rShiftAmt);
9018887Sgeoffrey.blake@arm.com          case 0x4:
9028887Sgeoffrey.blake@arm.com            if (u) {
9038887Sgeoffrey.blake@arm.com                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
9043326Sktlim@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9053326Sktlim@umich.edu            } else {
9063326Sktlim@umich.edu                return new Unknown(machInst);
9072693Sktlim@umich.edu            }
9082693Sktlim@umich.edu          case 0x5:
9092693Sktlim@umich.edu            if (u) {
9102693Sktlim@umich.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9112693Sktlim@umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9122693Sktlim@umich.edu            } else {
9138481Sgblack@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9148481Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9158481Sgblack@eecs.umich.edu            }
9168481Sgblack@eecs.umich.edu          case 0x6:
9178481Sgblack@eecs.umich.edu          case 0x7:
9188481Sgblack@eecs.umich.edu            if (u) {
9198481Sgblack@eecs.umich.edu                if (a == 0x6) {
9208481Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9218481Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9228481Sgblack@eecs.umich.edu                } else {
9238481Sgblack@eecs.umich.edu                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
9248481Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9258481Sgblack@eecs.umich.edu                }
9268481Sgblack@eecs.umich.edu            } else {
9278481Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9288481Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9298481Sgblack@eecs.umich.edu            }
9308481Sgblack@eecs.umich.edu          case 0x8:
9318481Sgblack@eecs.umich.edu            if (l) {
9328481Sgblack@eecs.umich.edu                return new Unknown(machInst);
9338481Sgblack@eecs.umich.edu            } else if (u) {
9344032Sktlim@umich.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9353221Sktlim@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9363221Sktlim@umich.edu            } else {
9376974Stjones1@inf.ed.ac.uk                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
9386974Stjones1@inf.ed.ac.uk                        b, size, machInst, vd, vm, rShiftAmt);
9398481Sgblack@eecs.umich.edu            }
9406974Stjones1@inf.ed.ac.uk          case 0x9:
9416974Stjones1@inf.ed.ac.uk            if (l) {
9426974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
9432669Sktlim@umich.edu            } else if (u) {
9446974Stjones1@inf.ed.ac.uk                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
9456974Stjones1@inf.ed.ac.uk                        b, size, machInst, vd, vm, rShiftAmt);
9468481Sgblack@eecs.umich.edu            } else {
9476974Stjones1@inf.ed.ac.uk                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
9486974Stjones1@inf.ed.ac.uk                        b, size, machInst, vd, vm, rShiftAmt);
9496974Stjones1@inf.ed.ac.uk            }
9506974Stjones1@inf.ed.ac.uk          case 0xa:
9516974Stjones1@inf.ed.ac.uk            if (l || b) {
9526974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
9536974Stjones1@inf.ed.ac.uk            } else {
9546974Stjones1@inf.ed.ac.uk                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9556974Stjones1@inf.ed.ac.uk                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9566974Stjones1@inf.ed.ac.uk            }
9576974Stjones1@inf.ed.ac.uk          case 0xe:
9586974Stjones1@inf.ed.ac.uk            if (l) {
9596974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
9606974Stjones1@inf.ed.ac.uk            } else {
9616974Stjones1@inf.ed.ac.uk                if (bits(imm6, 5) == 0)
9626974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
9636974Stjones1@inf.ed.ac.uk                if (u) {
9646974Stjones1@inf.ed.ac.uk                    if (b) {
9656974Stjones1@inf.ed.ac.uk                        return new NVcvtu2fpQ<float>(
9666974Stjones1@inf.ed.ac.uk                                machInst, vd, vm, 64 - imm6);
9676974Stjones1@inf.ed.ac.uk                    } else {
9686974Stjones1@inf.ed.ac.uk                        return new NVcvtu2fpD<float>(
9696974Stjones1@inf.ed.ac.uk                                machInst, vd, vm, 64 - imm6);
9706974Stjones1@inf.ed.ac.uk                    }
9712292SN/A                } else {
9722292SN/A                    if (b) {
9732292SN/A                        return new NVcvts2fpQ<float>(
9742292SN/A                                machInst, vd, vm, 64 - imm6);
9752292SN/A                    } else {
9762292SN/A                        return new NVcvts2fpD<float>(
9772292SN/A                                machInst, vd, vm, 64 - imm6);
9782292SN/A                    }
9792292SN/A                }
9802292SN/A            }
9812292SN/A          case 0xf:
9822292SN/A            if (l) {
9832292SN/A                return new Unknown(machInst);
9842292SN/A            } else {
9852292SN/A                if (bits(imm6, 5) == 0)
9862292SN/A                    return new Unknown(machInst);
9872292SN/A                if (u) {
9882292SN/A                    if (b) {
9892292SN/A                        return new NVcvt2ufxQ<float>(
9902292SN/A                                machInst, vd, vm, 64 - imm6);
9912292SN/A                    } else {
9922292SN/A                        return new NVcvt2ufxD<float>(
9932292SN/A                                machInst, vd, vm, 64 - imm6);
9942292SN/A                    }
9952292SN/A                } else {
9962292SN/A                    if (b) {
9972292SN/A                        return new NVcvt2sfxQ<float>(
9982292SN/A                                machInst, vd, vm, 64 - imm6);
9992329SN/A                    } else {
10002292SN/A                        return new NVcvt2sfxD<float>(
10012292SN/A                                machInst, vd, vm, 64 - imm6);
10022292SN/A                    }
10032292SN/A                }
10042292SN/A            }
10057720Sgblack@eecs.umich.edu        }
10062292SN/A        return new Unknown(machInst);
10077720Sgblack@eecs.umich.edu    }
10082292SN/A
10092292SN/A    static StaticInstPtr
10102292SN/A    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
10112292SN/A    {
10122292SN/A        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10132292SN/A        const uint32_t a = bits(machInst, 11, 8);
10142292SN/A        const IntRegIndex vd =
10152292SN/A            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
10162329SN/A                               (bits(machInst, 22) << 4)));
10172731Sktlim@umich.edu        const IntRegIndex vn =
10182292SN/A            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
10192292SN/A                               (bits(machInst, 7) << 4)));
10202292SN/A        const IntRegIndex vm =
10212292SN/A            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10222292SN/A                               (bits(machInst, 5) << 4)));
10232292SN/A        const unsigned size = bits(machInst, 21, 20);
10242292SN/A        switch (a) {
10252727Sktlim@umich.edu          case 0x0:
10262292SN/A            return decodeNeonUSThreeUSReg<Vaddl>(
10272292SN/A                    u, size, machInst, vd, vn, vm);
10284032Sktlim@umich.edu          case 0x1:
10294032Sktlim@umich.edu            return decodeNeonUSThreeUSReg<Vaddw>(
10304032Sktlim@umich.edu                    u, size, machInst, vd, vn, vm);
10314032Sktlim@umich.edu          case 0x2:
10322292SN/A            return decodeNeonUSThreeUSReg<Vsubl>(
10332292SN/A                    u, size, machInst, vd, vn, vm);
10342292SN/A          case 0x3:
10352292SN/A            return decodeNeonUSThreeUSReg<Vsubw>(
10362292SN/A                    u, size, machInst, vd, vn, vm);
10372329SN/A          case 0x4:
10382292SN/A            if (u) {
10392292SN/A                return decodeNeonUThreeUSReg<Vraddhn>(
10402292SN/A                        size, machInst, vd, vn, vm);
10412292SN/A            } else {
10427720Sgblack@eecs.umich.edu                return decodeNeonUThreeUSReg<Vaddhn>(
10432292SN/A                        size, machInst, vd, vn, vm);
10447720Sgblack@eecs.umich.edu            }
10452292SN/A          case 0x5:
10462292SN/A            return decodeNeonUSThreeUSReg<Vabal>(
10472329SN/A                    u, size, machInst, vd, vn, vm);
10482329SN/A          case 0x6:
10492292SN/A            if (u) {
10502292SN/A                return decodeNeonUThreeUSReg<Vrsubhn>(
10512292SN/A                        size, machInst, vd, vn, vm);
10522292SN/A            } else {
10532292SN/A                return decodeNeonUThreeUSReg<Vsubhn>(
10542292SN/A                        size, machInst, vd, vn, vm);
10552292SN/A            }
10562329SN/A          case 0x7:
10572731Sktlim@umich.edu            if (bits(machInst, 23)) {
10582292SN/A                return decodeNeonUSThreeUSReg<Vabdl>(
10592292SN/A                        u, size, machInst, vd, vn, vm);
10602292SN/A            } else {
10614032Sktlim@umich.edu                return decodeNeonUSThreeReg<VabdD, VabdQ>(
10624032Sktlim@umich.edu                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
10634032Sktlim@umich.edu            }
10644032Sktlim@umich.edu          case 0x8:
10656974Stjones1@inf.ed.ac.uk            return decodeNeonUSThreeUSReg<Vmlal>(
10666974Stjones1@inf.ed.ac.uk                    u, size, machInst, vd, vn, vm);
10676974Stjones1@inf.ed.ac.uk          case 0xa:
10686974Stjones1@inf.ed.ac.uk            return decodeNeonUSThreeUSReg<Vmlsl>(
10696974Stjones1@inf.ed.ac.uk                    u, size, machInst, vd, vn, vm);
10706974Stjones1@inf.ed.ac.uk          case 0x9:
10716974Stjones1@inf.ed.ac.uk            if (u) {
10724032Sktlim@umich.edu                return new Unknown(machInst);
10732292SN/A            } else {
10742292SN/A                return decodeNeonSThreeUSReg<Vqdmlal>(
10752292SN/A                        size, machInst, vd, vn, vm);
10762292SN/A            }
10772292SN/A          case 0xb:
10782292SN/A            if (u) {
10792292SN/A                return new Unknown(machInst);
10802727Sktlim@umich.edu            } else {
10812292SN/A                return decodeNeonSThreeUSReg<Vqdmlsl>(
10822292SN/A                        size, machInst, vd, vn, vm);
10832292SN/A            }
10842292SN/A          case 0xc:
10852292SN/A            return decodeNeonUSThreeUSReg<Vmull>(
10863349Sbinkertn@umich.edu                    u, size, machInst, vd, vn, vm);
10872693Sktlim@umich.edu          case 0xd:
10882693Sktlim@umich.edu            if (u) {
10892693Sktlim@umich.edu                return new Unknown(machInst);
10902693Sktlim@umich.edu            } else {
10912693Sktlim@umich.edu                return decodeNeonSThreeUSReg<Vqdmull>(
10922693Sktlim@umich.edu                        size, machInst, vd, vn, vm);
10932693Sktlim@umich.edu            }
10942693Sktlim@umich.edu          case 0xe:
10952693Sktlim@umich.edu            return decodeNeonUThreeUSReg<Vmullp>(
10962693Sktlim@umich.edu                    size, machInst, vd, vn, vm);
10972693Sktlim@umich.edu        }
10982693Sktlim@umich.edu        return new Unknown(machInst);
10992693Sktlim@umich.edu    }
11002693Sktlim@umich.edu
11012693Sktlim@umich.edu    static StaticInstPtr
11022693Sktlim@umich.edu    decodeNeonTwoRegScalar(ExtMachInst machInst)
11038887Sgeoffrey.blake@arm.com    {
11042693Sktlim@umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
11052732Sktlim@umich.edu        const uint32_t a = bits(machInst, 11, 8);
11062693Sktlim@umich.edu        const unsigned size = bits(machInst, 21, 20);
11072693Sktlim@umich.edu        const IntRegIndex vd =
11082693Sktlim@umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11098727Snilay@cs.wisc.edu                               (bits(machInst, 22) << 4)));
11108727Snilay@cs.wisc.edu        const IntRegIndex vn =
11118727Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11128727Snilay@cs.wisc.edu                               (bits(machInst, 7) << 4)));
11132693Sktlim@umich.edu        const IntRegIndex vm = (size == 2) ?
11142693Sktlim@umich.edu            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
11152693Sktlim@umich.edu            (IntRegIndex)(2 * bits(machInst, 2, 0));
11162693Sktlim@umich.edu        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11172693Sktlim@umich.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11182678Sktlim@umich.edu        switch (a) {
11192678Sktlim@umich.edu          case 0x0:
11202678Sktlim@umich.edu            if (u) {
11212678Sktlim@umich.edu                switch (size) {
11222678Sktlim@umich.edu                  case 1:
11232678Sktlim@umich.edu                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
11242678Sktlim@umich.edu                  case 2:
11252727Sktlim@umich.edu                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
11262678Sktlim@umich.edu                  default:
11272678Sktlim@umich.edu                    return new Unknown(machInst);
11282678Sktlim@umich.edu                }
11292678Sktlim@umich.edu            } else {
11302678Sktlim@umich.edu                switch (size) {
11312678Sktlim@umich.edu                  case 1:
11322678Sktlim@umich.edu                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
11332678Sktlim@umich.edu                  case 2:
11342678Sktlim@umich.edu                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
11352678Sktlim@umich.edu                  default:
11362678Sktlim@umich.edu                    return new Unknown(machInst);
11372678Sktlim@umich.edu                }
11382678Sktlim@umich.edu            }
11392678Sktlim@umich.edu          case 0x1:
11407598Sminkyu.jeong@arm.com            if (u)
11417598Sminkyu.jeong@arm.com                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
11427598Sminkyu.jeong@arm.com            else
11432678Sktlim@umich.edu                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
11442678Sktlim@umich.edu          case 0x4:
11452678Sktlim@umich.edu            if (u) {
11462678Sktlim@umich.edu                switch (size) {
11472292SN/A                  case 1:
11482292SN/A                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11492292SN/A                  case 2:
11502292SN/A                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11512292SN/A                  default:
11522292SN/A                    return new Unknown(machInst);
11532292SN/A                }
11542292SN/A            } else {
11553126Sktlim@umich.edu                switch (size) {
11562292SN/A                  case 1:
11572292SN/A                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
11582292SN/A                  case 2:
11592292SN/A                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11602292SN/A                  default:
11612292SN/A                    return new Unknown(machInst);
11622292SN/A                }
11632292SN/A            }
11642292SN/A          case 0x5:
11652292SN/A            if (u)
11662292SN/A                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
11672292SN/A            else
11682292SN/A                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
11692329SN/A          case 0x2:
11702329SN/A            if (u) {
11712329SN/A                switch (size) {
11722292SN/A                  case 1:
11739527SMatt.Horsnell@arm.com                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11749527SMatt.Horsnell@arm.com                  case 2:
11759527SMatt.Horsnell@arm.com                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11769527SMatt.Horsnell@arm.com                  default:
11779527SMatt.Horsnell@arm.com                    return new Unknown(machInst);
11789527SMatt.Horsnell@arm.com                }
11799527SMatt.Horsnell@arm.com            } else {
11802292SN/A                switch (size) {
11812292SN/A                  case 1:
11822292SN/A                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
11832292SN/A                  case 2:
11842292SN/A                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
11852292SN/A                  default:
11862292SN/A                    return new Unknown(machInst);
11872292SN/A                }
11882292SN/A            }
11892316SN/A          case 0x6:
11902316SN/A            if (u) {
11912329SN/A                switch (size) {
11928727Snilay@cs.wisc.edu                  case 1:
11938727Snilay@cs.wisc.edu                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
11948727Snilay@cs.wisc.edu                  case 2:
11958727Snilay@cs.wisc.edu                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
11962329SN/A                  default:
11972329SN/A                    return new Unknown(machInst);
11982329SN/A                }
11992316SN/A            } else {
12002732Sktlim@umich.edu                switch (size) {
12012316SN/A                  case 1:
12022292SN/A                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
12032292SN/A                  case 2:
12042292SN/A                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
12056974Stjones1@inf.ed.ac.uk                  default:
12066974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
12076974Stjones1@inf.ed.ac.uk                }
12088975Sandreas.hansson@arm.com            }
12096974Stjones1@inf.ed.ac.uk          case 0x3:
12106974Stjones1@inf.ed.ac.uk            if (u) {
12116974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
12126974Stjones1@inf.ed.ac.uk            } else {
12136974Stjones1@inf.ed.ac.uk                switch (size) {
12146974Stjones1@inf.ed.ac.uk                  case 1:
12156974Stjones1@inf.ed.ac.uk                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12166974Stjones1@inf.ed.ac.uk                  case 2:
12176974Stjones1@inf.ed.ac.uk                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12186974Stjones1@inf.ed.ac.uk                  default:
12196974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
12202693Sktlim@umich.edu                }
12212693Sktlim@umich.edu            }
12222693Sktlim@umich.edu          case 0x7:
12232698Sktlim@umich.edu            if (u) {
12244985Sktlim@umich.edu                return new Unknown(machInst);
12252698Sktlim@umich.edu            } else {
12262693Sktlim@umich.edu                switch (size) {
12278587Snilay@cs.wisc.edu                  case 1:
12288587Snilay@cs.wisc.edu                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12298587Snilay@cs.wisc.edu                  case 2:
12308975Sandreas.hansson@arm.com                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12316974Stjones1@inf.ed.ac.uk                  default:
12328133SAli.Saidi@ARM.com                    return new Unknown(machInst);
12338133SAli.Saidi@ARM.com                }
12348133SAli.Saidi@ARM.com            }
12356974Stjones1@inf.ed.ac.uk          case 0x8:
12366974Stjones1@inf.ed.ac.uk            if (u) {
12372699Sktlim@umich.edu                switch (size) {
12382693Sktlim@umich.edu                  case 1:
12396974Stjones1@inf.ed.ac.uk                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
12406974Stjones1@inf.ed.ac.uk                  case 2:
12416974Stjones1@inf.ed.ac.uk                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
12426974Stjones1@inf.ed.ac.uk                  default:
12436974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
12446974Stjones1@inf.ed.ac.uk                }
12456974Stjones1@inf.ed.ac.uk            } else {
12466974Stjones1@inf.ed.ac.uk                switch (size) {
12472693Sktlim@umich.edu                  case 1:
12482693Sktlim@umich.edu                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
12492727Sktlim@umich.edu                  case 2:
12502693Sktlim@umich.edu                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
12512693Sktlim@umich.edu                  default:
12522693Sktlim@umich.edu                    return new Unknown(machInst);
12532693Sktlim@umich.edu                }
12542693Sktlim@umich.edu            }
12552292SN/A          case 0x9:
12569440SAndreas.Sandberg@ARM.com            if (u)
12572292SN/A                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
12582292SN/A            else
12592292SN/A                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
12602292SN/A          case 0xa:
12612292SN/A            if (u) {
12622292SN/A                switch (size) {
12632292SN/A                  case 1:
12649440SAndreas.Sandberg@ARM.com                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
12652292SN/A                  case 2:
12662292SN/A                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
12672292SN/A                  default:
12682292SN/A                    return new Unknown(machInst);
12692292SN/A                }
12702292SN/A            } else {
12712292SN/A                switch (size) {
12729440SAndreas.Sandberg@ARM.com                  case 1:
12732292SN/A                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
12742292SN/A                  case 2:
12752292SN/A                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
12762292SN/A                  default:
12772292SN/A                    return new Unknown(machInst);
12782292SN/A                }
12792292SN/A            }
12809440SAndreas.Sandberg@ARM.com          case 0xb:
12812292SN/A            if (u) {
12822292SN/A                return new Unknown(machInst);
12832292SN/A            } else {
12842292SN/A                if (u) {
12852329SN/A                    switch (size) {
12862329SN/A                      case 1:
12872329SN/A                        return new Vqdmulls<uint16_t>(
12889440SAndreas.Sandberg@ARM.com                                machInst, vd, vn, vm, index);
12892329SN/A                      case 2:
12902329SN/A                        return new Vqdmulls<uint32_t>(
12912329SN/A                                machInst, vd, vn, vm, index);
12922329SN/A                      default:
12932329SN/A                        return new Unknown(machInst);
12942329SN/A                    }
12952329SN/A                } else {
12962329SN/A                    switch (size) {
12979440SAndreas.Sandberg@ARM.com                      case 1:
12989440SAndreas.Sandberg@ARM.com                        return new Vqdmulls<int16_t>(
12992329SN/A                                machInst, vd, vn, vm, index);
13002329SN/A                      case 2:
13012329SN/A                        return new Vqdmulls<int32_t>(
13029440SAndreas.Sandberg@ARM.com                                machInst, vd, vn, vm, index);
13032329SN/A                      default:
13042329SN/A                        return new Unknown(machInst);
13052329SN/A                    }
13062329SN/A                }
13072329SN/A            }
13082329SN/A          case 0xc:
13092329SN/A            if (u) {
13109440SAndreas.Sandberg@ARM.com                switch (size) {
13119440SAndreas.Sandberg@ARM.com                  case 1:
13122329SN/A                    return new VqdmulhsQ<int16_t>(
13132329SN/A                            machInst, vd, vn, vm, index);
13142329SN/A                  case 2:
13152329SN/A                    return new VqdmulhsQ<int32_t>(
13162329SN/A                            machInst, vd, vn, vm, index);
13172329SN/A                  default:
13189944Smatt.horsnell@ARM.com                    return new Unknown(machInst);
13199944Smatt.horsnell@ARM.com                }
1320            } else {
1321                switch (size) {
1322                  case 1:
1323                    return new VqdmulhsD<int16_t>(
1324                            machInst, vd, vn, vm, index);
1325                  case 2:
1326                    return new VqdmulhsD<int32_t>(
1327                            machInst, vd, vn, vm, index);
1328                  default:
1329                    return new Unknown(machInst);
1330                }
1331            }
1332          case 0xd:
1333            if (u) {
1334                switch (size) {
1335                  case 1:
1336                    return new VqrdmulhsQ<int16_t>(
1337                            machInst, vd, vn, vm, index);
1338                  case 2:
1339                    return new VqrdmulhsQ<int32_t>(
1340                            machInst, vd, vn, vm, index);
1341                  default:
1342                    return new Unknown(machInst);
1343                }
1344            } else {
1345                switch (size) {
1346                  case 1:
1347                    return new VqrdmulhsD<int16_t>(
1348                            machInst, vd, vn, vm, index);
1349                  case 2:
1350                    return new VqrdmulhsD<int32_t>(
1351                            machInst, vd, vn, vm, index);
1352                  default:
1353                    return new Unknown(machInst);
1354                }
1355            }
1356        }
1357        return new Unknown(machInst);
1358    }
1359
1360    static StaticInstPtr
1361    decodeNeonTwoRegMisc(ExtMachInst machInst)
1362    {
1363        const uint32_t a = bits(machInst, 17, 16);
1364        const uint32_t b = bits(machInst, 10, 6);
1365        const bool q = bits(machInst, 6);
1366        const IntRegIndex vd =
1367            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1368                               (bits(machInst, 22) << 4)));
1369        const IntRegIndex vm =
1370            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1371                               (bits(machInst, 5) << 4)));
1372        const unsigned size = bits(machInst, 19, 18);
1373        switch (a) {
1374          case 0x0:
1375            switch (bits(b, 4, 1)) {
1376              case 0x0:
1377                switch (size) {
1378                  case 0:
1379                    if (q) {
1380                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
1381                    } else {
1382                        return new NVrev64D<uint8_t>(machInst, vd, vm);
1383                    }
1384                  case 1:
1385                    if (q) {
1386                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
1387                    } else {
1388                        return new NVrev64D<uint16_t>(machInst, vd, vm);
1389                    }
1390                  case 2:
1391                    if (q) {
1392                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
1393                    } else {
1394                        return new NVrev64D<uint32_t>(machInst, vd, vm);
1395                    }
1396                  default:
1397                    return new Unknown(machInst);
1398                }
1399              case 0x1:
1400                switch (size) {
1401                  case 0:
1402                    if (q) {
1403                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
1404                    } else {
1405                        return new NVrev32D<uint8_t>(machInst, vd, vm);
1406                    }
1407                  case 1:
1408                    if (q) {
1409                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1410                    } else {
1411                        return new NVrev32D<uint16_t>(machInst, vd, vm);
1412                    }
1413                  default:
1414                    return new Unknown(machInst);
1415                }
1416              case 0x2:
1417                if (size != 0) {
1418                    return new Unknown(machInst);
1419                } else if (q) {
1420                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
1421                } else {
1422                    return new NVrev16D<uint8_t>(machInst, vd, vm);
1423                }
1424              case 0x4:
1425                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1426                        q, size, machInst, vd, vm);
1427              case 0x5:
1428                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1429                        q, size, machInst, vd, vm);
1430              case 0x8:
1431                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1432                        q, size, machInst, vd, vm);
1433              case 0x9:
1434                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1435                        q, size, machInst, vd, vm);
1436              case 0xa:
1437                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1438                        q, size, machInst, vd, vm);
1439              case 0xb:
1440                if (q)
1441                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
1442                else
1443                    return new NVmvnD<uint64_t>(machInst, vd, vm);
1444              case 0xc:
1445                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1446                        q, size, machInst, vd, vm);
1447              case 0xd:
1448                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1449                        q, size, machInst, vd, vm);
1450              case 0xe:
1451                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1452                        q, size, machInst, vd, vm);
1453              case 0xf:
1454                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1455                        q, size, machInst, vd, vm);
1456              default:
1457                return new Unknown(machInst);
1458            }
1459          case 0x1:
1460            switch (bits(b, 3, 1)) {
1461              case 0x0:
1462                if (bits(b, 4)) {
1463                    if (q) {
1464                        return new NVcgtQFp<float>(machInst, vd, vm);
1465                    } else {
1466                        return new NVcgtDFp<float>(machInst, vd, vm);
1467                    }
1468                } else {
1469                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1470                            q, size, machInst, vd, vm);
1471                }
1472              case 0x1:
1473                if (bits(b, 4)) {
1474                    if (q) {
1475                        return new NVcgeQFp<float>(machInst, vd, vm);
1476                    } else {
1477                        return new NVcgeDFp<float>(machInst, vd, vm);
1478                    }
1479                } else {
1480                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1481                            q, size, machInst, vd, vm);
1482                }
1483              case 0x2:
1484                if (bits(b, 4)) {
1485                    if (q) {
1486                        return new NVceqQFp<float>(machInst, vd, vm);
1487                    } else {
1488                        return new NVceqDFp<float>(machInst, vd, vm);
1489                    }
1490                } else {
1491                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1492                            q, size, machInst, vd, vm);
1493                }
1494              case 0x3:
1495                if (bits(b, 4)) {
1496                    if (q) {
1497                        return new NVcleQFp<float>(machInst, vd, vm);
1498                    } else {
1499                        return new NVcleDFp<float>(machInst, vd, vm);
1500                    }
1501                } else {
1502                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1503                            q, size, machInst, vd, vm);
1504                }
1505              case 0x4:
1506                if (bits(b, 4)) {
1507                    if (q) {
1508                        return new NVcltQFp<float>(machInst, vd, vm);
1509                    } else {
1510                        return new NVcltDFp<float>(machInst, vd, vm);
1511                    }
1512                } else {
1513                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1514                            q, size, machInst, vd, vm);
1515                }
1516              case 0x6:
1517                if (bits(machInst, 10)) {
1518                    if (q)
1519                        return new NVabsQFp<float>(machInst, vd, vm);
1520                    else
1521                        return new NVabsDFp<float>(machInst, vd, vm);
1522                } else {
1523                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1524                            q, size, machInst, vd, vm);
1525                }
1526              case 0x7:
1527                if (bits(machInst, 10)) {
1528                    if (q)
1529                        return new NVnegQFp<float>(machInst, vd, vm);
1530                    else
1531                        return new NVnegDFp<float>(machInst, vd, vm);
1532                } else {
1533                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1534                            q, size, machInst, vd, vm);
1535                }
1536            }
1537          case 0x2:
1538            switch (bits(b, 4, 1)) {
1539              case 0x0:
1540                if (q)
1541                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1542                else
1543                    return new NVswpD<uint64_t>(machInst, vd, vm);
1544              case 0x1:
1545                return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
1546                        q, size, machInst, vd, vm);
1547              case 0x2:
1548                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1549                        q, size, machInst, vd, vm);
1550              case 0x3:
1551                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1552                        q, size, machInst, vd, vm);
1553              case 0x4:
1554                if (b == 0x8) {
1555                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1556                            size, machInst, vd, vm);
1557                } else {
1558                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1559                            size, machInst, vd, vm);
1560                }
1561              case 0x5:
1562                if (q) {
1563                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1564                            size, machInst, vd, vm);
1565                } else {
1566                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1567                            size, machInst, vd, vm);
1568                }
1569              case 0x6:
1570                if (b == 0xc) {
1571                    const IntRegIndex vd =
1572                        (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1573                                           (bits(machInst, 22) << 4)));
1574                    const IntRegIndex vm =
1575                        (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1576                                           (bits(machInst, 5) << 4)));
1577                    unsigned size = bits(machInst, 19, 18);
1578                    return decodeNeonSTwoShiftUSReg<NVshll>(
1579                            size, machInst, vd, vm, 8 << size);
1580                } else {
1581                    return new Unknown(machInst);
1582                }
1583              case 0xc:
1584              case 0xe:
1585                if (b == 0x18) {
1586                    if (size != 1 || (vm % 2))
1587                        return new Unknown(machInst);
1588                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1589                } else if (b == 0x1c) {
1590                    if (size != 1 || (vd % 2))
1591                        return new Unknown(machInst);
1592                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1593                } else {
1594                    return new Unknown(machInst);
1595                }
1596              default:
1597                return new Unknown(machInst);
1598            }
1599          case 0x3:
1600            if (bits(b, 4, 3) == 0x3) {
1601                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1602                    return new Unknown(machInst);
1603                } else {
1604                    if (bits(b, 2)) {
1605                        if (bits(b, 1)) {
1606                            if (q) {
1607                                return new NVcvt2ufxQ<float>(
1608                                        machInst, vd, vm, 0);
1609                            } else {
1610                                return new NVcvt2ufxD<float>(
1611                                        machInst, vd, vm, 0);
1612                            }
1613                        } else {
1614                            if (q) {
1615                                return new NVcvt2sfxQ<float>(
1616                                        machInst, vd, vm, 0);
1617                            } else {
1618                                return new NVcvt2sfxD<float>(
1619                                        machInst, vd, vm, 0);
1620                            }
1621                        }
1622                    } else {
1623                        if (bits(b, 1)) {
1624                            if (q) {
1625                                return new NVcvtu2fpQ<float>(
1626                                        machInst, vd, vm, 0);
1627                            } else {
1628                                return new NVcvtu2fpD<float>(
1629                                        machInst, vd, vm, 0);
1630                            }
1631                        } else {
1632                            if (q) {
1633                                return new NVcvts2fpQ<float>(
1634                                        machInst, vd, vm, 0);
1635                            } else {
1636                                return new NVcvts2fpD<float>(
1637                                        machInst, vd, vm, 0);
1638                            }
1639                        }
1640                    }
1641                }
1642            } else if ((b & 0x1a) == 0x10) {
1643                if (bits(b, 2)) {
1644                    if (q) {
1645                        return new NVrecpeQFp<float>(machInst, vd, vm);
1646                    } else {
1647                        return new NVrecpeDFp<float>(machInst, vd, vm);
1648                    }
1649                } else {
1650                    if (q) {
1651                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1652                    } else {
1653                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1654                    }
1655                }
1656            } else if ((b & 0x1a) == 0x12) {
1657                if (bits(b, 2)) {
1658                    if (q) {
1659                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1660                    } else {
1661                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1662                    }
1663                } else {
1664                    if (q) {
1665                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1666                    } else {
1667                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1668                    }
1669                }
1670            } else {
1671                return new Unknown(machInst);
1672            }
1673        }
1674        return new Unknown(machInst);
1675    }
1676
1677    StaticInstPtr
1678    decodeNeonData(ExtMachInst machInst)
1679    {
1680        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1681        const uint32_t a = bits(machInst, 23, 19);
1682        const uint32_t b = bits(machInst, 11, 8);
1683        const uint32_t c = bits(machInst, 7, 4);
1684        if (bits(a, 4) == 0) {
1685            return decodeNeonThreeRegistersSameLength(machInst);
1686        } else if ((c & 0x9) == 1) {
1687            if ((a & 0x7) == 0) {
1688                return decodeNeonOneRegModImm(machInst);
1689            } else {
1690                return decodeNeonTwoRegAndShift(machInst);
1691            }
1692        } else if ((c & 0x9) == 9) {
1693            return decodeNeonTwoRegAndShift(machInst);
1694        } else if (bits(a, 2, 1) != 0x3) {
1695            if ((c & 0x5) == 0) {
1696                return decodeNeonThreeRegDiffLengths(machInst);
1697            } else if ((c & 0x5) == 4) {
1698                return decodeNeonTwoRegScalar(machInst);
1699            }
1700        } else if ((a & 0x16) == 0x16) {
1701            const IntRegIndex vd =
1702                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1703                                   (bits(machInst, 22) << 4)));
1704            const IntRegIndex vn =
1705                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1706                                   (bits(machInst, 7) << 4)));
1707            const IntRegIndex vm =
1708                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1709                                   (bits(machInst, 5) << 4)));
1710            if (!u) {
1711                if (bits(c, 0) == 0) {
1712                    unsigned imm4 = bits(machInst, 11, 8);
1713                    bool q = bits(machInst, 6);
1714                    if (imm4 >= 16 && !q)
1715                        return new Unknown(machInst);
1716                    if (q) {
1717                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1718                    } else {
1719                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1720                    }
1721                }
1722            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1723                return decodeNeonTwoRegMisc(machInst);
1724            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1725                unsigned length = bits(machInst, 9, 8) + 1;
1726                if ((uint32_t)vn / 2 + length > 32)
1727                    return new Unknown(machInst);
1728                if (bits(machInst, 6) == 0) {
1729                    switch (length) {
1730                      case 1:
1731                        return new NVtbl1(machInst, vd, vn, vm);
1732                      case 2:
1733                        return new NVtbl2(machInst, vd, vn, vm);
1734                      case 3:
1735                        return new NVtbl3(machInst, vd, vn, vm);
1736                      case 4:
1737                        return new NVtbl4(machInst, vd, vn, vm);
1738                    }
1739                } else {
1740                    switch (length) {
1741                      case 1:
1742                        return new NVtbx1(machInst, vd, vn, vm);
1743                      case 2:
1744                        return new NVtbx2(machInst, vd, vn, vm);
1745                      case 3:
1746                        return new NVtbx3(machInst, vd, vn, vm);
1747                      case 4:
1748                        return new NVtbx4(machInst, vd, vn, vm);
1749                    }
1750                }
1751            } else if (b == 0xc && (c & 0x9) == 0) {
1752                unsigned imm4 = bits(machInst, 19, 16);
1753                if (bits(imm4, 2, 0) == 0)
1754                    return new Unknown(machInst);
1755                unsigned size = 0;
1756                while ((imm4 & 0x1) == 0) {
1757                    size++;
1758                    imm4 >>= 1;
1759                }
1760                unsigned index = imm4 >> 1;
1761                const bool q = bits(machInst, 6);
1762                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1763                        q, size, machInst, vd, vm, index);
1764            }
1765        }
1766        return new Unknown(machInst);
1767    }
1768    '''
1769}};
1770
1771def format ThumbNeonMem() {{
1772    decode_block = '''
1773    return decodeNeonMem(machInst);
1774    '''
1775}};
1776
1777def format ThumbNeonData() {{
1778    decode_block = '''
1779    return decodeNeonData(machInst);
1780    '''
1781}};
1782
1783let {{
1784    header_output = '''
1785    StaticInstPtr
1786    decodeExtensionRegLoadStore(ExtMachInst machInst);
1787    '''
1788    decoder_output = '''
1789    StaticInstPtr
1790    decodeExtensionRegLoadStore(ExtMachInst machInst)
1791    {
1792        const uint32_t opcode = bits(machInst, 24, 20);
1793        const uint32_t offset = bits(machInst, 7, 0);
1794        const bool single = (bits(machInst, 8) == 0);
1795        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1796        RegIndex vd;
1797        if (single) {
1798            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1799                                      bits(machInst, 22));
1800        } else {
1801            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1802                                      (bits(machInst, 22) << 5));
1803        }
1804        switch (bits(opcode, 4, 3)) {
1805          case 0x0:
1806            if (bits(opcode, 4, 1) == 0x2 &&
1807                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1808                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1809                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1810                    break;
1811                }
1812                const IntRegIndex rt =
1813                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1814                const IntRegIndex rt2 =
1815                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1816                const bool op = bits(machInst, 20);
1817                uint32_t vm;
1818                if (single) {
1819                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1820                } else {
1821                    vm = (bits(machInst, 3, 0) << 1) |
1822                         (bits(machInst, 5) << 5);
1823                }
1824                if (op) {
1825                    return new Vmov2Core2Reg(machInst, rt, rt2,
1826                                             (IntRegIndex)vm);
1827                } else {
1828                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1829                                             rt, rt2);
1830                }
1831            }
1832            break;
1833          case 0x1:
1834            {
1835                if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1836                    break;
1837                }
1838                switch (bits(opcode, 1, 0)) {
1839                  case 0x0:
1840                    return new VLdmStm(machInst, rn, vd, single,
1841                                       true, false, false, offset);
1842                  case 0x1:
1843                    return new VLdmStm(machInst, rn, vd, single,
1844                                       true, false, true, offset);
1845                  case 0x2:
1846                    return new VLdmStm(machInst, rn, vd, single,
1847                                       true, true, false, offset);
1848                  case 0x3:
1849                    // If rn == sp, then this is called vpop.
1850                    return new VLdmStm(machInst, rn, vd, single,
1851                                       true, true, true, offset);
1852                }
1853            }
1854          case 0x2:
1855            if (bits(opcode, 1, 0) == 0x2) {
1856                // If rn == sp, then this is called vpush.
1857                return new VLdmStm(machInst, rn, vd, single,
1858                                   false, true, false, offset);
1859            } else if (bits(opcode, 1, 0) == 0x3) {
1860                return new VLdmStm(machInst, rn, vd, single,
1861                                   false, true, true, offset);
1862            }
1863            // Fall through on purpose
1864          case 0x3:
1865            const bool up = (bits(machInst, 23) == 1);
1866            const uint32_t imm = bits(machInst, 7, 0) << 2;
1867            RegIndex vd;
1868            if (single) {
1869                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1870                                          (bits(machInst, 22)));
1871            } else {
1872                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1873                                          (bits(machInst, 22) << 5));
1874            }
1875            if (bits(opcode, 1, 0) == 0x0) {
1876                if (single) {
1877                    if (up) {
1878                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1879                    } else {
1880                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1881                    }
1882                } else {
1883                    if (up) {
1884                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1885                                               rn, up, imm);
1886                    } else {
1887                        return new %(vstr_d)s(machInst, vd, vd + 1,
1888                                              rn, up, imm);
1889                    }
1890                }
1891            } else if (bits(opcode, 1, 0) == 0x1) {
1892                if (single) {
1893                    if (up) {
1894                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1895                    } else {
1896                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1897                    }
1898                } else {
1899                    if (up) {
1900                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1901                                               rn, up, imm);
1902                    } else {
1903                        return new %(vldr_d)s(machInst, vd, vd + 1,
1904                                              rn, up, imm);
1905                    }
1906                }
1907            }
1908        }
1909        return new Unknown(machInst);
1910    }
1911    ''' % {
1912        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1913        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1914        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1915        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1916        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1917        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1918        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1919        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1920    }
1921}};
1922
1923def format ExtensionRegLoadStore() {{
1924    decode_block = '''
1925    return decodeExtensionRegLoadStore(machInst);
1926    '''
1927}};
1928
1929let {{
1930    header_output = '''
1931    StaticInstPtr
1932    decodeShortFpTransfer(ExtMachInst machInst);
1933    '''
1934    decoder_output = '''
1935    StaticInstPtr
1936    decodeShortFpTransfer(ExtMachInst machInst)
1937    {
1938        const uint32_t l = bits(machInst, 20);
1939        const uint32_t c = bits(machInst, 8);
1940        const uint32_t a = bits(machInst, 23, 21);
1941        const uint32_t b = bits(machInst, 6, 5);
1942        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1943            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1944            return new Unknown(machInst);
1945        }
1946        if (l == 0 && c == 0) {
1947            if (a == 0) {
1948                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1949                                    bits(machInst, 7);
1950                const IntRegIndex rt =
1951                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1952                if (bits(machInst, 20) == 1) {
1953                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1954                } else {
1955                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1956                }
1957            } else if (a == 0x7) {
1958                const IntRegIndex rt =
1959                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1960                uint32_t specReg = bits(machInst, 19, 16);
1961                switch (specReg) {
1962                  case 0:
1963                    specReg = MISCREG_FPSID;
1964                    break;
1965                  case 1:
1966                    specReg = MISCREG_FPSCR;
1967                    break;
1968                  case 6:
1969                    specReg = MISCREG_MVFR1;
1970                    break;
1971                  case 7:
1972                    specReg = MISCREG_MVFR0;
1973                    break;
1974                  case 8:
1975                    specReg = MISCREG_FPEXC;
1976                    break;
1977                  default:
1978                    return new Unknown(machInst);
1979                }
1980                if (specReg == MISCREG_FPSCR) {
1981                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1982                } else {
1983                    return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1984                }
1985            }
1986        } else if (l == 0 && c == 1) {
1987            if (bits(a, 2) == 0) {
1988                uint32_t vd = (bits(machInst, 7) << 5) |
1989                              (bits(machInst, 19, 16) << 1);
1990                // Handle accessing each single precision half of the vector.
1991                vd += bits(machInst, 21);
1992                const IntRegIndex rt =
1993                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1994                if (bits(machInst, 22) == 1) {
1995                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1996                                            rt, bits(machInst, 6, 5));
1997                } else if (bits(machInst, 5) == 1) {
1998                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1999                                            rt, bits(machInst, 6));
2000                } else if (bits(machInst, 6) == 0) {
2001                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2002                } else {
2003                    return new Unknown(machInst);
2004                }
2005            } else if (bits(b, 1) == 0) {
2006                bool q = bits(machInst, 21);
2007                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2008                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2009                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2010                IntRegIndex rt = (IntRegIndex)(uint32_t)
2011                    bits(machInst, 15, 12);
2012                if (q) {
2013                    switch (be) {
2014                      case 0:
2015                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2016                      case 1:
2017                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2018                      case 2:
2019                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2020                      case 3:
2021                        return new Unknown(machInst);
2022                    }
2023                } else {
2024                    switch (be) {
2025                      case 0:
2026                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2027                      case 1:
2028                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2029                      case 2:
2030                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2031                      case 3:
2032                        return new Unknown(machInst);
2033                    }
2034                }
2035            }
2036        } else if (l == 1 && c == 0) {
2037            if (a == 0) {
2038                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2039                                    bits(machInst, 7);
2040                const IntRegIndex rt =
2041                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042                if (bits(machInst, 20) == 1) {
2043                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2044                } else {
2045                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2046                }
2047            } else if (a == 7) {
2048                const IntRegIndex rt =
2049                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2050                uint32_t specReg = bits(machInst, 19, 16);
2051                switch (specReg) {
2052                  case 0:
2053                    specReg = MISCREG_FPSID;
2054                    break;
2055                  case 1:
2056                    specReg = MISCREG_FPSCR;
2057                    break;
2058                  case 6:
2059                    specReg = MISCREG_MVFR1;
2060                    break;
2061                  case 7:
2062                    specReg = MISCREG_MVFR0;
2063                    break;
2064                  case 8:
2065                    specReg = MISCREG_FPEXC;
2066                    break;
2067                  default:
2068                    return new Unknown(machInst);
2069                }
2070                if (rt == 0xf) {
2071                    if (specReg == MISCREG_FPSCR) {
2072                        return new VmrsApsrFpscr(machInst);
2073                    } else {
2074                        return new Unknown(machInst);
2075                    }
2076                } else if (specReg == MISCREG_FPSCR) {
2077                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2078                } else {
2079                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2080                }
2081            }
2082        } else {
2083            uint32_t vd = (bits(machInst, 7) << 5) |
2084                          (bits(machInst, 19, 16) << 1);
2085            // Handle indexing into each single precision half of the vector.
2086            vd += bits(machInst, 21);
2087            uint32_t index;
2088            const IntRegIndex rt =
2089                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2090            const bool u = (bits(machInst, 23) == 1);
2091            if (bits(machInst, 22) == 1) {
2092                index = bits(machInst, 6, 5);
2093                if (u) {
2094                    return new VmovRegCoreUB(machInst, rt,
2095                                             (IntRegIndex)vd, index);
2096                } else {
2097                    return new VmovRegCoreSB(machInst, rt,
2098                                             (IntRegIndex)vd, index);
2099                }
2100            } else if (bits(machInst, 5) == 1) {
2101                index = bits(machInst, 6);
2102                if (u) {
2103                    return new VmovRegCoreUH(machInst, rt,
2104                                             (IntRegIndex)vd, index);
2105                } else {
2106                    return new VmovRegCoreSH(machInst, rt,
2107                                             (IntRegIndex)vd, index);
2108                }
2109            } else if (bits(machInst, 6) == 0 && !u) {
2110                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2111            } else {
2112                return new Unknown(machInst);
2113            }
2114        }
2115        return new Unknown(machInst);
2116    }
2117    '''
2118}};
2119
2120def format ShortFpTransfer() {{
2121    decode_block = '''
2122    return decodeShortFpTransfer(machInst);
2123    '''
2124}};
2125
2126let {{
2127    header_output = '''
2128    StaticInstPtr
2129    decodeVfpData(ExtMachInst machInst);
2130    '''
2131    decoder_output = '''
2132    StaticInstPtr
2133    decodeVfpData(ExtMachInst machInst)
2134    {
2135        const uint32_t opc1 = bits(machInst, 23, 20);
2136        const uint32_t opc2 = bits(machInst, 19, 16);
2137        const uint32_t opc3 = bits(machInst, 7, 6);
2138        //const uint32_t opc4 = bits(machInst, 3, 0);
2139        const bool single = (bits(machInst, 8) == 0);
2140        // Used to select between vcmp and vcmpe.
2141        const bool e = (bits(machInst, 7) == 1);
2142        IntRegIndex vd;
2143        IntRegIndex vm;
2144        IntRegIndex vn;
2145        if (single) {
2146            vd = (IntRegIndex)(bits(machInst, 22) |
2147                    (bits(machInst, 15, 12) << 1));
2148            vm = (IntRegIndex)(bits(machInst, 5) |
2149                    (bits(machInst, 3, 0) << 1));
2150            vn = (IntRegIndex)(bits(machInst, 7) |
2151                    (bits(machInst, 19, 16) << 1));
2152        } else {
2153            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2154                    (bits(machInst, 15, 12) << 1));
2155            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2156                    (bits(machInst, 3, 0) << 1));
2157            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2158                    (bits(machInst, 19, 16) << 1));
2159        }
2160        switch (opc1 & 0xb /* 1011 */) {
2161          case 0x0:
2162            if (bits(machInst, 6) == 0) {
2163                if (single) {
2164                    return decodeVfpRegRegRegOp<VmlaS>(
2165                            machInst, vd, vn, vm, false);
2166                } else {
2167                    return decodeVfpRegRegRegOp<VmlaD>(
2168                            machInst, vd, vn, vm, true);
2169                }
2170            } else {
2171                if (single) {
2172                    return decodeVfpRegRegRegOp<VmlsS>(
2173                            machInst, vd, vn, vm, false);
2174                } else {
2175                    return decodeVfpRegRegRegOp<VmlsD>(
2176                            machInst, vd, vn, vm, true);
2177                }
2178            }
2179          case 0x1:
2180            if (bits(machInst, 6) == 1) {
2181                if (single) {
2182                    return decodeVfpRegRegRegOp<VnmlaS>(
2183                            machInst, vd, vn, vm, false);
2184                } else {
2185                    return decodeVfpRegRegRegOp<VnmlaD>(
2186                            machInst, vd, vn, vm, true);
2187                }
2188            } else {
2189                if (single) {
2190                    return decodeVfpRegRegRegOp<VnmlsS>(
2191                            machInst, vd, vn, vm, false);
2192                } else {
2193                    return decodeVfpRegRegRegOp<VnmlsD>(
2194                            machInst, vd, vn, vm, true);
2195                }
2196            }
2197          case 0x2:
2198            if ((opc3 & 0x1) == 0) {
2199                if (single) {
2200                    return decodeVfpRegRegRegOp<VmulS>(
2201                            machInst, vd, vn, vm, false);
2202                } else {
2203                    return decodeVfpRegRegRegOp<VmulD>(
2204                            machInst, vd, vn, vm, true);
2205                }
2206            } else {
2207                if (single) {
2208                    return decodeVfpRegRegRegOp<VnmulS>(
2209                            machInst, vd, vn, vm, false);
2210                } else {
2211                    return decodeVfpRegRegRegOp<VnmulD>(
2212                            machInst, vd, vn, vm, true);
2213                }
2214            }
2215          case 0x3:
2216            if ((opc3 & 0x1) == 0) {
2217                if (single) {
2218                    return decodeVfpRegRegRegOp<VaddS>(
2219                            machInst, vd, vn, vm, false);
2220                } else {
2221                    return decodeVfpRegRegRegOp<VaddD>(
2222                            machInst, vd, vn, vm, true);
2223                }
2224            } else {
2225                if (single) {
2226                    return decodeVfpRegRegRegOp<VsubS>(
2227                            machInst, vd, vn, vm, false);
2228                } else {
2229                    return decodeVfpRegRegRegOp<VsubD>(
2230                            machInst, vd, vn, vm, true);
2231                }
2232            }
2233          case 0x8:
2234            if ((opc3 & 0x1) == 0) {
2235                if (single) {
2236                    return decodeVfpRegRegRegOp<VdivS>(
2237                            machInst, vd, vn, vm, false);
2238                } else {
2239                    return decodeVfpRegRegRegOp<VdivD>(
2240                            machInst, vd, vn, vm, true);
2241                }
2242            }
2243            break;
2244          case 0xb:
2245            if ((opc3 & 0x1) == 0) {
2246                const uint32_t baseImm =
2247                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2248                if (single) {
2249                    uint32_t imm = vfp_modified_imm(baseImm, false);
2250                    return decodeVfpRegImmOp<VmovImmS>(
2251                            machInst, vd, imm, false);
2252                } else {
2253                    uint64_t imm = vfp_modified_imm(baseImm, true);
2254                    return decodeVfpRegImmOp<VmovImmD>(
2255                            machInst, vd, imm, true);
2256                }
2257            }
2258            switch (opc2) {
2259              case 0x0:
2260                if (opc3 == 1) {
2261                    if (single) {
2262                        return decodeVfpRegRegOp<VmovRegS>(
2263                                machInst, vd, vm, false);
2264                    } else {
2265                        return decodeVfpRegRegOp<VmovRegD>(
2266                                machInst, vd, vm, true);
2267                    }
2268                } else {
2269                    if (single) {
2270                        return decodeVfpRegRegOp<VabsS>(
2271                                machInst, vd, vm, false);
2272                    } else {
2273                        return decodeVfpRegRegOp<VabsD>(
2274                                machInst, vd, vm, true);
2275                    }
2276                }
2277              case 0x1:
2278                if (opc3 == 1) {
2279                    if (single) {
2280                        return decodeVfpRegRegOp<VnegS>(
2281                                machInst, vd, vm, false);
2282                    } else {
2283                        return decodeVfpRegRegOp<VnegD>(
2284                                machInst, vd, vm, true);
2285                    }
2286                } else {
2287                    if (single) {
2288                        return decodeVfpRegRegOp<VsqrtS>(
2289                                machInst, vd, vm, false);
2290                    } else {
2291                        return decodeVfpRegRegOp<VsqrtD>(
2292                                machInst, vd, vm, true);
2293                    }
2294                }
2295              case 0x2:
2296              case 0x3:
2297                {
2298                    const bool toHalf = bits(machInst, 16);
2299                    const bool top = bits(machInst, 7);
2300                    if (top) {
2301                        if (toHalf) {
2302                            return new VcvtFpSFpHT(machInst, vd, vm);
2303                        } else {
2304                            return new VcvtFpHTFpS(machInst, vd, vm);
2305                        }
2306                    } else {
2307                        if (toHalf) {
2308                            return new VcvtFpSFpHB(machInst, vd, vm);
2309                        } else {
2310                            return new VcvtFpHBFpS(machInst, vd, vm);
2311                        }
2312                    }
2313                }
2314              case 0x4:
2315                if (single) {
2316                    if (e) {
2317                        return new VcmpeS(machInst, vd, vm);
2318                    } else {
2319                        return new VcmpS(machInst, vd, vm);
2320                    }
2321                } else {
2322                    if (e) {
2323                        return new VcmpeD(machInst, vd, vm);
2324                    } else {
2325                        return new VcmpD(machInst, vd, vm);
2326                    }
2327                }
2328              case 0x5:
2329                if (single) {
2330                    if (e) {
2331                        return new VcmpeZeroS(machInst, vd, 0);
2332                    } else {
2333                        return new VcmpZeroS(machInst, vd, 0);
2334                    }
2335                } else {
2336                    if (e) {
2337                        return new VcmpeZeroD(machInst, vd, 0);
2338                    } else {
2339                        return new VcmpZeroD(machInst, vd, 0);
2340                    }
2341                }
2342              case 0x7:
2343                if (opc3 == 0x3) {
2344                    if (single) {
2345                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2346                                (bits(machInst, 15, 12) << 1));
2347                        return new VcvtFpSFpD(machInst, vd, vm);
2348                    } else {
2349                        vd = (IntRegIndex)(bits(machInst, 22) |
2350                                (bits(machInst, 15, 12) << 1));
2351                        return new VcvtFpDFpS(machInst, vd, vm);
2352                    }
2353                }
2354                break;
2355              case 0x8:
2356                if (bits(machInst, 7) == 0) {
2357                    if (single) {
2358                        return new VcvtUIntFpS(machInst, vd, vm);
2359                    } else {
2360                        vm = (IntRegIndex)(bits(machInst, 5) |
2361                                (bits(machInst, 3, 0) << 1));
2362                        return new VcvtUIntFpD(machInst, vd, vm);
2363                    }
2364                } else {
2365                    if (single) {
2366                        return new VcvtSIntFpS(machInst, vd, vm);
2367                    } else {
2368                        vm = (IntRegIndex)(bits(machInst, 5) |
2369                                (bits(machInst, 3, 0) << 1));
2370                        return new VcvtSIntFpD(machInst, vd, vm);
2371                    }
2372                }
2373              case 0xa:
2374                {
2375                    const bool half = (bits(machInst, 7) == 0);
2376                    const uint32_t imm = bits(machInst, 5) |
2377                                         (bits(machInst, 3, 0) << 1);
2378                    const uint32_t size =
2379                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2380                    if (single) {
2381                        if (half) {
2382                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2383                        } else {
2384                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2385                        }
2386                    } else {
2387                        if (half) {
2388                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2389                        } else {
2390                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2391                        }
2392                    }
2393                }
2394              case 0xb:
2395                {
2396                    const bool half = (bits(machInst, 7) == 0);
2397                    const uint32_t imm = bits(machInst, 5) |
2398                                         (bits(machInst, 3, 0) << 1);
2399                    const uint32_t size =
2400                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2401                    if (single) {
2402                        if (half) {
2403                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2404                        } else {
2405                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2406                        }
2407                    } else {
2408                        if (half) {
2409                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2410                        } else {
2411                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2412                        }
2413                    }
2414                }
2415              case 0xc:
2416                if (bits(machInst, 7) == 0) {
2417                    if (single) {
2418                        return new VcvtFpUIntSR(machInst, vd, vm);
2419                    } else {
2420                        vd = (IntRegIndex)(bits(machInst, 22) |
2421                                (bits(machInst, 15, 12) << 1));
2422                        return new VcvtFpUIntDR(machInst, vd, vm);
2423                    }
2424                } else {
2425                    if (single) {
2426                        return new VcvtFpUIntS(machInst, vd, vm);
2427                    } else {
2428                        vd = (IntRegIndex)(bits(machInst, 22) |
2429                                (bits(machInst, 15, 12) << 1));
2430                        return new VcvtFpUIntD(machInst, vd, vm);
2431                    }
2432                }
2433              case 0xd:
2434                if (bits(machInst, 7) == 0) {
2435                    if (single) {
2436                        return new VcvtFpSIntSR(machInst, vd, vm);
2437                    } else {
2438                        vd = (IntRegIndex)(bits(machInst, 22) |
2439                                (bits(machInst, 15, 12) << 1));
2440                        return new VcvtFpSIntDR(machInst, vd, vm);
2441                    }
2442                } else {
2443                    if (single) {
2444                        return new VcvtFpSIntS(machInst, vd, vm);
2445                    } else {
2446                        vd = (IntRegIndex)(bits(machInst, 22) |
2447                                (bits(machInst, 15, 12) << 1));
2448                        return new VcvtFpSIntD(machInst, vd, vm);
2449                    }
2450                }
2451              case 0xe:
2452                {
2453                    const bool half = (bits(machInst, 7) == 0);
2454                    const uint32_t imm = bits(machInst, 5) |
2455                                         (bits(machInst, 3, 0) << 1);
2456                    const uint32_t size =
2457                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2458                    if (single) {
2459                        if (half) {
2460                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2461                        } else {
2462                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2463                        }
2464                    } else {
2465                        if (half) {
2466                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2467                        } else {
2468                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2469                        }
2470                    }
2471                }
2472              case 0xf:
2473                {
2474                    const bool half = (bits(machInst, 7) == 0);
2475                    const uint32_t imm = bits(machInst, 5) |
2476                                         (bits(machInst, 3, 0) << 1);
2477                    const uint32_t size =
2478                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2479                    if (single) {
2480                        if (half) {
2481                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2482                        } else {
2483                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2484                        }
2485                    } else {
2486                        if (half) {
2487                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2488                        } else {
2489                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2490                        }
2491                    }
2492                }
2493            }
2494            break;
2495        }
2496        return new Unknown(machInst);
2497    }
2498    '''
2499}};
2500
2501def format VfpData() {{
2502    decode_block = '''
2503    return decodeVfpData(machInst);
2504    '''
2505}};
2506