fp.isa revision 7643
19814Sandreas.hansson@arm.com// -*- mode:c++ -*-
22292SN/A
312216Snikos.nikoleris@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:
822678Sktlim@umich.edu            return new Base<uint16_t>(machInst, dest, op1, step);
832678Sktlim@umich.edu          case 2:
842292SN/A            return new Base<uint32_t>(machInst, dest, op1, step);
852678Sktlim@umich.edu          case 3:
862678Sktlim@umich.edu            return new Base<uint64_t>(machInst, dest, op1, step);
875336Shines@cs.fsu.edu          default:
882678Sktlim@umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
894873Sstever@eecs.umich.edu        }
902678Sktlim@umich.edu    }
912292SN/A
922678Sktlim@umich.edu}};
932678Sktlim@umich.edu
942678Sktlim@umich.edulet {{
952678Sktlim@umich.edu    header_output = '''
962678Sktlim@umich.edu    StaticInstPtr
972678Sktlim@umich.edu    decodeNeonMem(ExtMachInst machInst);
987852SMatt.Horsnell@arm.com
997852SMatt.Horsnell@arm.com    StaticInstPtr
1002344SN/A    decodeNeonData(ExtMachInst machInst);
10110333Smitch.hayenga@arm.com    '''
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);
1092678Sktlim@umich.edu        const bool singleAll = single && (bits(b, 3, 2) == 3);
1106974Stjones1@inf.ed.ac.uk        const bool load = bits(machInst, 21);
1116974Stjones1@inf.ed.ac.uk
1126974Stjones1@inf.ed.ac.uk        unsigned width = 0;
1136974Stjones1@inf.ed.ac.uk
1146974Stjones1@inf.ed.ac.uk        if (single) {
1159444SAndreas.Sandberg@ARM.com            width = bits(b, 1, 0) + 1;
11610327Smitch.hayenga@arm.com        } else {
1172678Sktlim@umich.edu            switch (bits(b, 3, 1)) {
11812216Snikos.nikoleris@arm.com              case 0x0: width = 4;
11912216Snikos.nikoleris@arm.com                break;
12012216Snikos.nikoleris@arm.com              case 0x1: width = (b & 0x1) ? 2 : 1;
1216974Stjones1@inf.ed.ac.uk                break;
1226974Stjones1@inf.ed.ac.uk              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;
1272678Sktlim@umich.edu                break;
1282678Sktlim@umich.edu              case 0x5:
1292678Sktlim@umich.edu                if ((b & 0x1) == 0) {
1302678Sktlim@umich.edu                    width = 1;
1312678Sktlim@umich.edu                    break;
1322344SN/A                }
1332307SN/A                // Fall through on purpose.
1346974Stjones1@inf.ed.ac.uk              default:
1356974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
1366974Stjones1@inf.ed.ac.uk            }
13710020Smatt.horsnell@ARM.com        }
13810020Smatt.horsnell@ARM.com        assert(width > 0 && width <= 4);
13910023Smatt.horsnell@ARM.com
14010023Smatt.horsnell@ARM.com        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
1412678Sktlim@umich.edu        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
1422292SN/A        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
1432292SN/A                                                 bits(machInst, 22) << 4);
1442292SN/A        const uint32_t type = bits(machInst, 11, 8);
1452292SN/A        uint32_t size = 0;
1468545Ssaidi@eecs.umich.edu        uint32_t align = 0;
14711243Spau.cabre@metempsy.com        unsigned inc = 1;
14811243Spau.cabre@metempsy.com        unsigned regs = 1;
1492292SN/A        unsigned lane = 0;
1502292SN/A        if (single) {
1512292SN/A            if (singleAll) {
1522292SN/A                size = bits(machInst, 7, 6);
1532292SN/A                bool t = bits(machInst, 5);
1545529Snate@binkert.org                unsigned eBytes = (1 << size);
1555529Snate@binkert.org                align = (eBytes - 1) | TLB::AllowUnaligned;
1565529Snate@binkert.org                if (width == 1) {
1572292SN/A                    regs = t ? 2 : 1;
1584329Sktlim@umich.edu                    inc = 1;
1594329Sktlim@umich.edu                } else {
1604329Sktlim@umich.edu                    regs = width;
1612907Sktlim@umich.edu                    inc = t ? 2 : 1;
1622907Sktlim@umich.edu                }
1632292SN/A                switch (width) {
1642292SN/A                  case 1:
16510175SMitch.Hayenga@ARM.com                  case 2:
16610175SMitch.Hayenga@ARM.com                    if (bits(machInst, 4))
1672329SN/A                        align = width * eBytes - 1;
1682329SN/A                    break;
1692329SN/A                  case 3:
1702292SN/A                    break;
1719936SFaissal.Sleiman@arm.com                  case 4:
1729936SFaissal.Sleiman@arm.com                    if (size == 3) {
1739936SFaissal.Sleiman@arm.com                        if (bits(machInst, 4) == 0)
1749936SFaissal.Sleiman@arm.com                            return new Unknown(machInst);
1752292SN/A                        size = 2;
1762292SN/A                        align = 0xf;
1772292SN/A                    } else if (size == 2) {
1788199SAli.Saidi@ARM.com                        if (bits(machInst, 4))
1798199SAli.Saidi@ARM.com                            align = 7;
18011780Sarthur.perais@inria.fr                    } else {
1819444SAndreas.Sandberg@ARM.com                        if (bits(machInst, 4))
1829444SAndreas.Sandberg@ARM.com                            align = 4 * eBytes - 1;
1839444SAndreas.Sandberg@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);
1928199SAli.Saidi@ARM.com                // If width is 1, inc is always 1. That's overridden later.
1932292SN/A                switch (size) {
1942292SN/A                  case 0:
1952292SN/A                    inc = 1;
1962292SN/A                    lane = bits(indexAlign, 3, 1);
19711780Sarthur.perais@inria.fr                    break;
1982292SN/A                  case 1:
1993492Sktlim@umich.edu                    inc = bits(indexAlign, 1) ? 2 : 1;
2002329SN/A                    lane = bits(indexAlign, 3, 2);
2012292SN/A                    break;
2029444SAndreas.Sandberg@ARM.com                  case 2:
2039444SAndreas.Sandberg@ARM.com                    inc = bits(indexAlign, 2) ? 2 : 1;
2049814Sandreas.hansson@arm.com                    lane = bits(indexAlign, 3);
2052292SN/A                    break;
2062292SN/A                }
2072292SN/A                // Override inc for width of 1.
2082292SN/A                if (width == 1) {
2092292SN/A                    inc = 1;
2102292SN/A                }
2112292SN/A                switch (width) {
2122292SN/A                  case 1:
2132292SN/A                    switch (size) {
21410386Sandreas.hansson@arm.com                      case 0:
2152292SN/A                        break;
2162292SN/A                      case 1:
2172292SN/A                        if (bits(indexAlign, 0))
2182292SN/A                            align = 1;
2192292SN/A                        break;
2202727Sktlim@umich.edu                      case 2:
2212727Sktlim@umich.edu                        if (bits(indexAlign, 1, 0))
2222727Sktlim@umich.edu                            align = 3;
2232727Sktlim@umich.edu                        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;
2382361SN/A                        break;
2392361SN/A                      case 2:
2402361SN/A                        if (bits(indexAlign, 0))
2412361SN/A                            align = (4 << bits(indexAlign, 1, 0)) - 1;
2422727Sktlim@umich.edu                        break;
2432727Sktlim@umich.edu                    }
2442727Sktlim@umich.edu                    break;
2452727Sktlim@umich.edu                }
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;
2658922Swilliam.wang@arm.com                    break;
2664329Sktlim@umich.edu                  case 0x6: regs = 3;
2674329Sktlim@umich.edu                    break;
2684329Sktlim@umich.edu                  case 0x2: regs = 4;
2694329Sktlim@umich.edu                    break;
2704329Sktlim@umich.edu                  default:
2714329Sktlim@umich.edu                    return new Unknown(machInst);
2722292SN/A                }
2732292SN/A                break;
2742292SN/A              case 2:
2752292SN/A                // 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:
2869444SAndreas.Sandberg@ARM.com                    return new Unknown(machInst);
2872307SN/A                }
2889444SAndreas.Sandberg@ARM.com                break;
2892367SN/A              case 3:
2902307SN/A                regs = 3;
2912329SN/A                switch (type) {
2929444SAndreas.Sandberg@ARM.com                  case 0x4: inc = 1;
2932307SN/A                    break;
2942307SN/A                  case 0x5: inc = 2;;
2952307SN/A                    break;
2962307SN/A                  default:
2972307SN/A                    return new Unknown(machInst);
2982307SN/A                }
2999444SAndreas.Sandberg@ARM.com                break;
3002307SN/A              case 4:
3012307SN/A                regs = 4;
3022307SN/A                switch (type) {
3032307SN/A                  case 0: inc = 1;
3042292SN/A                    break;
3052292SN/A                  case 1: inc = 2;
3062329SN/A                    break;
3072329SN/A                  default:
3082292SN/A                    return new Unknown(machInst);
3092329SN/A                }
3102329SN/A                break;
3112292SN/A            }
3122292SN/A        }
3132292SN/A
3142292SN/A        if (load) {
3152292SN/A            // Load instructions.
3162329SN/A            if (single) {
3172292SN/A                return new VldSingle(machInst, singleAll, width, rn, vd,
3182292SN/A                                     regs, inc, size, align, rm, lane);
3199936SFaissal.Sleiman@arm.com            } else {
3202292SN/A                return new VldMult(machInst, width, rn, vd,
3212292SN/A                                   regs, inc, size, align, rm);
3222292SN/A            }
3232292SN/A        } else {
3242292SN/A            // Store instructions.
3252292SN/A            if (single) {
3262329SN/A                if (singleAll) {
3272329SN/A                    return new Unknown(machInst);
3282329SN/A                } else {
3292292SN/A                    return new VstSingle(machInst, false, width, rn, vd,
3302292SN/A                                         regs, inc, size, align, rm, lane);
3312292SN/A                }
3322292SN/A            } else {
3332292SN/A                return new VstMult(machInst, width, rn, vd,
3342329SN/A                                   regs, inc, size, align, rm);
3352292SN/A            }
3369936SFaissal.Sleiman@arm.com        }
3379936SFaissal.Sleiman@arm.com        return new Unknown(machInst);
3382292SN/A    }
3392292SN/A    '''
3402292SN/A
3412292SN/A    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)))
3612329SN/A            return new Unknown(machInst);
3622329SN/A        switch (a) {
3632292SN/A          case 0x0:
3647720Sgblack@eecs.umich.edu            if (b) {
3657720Sgblack@eecs.umich.edu                if (u) {
3662292SN/A                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3672292SN/A                            q, size, machInst, vd, vn, vm);
3682292SN/A                } else {
3692292SN/A                    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);
3907720Sgblack@eecs.umich.edu                        }
3917720Sgblack@eecs.umich.edu                      case 1:
3922292SN/A                        if (q) {
3932292SN/A                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3942292SN/A                        } else {
3952292SN/A                            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 {
41610239Sbinhpham@cs.rutgers.edu                            return new VandD<uint64_t>(machInst, vd, vn, vm);
4172292SN/A                        }
41810239Sbinhpham@cs.rutgers.edu                      case 1:
41910239Sbinhpham@cs.rutgers.edu                        if (q) {
42010239Sbinhpham@cs.rutgers.edu                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
42110239Sbinhpham@cs.rutgers.edu                        } else {
42210239Sbinhpham@cs.rutgers.edu                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
4232292SN/A                        }
42410239Sbinhpham@cs.rutgers.edu                      case 2:
42510239Sbinhpham@cs.rutgers.edu                        if (vn == vm) {
42610239Sbinhpham@cs.rutgers.edu                            if (q) {
42710239Sbinhpham@cs.rutgers.edu                                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 {
4342292SN/A                            if (q) {
4352292SN/A                                return new VorrQ<uint64_t>(
4368545Ssaidi@eecs.umich.edu                                        machInst, vd, vn, vm);
4378545Ssaidi@eecs.umich.edu                            } else {
4388545Ssaidi@eecs.umich.edu                                return new VorrD<uint64_t>(
43911357Sstephan.diestelhorst@arm.com                                        machInst, vd, vn, vm);
44011357Sstephan.diestelhorst@arm.com                            }
44111357Sstephan.diestelhorst@arm.com                        }
4428545Ssaidi@eecs.umich.edu                      case 3:
44310030SAli.Saidi@ARM.com                        if (q) {
4448545Ssaidi@eecs.umich.edu                            return new VornQ<uint64_t>(
44511356Skrinat01@arm.com                                    machInst, vd, vn, vm);
44611356Skrinat01@arm.com                        } else {
44710030SAli.Saidi@ARM.com                            return new VornD<uint64_t>(
4489383SAli.Saidi@ARM.com                                    machInst, vd, vn, vm);
4499383SAli.Saidi@ARM.com                        }
4509383SAli.Saidi@ARM.com                    }
4519383SAli.Saidi@ARM.com                }
4529383SAli.Saidi@ARM.com            }
4539383SAli.Saidi@ARM.com          case 0x2:
4549383SAli.Saidi@ARM.com            if (b) {
45510030SAli.Saidi@ARM.com                if (u) {
45610030SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
45710030SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
45810030SAli.Saidi@ARM.com                } else {
45911097Songal@cs.wisc.edu                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
46011097Songal@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
46111097Songal@cs.wisc.edu                }
46210030SAli.Saidi@ARM.com            } else {
46311097Songal@cs.wisc.edu                if (size == 3)
46411097Songal@cs.wisc.edu                    return new Unknown(machInst);
46511097Songal@cs.wisc.edu                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>(
48010824SAndreas.Sandberg@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                }
48511097Songal@cs.wisc.edu            } else {
48611097Songal@cs.wisc.edu                return decodeNeonUSThreeReg<VshlD, VshlQ>(
48711097Songal@cs.wisc.edu                        q, u, size, machInst, vd, vm, vn);
4888545Ssaidi@eecs.umich.edu            }
48911097Songal@cs.wisc.edu          case 0x5:
4908545Ssaidi@eecs.umich.edu            if (b) {
49111097Songal@cs.wisc.edu                if (u) {
49211097Songal@cs.wisc.edu                    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);
49710149Smarco.elver@ed.ac.uk                }
49810149Smarco.elver@ed.ac.uk            } else {
49910149Smarco.elver@ed.ac.uk                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
5008545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vm, vn);
50110030SAli.Saidi@ARM.com            }
5028545Ssaidi@eecs.umich.edu          case 0x6:
5038545Ssaidi@eecs.umich.edu            if (b) {
50410474Sandreas.hansson@arm.com                return decodeNeonUSThreeReg<VminD, VminQ>(
5058545Ssaidi@eecs.umich.edu                        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) {
51210030SAli.Saidi@ARM.com                return decodeNeonUSThreeReg<VabaD, VabaQ>(
51310030SAli.Saidi@ARM.com                        q, u, size, machInst, vd, vn, vm);
51410030SAli.Saidi@ARM.com            } else {
5158545Ssaidi@eecs.umich.edu                if (bits(machInst, 23) == 1) {
5168545Ssaidi@eecs.umich.edu                    if (q) {
5178545Ssaidi@eecs.umich.edu                        return new Unknown(machInst);
5189046SAli.Saidi@ARM.com                    } 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>(
5248545Ssaidi@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5258545Ssaidi@eecs.umich.edu                }
5268545Ssaidi@eecs.umich.edu            }
5272292SN/A          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 {
5378199SAli.Saidi@ARM.com                if (u) {
5388199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5398199SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
54010824SAndreas.Sandberg@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:
5468199SAli.Saidi@ARM.com            if (b) {
5478199SAli.Saidi@ARM.com                if (u) {
5488199SAli.Saidi@ARM.com                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5498272SAli.Saidi@ARM.com                            q, size, machInst, vd, vn, vm);
5508545Ssaidi@eecs.umich.edu                } else {
5518545Ssaidi@eecs.umich.edu                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
5528545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5538545Ssaidi@eecs.umich.edu                }
5549046SAli.Saidi@ARM.com            } else {
5558545Ssaidi@eecs.umich.edu                if (u) {
5568545Ssaidi@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
5578545Ssaidi@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5588592Sgblack@eecs.umich.edu                } else {
5598592Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
5608545Ssaidi@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5618199SAli.Saidi@ARM.com                }
5628545Ssaidi@eecs.umich.edu            }
5638199SAli.Saidi@ARM.com          case 0xa:
56410474Sandreas.hansson@arm.com            if (b) {
56510474Sandreas.hansson@arm.com                return decodeNeonUSThreeReg<VpminD, VpminQ>(
56610474Sandreas.hansson@arm.com                        q, u, size, machInst, vd, vn, vm);
56710474Sandreas.hansson@arm.com            } else {
5688545Ssaidi@eecs.umich.edu                return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
5698545Ssaidi@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5708199SAli.Saidi@ARM.com            }
5718545Ssaidi@eecs.umich.edu          case 0xb:
5728545Ssaidi@eecs.umich.edu            if (b) {
5739046SAli.Saidi@ARM.com                if (u) {
57410575SMarco.Elver@ARM.com                    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) {
5818545Ssaidi@eecs.umich.edu                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
5828545Ssaidi@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5838545Ssaidi@eecs.umich.edu                } else {
5848592Sgblack@eecs.umich.edu                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
5858592Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5868592Sgblack@eecs.umich.edu                }
5878545Ssaidi@eecs.umich.edu            }
5888545Ssaidi@eecs.umich.edu          case 0xc:
5898545Ssaidi@eecs.umich.edu            return new Unknown(machInst);
5908545Ssaidi@eecs.umich.edu          case 0xd:
59110474Sandreas.hansson@arm.com            if (b) {
59210474Sandreas.hansson@arm.com                if (u) {
59310474Sandreas.hansson@arm.com                    if (bits(c, 1) == 0) {
59410474Sandreas.hansson@arm.com                        if (q) {
5958545Ssaidi@eecs.umich.edu                            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) {
6048199SAli.Saidi@ARM.com                        if (q) {
6058199SAli.Saidi@ARM.com                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6068199SAli.Saidi@ARM.com                        } else {
6078199SAli.Saidi@ARM.com                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
6082292SN/A                        }
6092292SN/A                    } else {
6104032Sktlim@umich.edu                        if (q) {
6112292SN/A                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
6122292SN/A                        } else {
6132292SN/A                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
6147720Sgblack@eecs.umich.edu                        }
6157944SGiacomo.Gabrielli@arm.com                    }
6162292SN/A                }
6174032Sktlim@umich.edu            } else {
6184032Sktlim@umich.edu                if (u) {
6192669Sktlim@umich.edu                    if (bits(c, 1) == 0) {
6202292SN/A                        if (q) {
6217944SGiacomo.Gabrielli@arm.com                            return new VpaddQFp<float>(machInst, vd, vn, vm);
6227944SGiacomo.Gabrielli@arm.com                        } else {
6237944SGiacomo.Gabrielli@arm.com                            return new VpaddDFp<float>(machInst, vd, vn, vm);
6247944SGiacomo.Gabrielli@arm.com                        }
6257597Sminkyu.jeong@arm.com                    } else {
6267597Sminkyu.jeong@arm.com                        if (q) {
62710231Ssteve.reinhardt@amd.com                            return new VabdQFp<float>(machInst, vd, vn, vm);
6282329SN/A                        } else {
62910824SAndreas.Sandberg@ARM.com                            return new VabdDFp<float>(machInst, vd, vn, vm);
63010824SAndreas.Sandberg@ARM.com                        }
63110824SAndreas.Sandberg@ARM.com                    }
63210231Ssteve.reinhardt@amd.com                } else {
6337848SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
6347600Sminkyu.jeong@arm.com                        if (q) {
6357600Sminkyu.jeong@arm.com                            return new VaddQFp<float>(machInst, vd, vn, vm);
6367600Sminkyu.jeong@arm.com                        } else {
63710824SAndreas.Sandberg@ARM.com                            return new VaddDFp<float>(machInst, vd, vn, vm);
6383731Sktlim@umich.edu                        }
6392367SN/A                    } else {
6402367SN/A                        if (q) {
6412292SN/A                            return new VsubQFp<float>(machInst, vd, vn, vm);
6422292SN/A                        } else {
64310333Smitch.hayenga@arm.com                            return new VsubDFp<float>(machInst, vd, vn, vm);
6449046SAli.Saidi@ARM.com                        }
6454032Sktlim@umich.edu                    }
6464032Sktlim@umich.edu                }
6474032Sktlim@umich.edu            }
6488199SAli.Saidi@ARM.com          case 0xe:
6498199SAli.Saidi@ARM.com            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 {
6612292SN/A                            return new VacgtDFp<float>(machInst, vd, vn, vm);
6622292SN/A                        }
6632292SN/A                    }
6642292SN/A                } else {
6657720Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6667720Sgblack@eecs.umich.edu                }
6672292SN/A            } else {
6684032Sktlim@umich.edu                if (u) {
6694032Sktlim@umich.edu                    if (bits(c, 1) == 0) {
6702292SN/A                        if (q) {
6712292SN/A                            return new VcgeQFp<float>(machInst, vd, vn, vm);
6722292SN/A                        } else {
6732292SN/A                            return new VcgeDFp<float>(machInst, vd, vn, vm);
6742292SN/A                        }
6752292SN/A                    } else {
6767944SGiacomo.Gabrielli@arm.com                        if (q) {
6777944SGiacomo.Gabrielli@arm.com                            return new VcgtQFp<float>(machInst, vd, vn, vm);
6787944SGiacomo.Gabrielli@arm.com                        } else {
6797944SGiacomo.Gabrielli@arm.com                            return new VcgtDFp<float>(machInst, vd, vn, vm);
68012217Snikos.nikoleris@arm.com                        }
68112217Snikos.nikoleris@arm.com                    }
68212217Snikos.nikoleris@arm.com                } else {
6837848SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
68412217Snikos.nikoleris@arm.com                        if (q) {
68512217Snikos.nikoleris@arm.com                            return new VceqQFp<float>(machInst, vd, vn, vm);
6867848SAli.Saidi@ARM.com                        } else {
6872329SN/A                            return new VceqDFp<float>(machInst, vd, vn, vm);
6887782Sminkyu.jeong@arm.com                        }
6897720Sgblack@eecs.umich.edu                    } else {
6902292SN/A                        return new Unknown(machInst);
6912292SN/A                    }
6922292SN/A                }
6932292SN/A            }
6942292SN/A          case 0xf:
6952292SN/A            if (b) {
6962336SN/A                if (u) {
6972336SN/A                    return new Unknown(machInst);
6982336SN/A                } else {
6992329SN/A                    if (bits(c, 1) == 0) {
7002292SN/A                        if (q) {
7012329SN/A                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
7022292SN/A                        } else {
7032292SN/A                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
7048199SAli.Saidi@ARM.com                        }
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);
7102292SN/A                        }
7112292SN/A                    }
7122292SN/A                }
7132292SN/A            } else {
7147720Sgblack@eecs.umich.edu                if (u) {
7157720Sgblack@eecs.umich.edu                    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                        }
7412292SN/A                    }
7422292SN/A                }
7432292SN/A            }
7442292SN/A        }
7452329SN/A        return new Unknown(machInst);
7462329SN/A    }
7472292SN/A
7482292SN/A    static StaticInstPtr
7492292SN/A    decodeNeonOneRegModImm(ExtMachInst machInst)
7502292SN/A    {
7512292SN/A        const IntRegIndex vd =
7527720Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
7537720Sgblack@eecs.umich.edu                               (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        const uint64_t bigImm = simd_modified_imm(op, cmode, imm);
7622292SN/A        if (op) {
7632292SN/A            if (bits(cmode, 3) == 0) {
7642292SN/A                if (bits(cmode, 0) == 0) {
7652292SN/A                    if (q)
7662292SN/A                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7676974Stjones1@inf.ed.ac.uk                    else
7686974Stjones1@inf.ed.ac.uk                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7696974Stjones1@inf.ed.ac.uk                } else {
7706974Stjones1@inf.ed.ac.uk                    if (q)
7716974Stjones1@inf.ed.ac.uk                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
7726974Stjones1@inf.ed.ac.uk                    else
7736974Stjones1@inf.ed.ac.uk                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
7746974Stjones1@inf.ed.ac.uk                }
7756974Stjones1@inf.ed.ac.uk            } else {
7766974Stjones1@inf.ed.ac.uk                if (bits(cmode, 2) == 1) {
7776974Stjones1@inf.ed.ac.uk                    switch (bits(cmode, 1, 0)) {
7786974Stjones1@inf.ed.ac.uk                      case 0:
7796974Stjones1@inf.ed.ac.uk                      case 1:
7806974Stjones1@inf.ed.ac.uk                        if (q)
7816974Stjones1@inf.ed.ac.uk                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7826974Stjones1@inf.ed.ac.uk                        else
7832292SN/A                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7842292SN/A                      case 2:
7856974Stjones1@inf.ed.ac.uk                        if (q)
7866974Stjones1@inf.ed.ac.uk                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
7876974Stjones1@inf.ed.ac.uk                        else
7886974Stjones1@inf.ed.ac.uk                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
7896974Stjones1@inf.ed.ac.uk                      case 3:
7906974Stjones1@inf.ed.ac.uk                        if (q)
7912292SN/A                            return new Unknown(machInst);
7922292SN/A                        else
7932292SN/A                            return new Unknown(machInst);
7942292SN/A                    }
7958727Snilay@cs.wisc.edu                } else {
79611780Sarthur.perais@inria.fr                    if (bits(cmode, 0) == 0) {
7972292SN/A                        if (q)
79810333Smitch.hayenga@arm.com                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7992678Sktlim@umich.edu                        else
8002678Sktlim@umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8012678Sktlim@umich.edu                    } else {
8022678Sktlim@umich.edu                        if (q)
8032678Sktlim@umich.edu                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8042329SN/A                        else
8052329SN/A                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8062292SN/A                    }
8072292SN/A                }
8082292SN/A            }
8092292SN/A        } else {
8102292SN/A            if (bits(cmode, 3) == 0) {
8112292SN/A                if (bits(cmode, 0) == 0) {
8122292SN/A                    if (q)
8132678Sktlim@umich.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
81411780Sarthur.perais@inria.fr                    else
8152292SN/A                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8162292SN/A                } else {
8172292SN/A                    if (q)
8182292SN/A                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8192292SN/A                    else
8202292SN/A                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8212292SN/A                }
8222292SN/A            } else {
8232292SN/A                if (bits(cmode, 2) == 1) {
8242292SN/A                    if (q)
8256974Stjones1@inf.ed.ac.uk                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8266974Stjones1@inf.ed.ac.uk                    else
8276974Stjones1@inf.ed.ac.uk                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8286974Stjones1@inf.ed.ac.uk                } else {
8296974Stjones1@inf.ed.ac.uk                    if (bits(cmode, 0) == 0) {
8302669Sktlim@umich.edu                        if (q)
8312669Sktlim@umich.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
83212749Sgiacomo.travaglini@arm.com                        else
83312749Sgiacomo.travaglini@arm.com                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
83412749Sgiacomo.travaglini@arm.com                    } else {
8358481Sgblack@eecs.umich.edu                        if (q)
8362292SN/A                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8372292SN/A                        else
8382669Sktlim@umich.edu                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
83910031SAli.Saidi@ARM.com                    }
8403772Sgblack@eecs.umich.edu                }
84110031SAli.Saidi@ARM.com            }
84210031SAli.Saidi@ARM.com        }
84310031SAli.Saidi@ARM.com        return new Unknown(machInst);
84410031SAli.Saidi@ARM.com    }
8452669Sktlim@umich.edu
8466974Stjones1@inf.ed.ac.uk    static StaticInstPtr
8476974Stjones1@inf.ed.ac.uk    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8482292SN/A    {
8492678Sktlim@umich.edu        const uint32_t a = bits(machInst, 11, 8);
8502678Sktlim@umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
8512678Sktlim@umich.edu        const bool b = bits(machInst, 6);
8522678Sktlim@umich.edu        const bool l = bits(machInst, 7);
8536974Stjones1@inf.ed.ac.uk        const IntRegIndex vd =
8546974Stjones1@inf.ed.ac.uk            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
8556974Stjones1@inf.ed.ac.uk                               (bits(machInst, 22) << 4)));
8566974Stjones1@inf.ed.ac.uk        const IntRegIndex vm =
85710342SCurtis.Dunham@arm.com            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
8586974Stjones1@inf.ed.ac.uk                               (bits(machInst, 5) << 4)));
8596974Stjones1@inf.ed.ac.uk        unsigned imm6 = bits(machInst, 21, 16);
8606974Stjones1@inf.ed.ac.uk        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
8616974Stjones1@inf.ed.ac.uk        unsigned size = 3;
86210342SCurtis.Dunham@arm.com        unsigned lShiftAmt = 0;
86310342SCurtis.Dunham@arm.com        unsigned bitSel;
8646974Stjones1@inf.ed.ac.uk        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8656974Stjones1@inf.ed.ac.uk            if (bitSel & imm)
8666974Stjones1@inf.ed.ac.uk                break;
8676974Stjones1@inf.ed.ac.uk            else if (!size)
8686974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
8696974Stjones1@inf.ed.ac.uk            size--;
8706974Stjones1@inf.ed.ac.uk        }
8716974Stjones1@inf.ed.ac.uk        lShiftAmt = imm6 & ~bitSel;
8726974Stjones1@inf.ed.ac.uk        unsigned rShiftAmt = 0;
8736974Stjones1@inf.ed.ac.uk        if (a != 0xe && a != 0xf) {
8746974Stjones1@inf.ed.ac.uk            if (size > 2)
8756974Stjones1@inf.ed.ac.uk                rShiftAmt = 64 - imm6;
8766974Stjones1@inf.ed.ac.uk            else
8772678Sktlim@umich.edu                rShiftAmt = 2 * (8 << size) - imm6;
8787720Sgblack@eecs.umich.edu        }
8792292SN/A
8807720Sgblack@eecs.umich.edu        switch (a) {
8813797Sgblack@eecs.umich.edu          case 0x0:
8823221Sktlim@umich.edu            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
8832292SN/A                    b, u, size, machInst, vd, vm, rShiftAmt);
8842693Sktlim@umich.edu          case 0x1:
8854350Sgblack@eecs.umich.edu            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
8866974Stjones1@inf.ed.ac.uk                    b, u, size, machInst, vd, vm, rShiftAmt);
8873326Sktlim@umich.edu          case 0x2:
8883326Sktlim@umich.edu            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
8893326Sktlim@umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
8909046SAli.Saidi@ARM.com          case 0x3:
89110030SAli.Saidi@ARM.com            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
8929046SAli.Saidi@ARM.com                    b, u, size, machInst, vd, vm, rShiftAmt);
8933326Sktlim@umich.edu          case 0x4:
8943326Sktlim@umich.edu            if (u) {
8953326Sktlim@umich.edu                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
8963326Sktlim@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
8973326Sktlim@umich.edu            } else {
8983326Sktlim@umich.edu                return new Unknown(machInst);
8993326Sktlim@umich.edu            }
9007823Ssteve.reinhardt@amd.com          case 0x5:
9013326Sktlim@umich.edu            if (u) {
9023326Sktlim@umich.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9033326Sktlim@umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9042693Sktlim@umich.edu            } else {
9052693Sktlim@umich.edu                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9062693Sktlim@umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9072693Sktlim@umich.edu            }
9082693Sktlim@umich.edu          case 0x6:
9092693Sktlim@umich.edu          case 0x7:
9108481Sgblack@eecs.umich.edu            if (u) {
9118481Sgblack@eecs.umich.edu                if (a == 0x6) {
9128481Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9138481Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9148481Sgblack@eecs.umich.edu                } else {
9158481Sgblack@eecs.umich.edu                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
9168481Sgblack@eecs.umich.edu                            b, size, machInst, vd, vm, lShiftAmt);
9178481Sgblack@eecs.umich.edu                }
9188481Sgblack@eecs.umich.edu            } else {
9198481Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9208481Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
9218481Sgblack@eecs.umich.edu            }
9228481Sgblack@eecs.umich.edu          case 0x8:
9238481Sgblack@eecs.umich.edu            if (l) {
9248481Sgblack@eecs.umich.edu                return new Unknown(machInst);
9258481Sgblack@eecs.umich.edu            } else if (u) {
9268481Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9278481Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9284032Sktlim@umich.edu            } else {
9293221Sktlim@umich.edu                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
9303221Sktlim@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9316974Stjones1@inf.ed.ac.uk            }
9326974Stjones1@inf.ed.ac.uk          case 0x9:
9338481Sgblack@eecs.umich.edu            if (l) {
9346974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
9356974Stjones1@inf.ed.ac.uk            } else if (u) {
9366974Stjones1@inf.ed.ac.uk                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
9372669Sktlim@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9386974Stjones1@inf.ed.ac.uk            } else {
9396974Stjones1@inf.ed.ac.uk                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
9408481Sgblack@eecs.umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9416974Stjones1@inf.ed.ac.uk            }
9426974Stjones1@inf.ed.ac.uk          case 0xa:
9436974Stjones1@inf.ed.ac.uk            if (l || b) {
94411780Sarthur.perais@inria.fr                return new Unknown(machInst);
94511780Sarthur.perais@inria.fr            } else {
9466974Stjones1@inf.ed.ac.uk                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9476974Stjones1@inf.ed.ac.uk                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9486974Stjones1@inf.ed.ac.uk            }
9496974Stjones1@inf.ed.ac.uk          case 0xe:
9506974Stjones1@inf.ed.ac.uk            if (l) {
9516974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
9526974Stjones1@inf.ed.ac.uk            } else {
9536974Stjones1@inf.ed.ac.uk                if (bits(imm6, 5) == 0)
9546974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
9556974Stjones1@inf.ed.ac.uk                if (u) {
9566974Stjones1@inf.ed.ac.uk                    if (b) {
9576974Stjones1@inf.ed.ac.uk                        return new NVcvtu2fpQ<float>(
9586974Stjones1@inf.ed.ac.uk                                machInst, vd, vm, 64 - imm6);
9596974Stjones1@inf.ed.ac.uk                    } else {
9606974Stjones1@inf.ed.ac.uk                        return new NVcvtu2fpD<float>(
9616974Stjones1@inf.ed.ac.uk                                machInst, vd, vm, 64 - imm6);
9626974Stjones1@inf.ed.ac.uk                    }
9636974Stjones1@inf.ed.ac.uk                } else {
9646974Stjones1@inf.ed.ac.uk                    if (b) {
9652292SN/A                        return new NVcvts2fpQ<float>(
9662292SN/A                                machInst, vd, vm, 64 - imm6);
9672292SN/A                    } else {
9682292SN/A                        return new NVcvts2fpD<float>(
96911780Sarthur.perais@inria.fr                                machInst, vd, vm, 64 - imm6);
9702292SN/A                    }
9712292SN/A                }
9722292SN/A            }
9732292SN/A          case 0xf:
9742292SN/A            if (l) {
9752292SN/A                return new Unknown(machInst);
9762292SN/A            } else {
9772292SN/A                if (bits(imm6, 5) == 0)
9782292SN/A                    return new Unknown(machInst);
9792292SN/A                if (u) {
9802292SN/A                    if (b) {
9812292SN/A                        return new NVcvt2ufxQ<float>(
9822292SN/A                                machInst, vd, vm, 64 - imm6);
9832292SN/A                    } else {
9842292SN/A                        return new NVcvt2ufxD<float>(
9852292SN/A                                machInst, vd, vm, 64 - imm6);
9862292SN/A                    }
9872292SN/A                } else {
9882292SN/A                    if (b) {
9892292SN/A                        return new NVcvt2sfxQ<float>(
9902292SN/A                                machInst, vd, vm, 64 - imm6);
9912292SN/A                    } else {
9922292SN/A                        return new NVcvt2sfxD<float>(
9932329SN/A                                machInst, vd, vm, 64 - imm6);
9942292SN/A                    }
9952292SN/A                }
9962292SN/A            }
9972292SN/A        }
9982292SN/A        return new Unknown(machInst);
9997720Sgblack@eecs.umich.edu    }
10002292SN/A
10017720Sgblack@eecs.umich.edu    static StaticInstPtr
10022292SN/A    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
10032292SN/A    {
10042292SN/A        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10052292SN/A        const uint32_t a = bits(machInst, 11, 8);
10062292SN/A        const IntRegIndex vd =
10072292SN/A            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
10082292SN/A                               (bits(machInst, 22) << 4)));
10092292SN/A        const IntRegIndex vn =
10102329SN/A            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
10112731Sktlim@umich.edu                               (bits(machInst, 7) << 4)));
10122292SN/A        const IntRegIndex vm =
10132292SN/A            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10142292SN/A                               (bits(machInst, 5) << 4)));
10152292SN/A        const unsigned size = bits(machInst, 21, 20);
10162292SN/A        switch (a) {
10172292SN/A          case 0x0:
10182292SN/A            return decodeNeonUSThreeUSReg<Vaddl>(
10192727Sktlim@umich.edu                    u, size, machInst, vd, vn, vm);
10202292SN/A          case 0x1:
10212292SN/A            return decodeNeonUSThreeUSReg<Vaddw>(
10224032Sktlim@umich.edu                    u, size, machInst, vd, vn, vm);
10234032Sktlim@umich.edu          case 0x2:
10244032Sktlim@umich.edu            return decodeNeonUSThreeUSReg<Vsubl>(
10254032Sktlim@umich.edu                    u, size, machInst, vd, vn, vm);
10262292SN/A          case 0x3:
10272292SN/A            return decodeNeonUSThreeUSReg<Vsubw>(
10282292SN/A                    u, size, machInst, vd, vn, vm);
10292292SN/A          case 0x4:
10302292SN/A            if (u) {
10312329SN/A                return decodeNeonUThreeUSReg<Vraddhn>(
10322292SN/A                        size, machInst, vd, vn, vm);
10332292SN/A            } else {
10342292SN/A                return decodeNeonUThreeUSReg<Vaddhn>(
10352292SN/A                        size, machInst, vd, vn, vm);
10367720Sgblack@eecs.umich.edu            }
10372292SN/A          case 0x5:
10387720Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vabal>(
10392292SN/A                    u, size, machInst, vd, vn, vm);
10402292SN/A          case 0x6:
10412329SN/A            if (u) {
10422329SN/A                return decodeNeonUThreeUSReg<Vrsubhn>(
10432292SN/A                        size, machInst, vd, vn, vm);
10442292SN/A            } else {
10452292SN/A                return decodeNeonUThreeUSReg<Vsubhn>(
10462292SN/A                        size, machInst, vd, vn, vm);
10472292SN/A            }
10482292SN/A          case 0x7:
10492292SN/A            if (bits(machInst, 23)) {
10502329SN/A                return decodeNeonUSThreeUSReg<Vabdl>(
10512731Sktlim@umich.edu                        u, size, machInst, vd, vn, vm);
10522292SN/A            } else {
10532292SN/A                return decodeNeonUSThreeReg<VabdD, VabdQ>(
10542292SN/A                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
10554032Sktlim@umich.edu            }
10564032Sktlim@umich.edu          case 0x8:
10574032Sktlim@umich.edu            return decodeNeonUSThreeUSReg<Vmlal>(
105812749Sgiacomo.travaglini@arm.com                    u, size, machInst, vd, vn, vm);
10596974Stjones1@inf.ed.ac.uk          case 0xa:
106012749Sgiacomo.travaglini@arm.com            return decodeNeonUSThreeUSReg<Vmlsl>(
106112749Sgiacomo.travaglini@arm.com                    u, size, machInst, vd, vn, vm);
10626974Stjones1@inf.ed.ac.uk          case 0x9:
10634032Sktlim@umich.edu            if (u) {
10642292SN/A                return new Unknown(machInst);
10652292SN/A            } else {
10662292SN/A                return decodeNeonSThreeUSReg<Vqdmlal>(
10672292SN/A                        size, machInst, vd, vn, vm);
10682292SN/A            }
10692292SN/A          case 0xb:
10702727Sktlim@umich.edu            if (u) {
10712292SN/A                return new Unknown(machInst);
10722292SN/A            } else {
10732292SN/A                return decodeNeonSThreeUSReg<Vqdmlsl>(
10742292SN/A                        size, machInst, vd, vn, vm);
10752292SN/A            }
10763349Sbinkertn@umich.edu          case 0xc:
10772693Sktlim@umich.edu            return decodeNeonUSThreeUSReg<Vmull>(
10782693Sktlim@umich.edu                    u, size, machInst, vd, vn, vm);
10792693Sktlim@umich.edu          case 0xd:
10802693Sktlim@umich.edu            if (u) {
10812693Sktlim@umich.edu                return new Unknown(machInst);
10822693Sktlim@umich.edu            } else {
10832693Sktlim@umich.edu                return decodeNeonSThreeUSReg<Vqdmull>(
10842693Sktlim@umich.edu                        size, machInst, vd, vn, vm);
10852693Sktlim@umich.edu            }
10862693Sktlim@umich.edu          case 0xe:
10872693Sktlim@umich.edu            return decodeNeonUThreeUSReg<Vmullp>(
10882693Sktlim@umich.edu                    size, machInst, vd, vn, vm);
10892693Sktlim@umich.edu        }
10902693Sktlim@umich.edu        return new Unknown(machInst);
10912693Sktlim@umich.edu    }
10922693Sktlim@umich.edu
10938887Sgeoffrey.blake@arm.com    static StaticInstPtr
10942693Sktlim@umich.edu    decodeNeonTwoRegScalar(ExtMachInst machInst)
10952732Sktlim@umich.edu    {
10962693Sktlim@umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10972693Sktlim@umich.edu        const uint32_t a = bits(machInst, 11, 8);
10982693Sktlim@umich.edu        const unsigned size = bits(machInst, 21, 20);
10998727Snilay@cs.wisc.edu        const IntRegIndex vd =
11008727Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11018727Snilay@cs.wisc.edu                               (bits(machInst, 22) << 4)));
11028727Snilay@cs.wisc.edu        const IntRegIndex vn =
11032693Sktlim@umich.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11042693Sktlim@umich.edu                               (bits(machInst, 7) << 4)));
11052693Sktlim@umich.edu        const IntRegIndex vm = (size == 2) ?
11062693Sktlim@umich.edu            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
11072693Sktlim@umich.edu            (IntRegIndex)(2 * bits(machInst, 2, 0));
11082678Sktlim@umich.edu        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11092678Sktlim@umich.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11102678Sktlim@umich.edu        switch (a) {
11112678Sktlim@umich.edu          case 0x0:
11122678Sktlim@umich.edu            if (u) {
11132678Sktlim@umich.edu                switch (size) {
11142678Sktlim@umich.edu                  case 1:
11152727Sktlim@umich.edu                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
11162678Sktlim@umich.edu                  case 2:
11172678Sktlim@umich.edu                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
11182678Sktlim@umich.edu                  default:
11192678Sktlim@umich.edu                    return new Unknown(machInst);
11202678Sktlim@umich.edu                }
11212678Sktlim@umich.edu            } else {
112210575SMarco.Elver@ARM.com                switch (size) {
112310575SMarco.Elver@ARM.com                  case 1:
112410575SMarco.Elver@ARM.com                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
112510575SMarco.Elver@ARM.com                  case 2:
112610575SMarco.Elver@ARM.com                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
112710575SMarco.Elver@ARM.com                  default:
112810575SMarco.Elver@ARM.com                    return new Unknown(machInst);
112910575SMarco.Elver@ARM.com                }
113010575SMarco.Elver@ARM.com            }
113110575SMarco.Elver@ARM.com          case 0x1:
113210575SMarco.Elver@ARM.com            if (u)
113310575SMarco.Elver@ARM.com                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
113410575SMarco.Elver@ARM.com            else
113510575SMarco.Elver@ARM.com                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
11362678Sktlim@umich.edu          case 0x4:
11372678Sktlim@umich.edu            if (u) {
11382678Sktlim@umich.edu                switch (size) {
11392678Sktlim@umich.edu                  case 1:
11402678Sktlim@umich.edu                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11412678Sktlim@umich.edu                  case 2:
11427598Sminkyu.jeong@arm.com                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11437598Sminkyu.jeong@arm.com                  default:
11447598Sminkyu.jeong@arm.com                    return new Unknown(machInst);
11452678Sktlim@umich.edu                }
11462678Sktlim@umich.edu            } else {
11472678Sktlim@umich.edu                switch (size) {
11482678Sktlim@umich.edu                  case 1:
11492292SN/A                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
11502292SN/A                  case 2:
11512292SN/A                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11522292SN/A                  default:
11532292SN/A                    return new Unknown(machInst);
11542292SN/A                }
11552292SN/A            }
11562292SN/A          case 0x5:
11573126Sktlim@umich.edu            if (u)
11582292SN/A                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
11592292SN/A            else
11602292SN/A                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
11612292SN/A          case 0x2:
11622292SN/A            if (u) {
11632292SN/A                switch (size) {
11642292SN/A                  case 1:
11652292SN/A                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11662292SN/A                  case 2:
11672292SN/A                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11682292SN/A                  default:
11692292SN/A                    return new Unknown(machInst);
11702292SN/A                }
11712329SN/A            } else {
11722329SN/A                switch (size) {
11732329SN/A                  case 1:
11742292SN/A                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
11759527SMatt.Horsnell@arm.com                  case 2:
11769527SMatt.Horsnell@arm.com                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
11779527SMatt.Horsnell@arm.com                  default:
11789527SMatt.Horsnell@arm.com                    return new Unknown(machInst);
11799527SMatt.Horsnell@arm.com                }
11809527SMatt.Horsnell@arm.com            }
11819527SMatt.Horsnell@arm.com          case 0x6:
11822292SN/A            if (u) {
11832292SN/A                switch (size) {
11842292SN/A                  case 1:
11852292SN/A                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
11862292SN/A                  case 2:
11872292SN/A                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
11882292SN/A                  default:
11892292SN/A                    return new Unknown(machInst);
11902292SN/A                }
11912316SN/A            } else {
11922316SN/A                switch (size) {
11932329SN/A                  case 1:
11948727Snilay@cs.wisc.edu                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
11958727Snilay@cs.wisc.edu                  case 2:
11968727Snilay@cs.wisc.edu                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
11978727Snilay@cs.wisc.edu                  default:
11982329SN/A                    return new Unknown(machInst);
11992329SN/A                }
12002329SN/A            }
120112216Snikos.nikoleris@arm.com          case 0x3:
120212216Snikos.nikoleris@arm.com            if (u) {
120312216Snikos.nikoleris@arm.com                return new Unknown(machInst);
120412216Snikos.nikoleris@arm.com            } else {
120512216Snikos.nikoleris@arm.com                switch (size) {
12062732Sktlim@umich.edu                  case 1:
12072316SN/A                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12082292SN/A                  case 2:
12092292SN/A                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12102292SN/A                  default:
12116974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
12126974Stjones1@inf.ed.ac.uk                }
12136974Stjones1@inf.ed.ac.uk            }
12148975Sandreas.hansson@arm.com          case 0x7:
12156974Stjones1@inf.ed.ac.uk            if (u) {
12166974Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
12176974Stjones1@inf.ed.ac.uk            } else {
12186974Stjones1@inf.ed.ac.uk                switch (size) {
12196974Stjones1@inf.ed.ac.uk                  case 1:
12206974Stjones1@inf.ed.ac.uk                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12216974Stjones1@inf.ed.ac.uk                  case 2:
12226974Stjones1@inf.ed.ac.uk                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12236974Stjones1@inf.ed.ac.uk                  default:
12246974Stjones1@inf.ed.ac.uk                    return new Unknown(machInst);
12256974Stjones1@inf.ed.ac.uk                }
12262693Sktlim@umich.edu            }
12272693Sktlim@umich.edu          case 0x8:
12282693Sktlim@umich.edu            if (u) {
12292698Sktlim@umich.edu                switch (size) {
12304985Sktlim@umich.edu                  case 1:
12312698Sktlim@umich.edu                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
12322693Sktlim@umich.edu                  case 2:
12338587Snilay@cs.wisc.edu                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
12348587Snilay@cs.wisc.edu                  default:
12358587Snilay@cs.wisc.edu                    return new Unknown(machInst);
12368975Sandreas.hansson@arm.com                }
12376974Stjones1@inf.ed.ac.uk            } else {
12388133SAli.Saidi@ARM.com                switch (size) {
12398133SAli.Saidi@ARM.com                  case 1:
12408133SAli.Saidi@ARM.com                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
12416974Stjones1@inf.ed.ac.uk                  case 2:
12426974Stjones1@inf.ed.ac.uk                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
12432699Sktlim@umich.edu                  default:
12442693Sktlim@umich.edu                    return new Unknown(machInst);
12456974Stjones1@inf.ed.ac.uk                }
12466974Stjones1@inf.ed.ac.uk            }
12476974Stjones1@inf.ed.ac.uk          case 0x9:
12486974Stjones1@inf.ed.ac.uk            if (u)
12496974Stjones1@inf.ed.ac.uk                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
12506974Stjones1@inf.ed.ac.uk            else
12516974Stjones1@inf.ed.ac.uk                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
12526974Stjones1@inf.ed.ac.uk          case 0xa:
12532693Sktlim@umich.edu            if (u) {
12542693Sktlim@umich.edu                switch (size) {
12552727Sktlim@umich.edu                  case 1:
12562693Sktlim@umich.edu                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
12572693Sktlim@umich.edu                  case 2:
12582693Sktlim@umich.edu                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
12592693Sktlim@umich.edu                  default:
12602693Sktlim@umich.edu                    return new Unknown(machInst);
12612292SN/A                }
12629440SAndreas.Sandberg@ARM.com            } else {
12632292SN/A                switch (size) {
12642292SN/A                  case 1:
12652292SN/A                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
12662292SN/A                  case 2:
12672292SN/A                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
12682292SN/A                  default:
12692292SN/A                    return new Unknown(machInst);
12709440SAndreas.Sandberg@ARM.com                }
12712292SN/A            }
12722292SN/A          case 0xb:
12732292SN/A            if (u) {
12742292SN/A                return new Unknown(machInst);
12752292SN/A            } else {
12762292SN/A                if (u) {
12772292SN/A                    switch (size) {
12789440SAndreas.Sandberg@ARM.com                      case 1:
12792292SN/A                        return new Vqdmulls<uint16_t>(
12802292SN/A                                machInst, vd, vn, vm, index);
12812292SN/A                      case 2:
12822292SN/A                        return new Vqdmulls<uint32_t>(
12832292SN/A                                machInst, vd, vn, vm, index);
12842292SN/A                      default:
12852292SN/A                        return new Unknown(machInst);
12869440SAndreas.Sandberg@ARM.com                    }
12872292SN/A                } else {
12882292SN/A                    switch (size) {
12892292SN/A                      case 1:
12902292SN/A                        return new Vqdmulls<int16_t>(
12912329SN/A                                machInst, vd, vn, vm, index);
12922329SN/A                      case 2:
12932329SN/A                        return new Vqdmulls<int32_t>(
12949440SAndreas.Sandberg@ARM.com                                machInst, vd, vn, vm, index);
12952329SN/A                      default:
12962329SN/A                        return new Unknown(machInst);
12972329SN/A                    }
12982329SN/A                }
12992329SN/A            }
13002329SN/A          case 0xc:
13012329SN/A            if (u) {
13022329SN/A                switch (size) {
13039440SAndreas.Sandberg@ARM.com                  case 1:
13049440SAndreas.Sandberg@ARM.com                    return new VqdmulhsQ<int16_t>(
13052329SN/A                            machInst, vd, vn, vm, index);
13062329SN/A                  case 2:
13072329SN/A                    return new VqdmulhsQ<int32_t>(
13089440SAndreas.Sandberg@ARM.com                            machInst, vd, vn, vm, index);
13092329SN/A                  default:
13102329SN/A                    return new Unknown(machInst);
13112329SN/A                }
13122329SN/A            } else {
13132329SN/A                switch (size) {
13142329SN/A                  case 1:
13152329SN/A                    return new VqdmulhsD<int16_t>(
13169440SAndreas.Sandberg@ARM.com                            machInst, vd, vn, vm, index);
13179440SAndreas.Sandberg@ARM.com                  case 2:
13182329SN/A                    return new VqdmulhsD<int32_t>(
13192329SN/A                            machInst, vd, vn, vm, index);
13202329SN/A                  default:
13212329SN/A                    return new Unknown(machInst);
13222329SN/A                }
13232329SN/A            }
13249944Smatt.horsnell@ARM.com          case 0xd:
13259944Smatt.horsnell@ARM.com            if (u) {
1326                switch (size) {
1327                  case 1:
1328                    return new VqrdmulhsQ<int16_t>(
1329                            machInst, vd, vn, vm, index);
1330                  case 2:
1331                    return new VqrdmulhsQ<int32_t>(
1332                            machInst, vd, vn, vm, index);
1333                  default:
1334                    return new Unknown(machInst);
1335                }
1336            } else {
1337                switch (size) {
1338                  case 1:
1339                    return new VqrdmulhsD<int16_t>(
1340                            machInst, vd, vn, vm, index);
1341                  case 2:
1342                    return new VqrdmulhsD<int32_t>(
1343                            machInst, vd, vn, vm, index);
1344                  default:
1345                    return new Unknown(machInst);
1346                }
1347            }
1348        }
1349        return new Unknown(machInst);
1350    }
1351
1352    static StaticInstPtr
1353    decodeNeonTwoRegMisc(ExtMachInst machInst)
1354    {
1355        const uint32_t a = bits(machInst, 17, 16);
1356        const uint32_t b = bits(machInst, 10, 6);
1357        const bool q = bits(machInst, 6);
1358        const IntRegIndex vd =
1359            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1360                               (bits(machInst, 22) << 4)));
1361        const IntRegIndex vm =
1362            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1363                               (bits(machInst, 5) << 4)));
1364        const unsigned size = bits(machInst, 19, 18);
1365        switch (a) {
1366          case 0x0:
1367            switch (bits(b, 4, 1)) {
1368              case 0x0:
1369                switch (size) {
1370                  case 0:
1371                    if (q) {
1372                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
1373                    } else {
1374                        return new NVrev64D<uint8_t>(machInst, vd, vm);
1375                    }
1376                  case 1:
1377                    if (q) {
1378                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
1379                    } else {
1380                        return new NVrev64D<uint16_t>(machInst, vd, vm);
1381                    }
1382                  case 2:
1383                    if (q) {
1384                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
1385                    } else {
1386                        return new NVrev64D<uint32_t>(machInst, vd, vm);
1387                    }
1388                  default:
1389                    return new Unknown(machInst);
1390                }
1391              case 0x1:
1392                switch (size) {
1393                  case 0:
1394                    if (q) {
1395                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
1396                    } else {
1397                        return new NVrev32D<uint8_t>(machInst, vd, vm);
1398                    }
1399                  case 1:
1400                    if (q) {
1401                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1402                    } else {
1403                        return new NVrev32D<uint16_t>(machInst, vd, vm);
1404                    }
1405                  default:
1406                    return new Unknown(machInst);
1407                }
1408              case 0x2:
1409                if (size != 0) {
1410                    return new Unknown(machInst);
1411                } else if (q) {
1412                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
1413                } else {
1414                    return new NVrev16D<uint8_t>(machInst, vd, vm);
1415                }
1416              case 0x4:
1417                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1418                        q, size, machInst, vd, vm);
1419              case 0x5:
1420                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1421                        q, size, machInst, vd, vm);
1422              case 0x8:
1423                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1424                        q, size, machInst, vd, vm);
1425              case 0x9:
1426                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1427                        q, size, machInst, vd, vm);
1428              case 0xa:
1429                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1430                        q, size, machInst, vd, vm);
1431              case 0xb:
1432                if (q)
1433                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
1434                else
1435                    return new NVmvnD<uint64_t>(machInst, vd, vm);
1436              case 0xc:
1437                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1438                        q, size, machInst, vd, vm);
1439              case 0xd:
1440                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1441                        q, size, machInst, vd, vm);
1442              case 0xe:
1443                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1444                        q, size, machInst, vd, vm);
1445              case 0xf:
1446                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1447                        q, size, machInst, vd, vm);
1448              default:
1449                return new Unknown(machInst);
1450            }
1451          case 0x1:
1452            switch (bits(b, 3, 1)) {
1453              case 0x0:
1454                if (bits(b, 4)) {
1455                    if (q) {
1456                        return new NVcgtQFp<float>(machInst, vd, vm);
1457                    } else {
1458                        return new NVcgtDFp<float>(machInst, vd, vm);
1459                    }
1460                } else {
1461                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1462                            q, size, machInst, vd, vm);
1463                }
1464              case 0x1:
1465                if (bits(b, 4)) {
1466                    if (q) {
1467                        return new NVcgeQFp<float>(machInst, vd, vm);
1468                    } else {
1469                        return new NVcgeDFp<float>(machInst, vd, vm);
1470                    }
1471                } else {
1472                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1473                            q, size, machInst, vd, vm);
1474                }
1475              case 0x2:
1476                if (bits(b, 4)) {
1477                    if (q) {
1478                        return new NVceqQFp<float>(machInst, vd, vm);
1479                    } else {
1480                        return new NVceqDFp<float>(machInst, vd, vm);
1481                    }
1482                } else {
1483                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1484                            q, size, machInst, vd, vm);
1485                }
1486              case 0x3:
1487                if (bits(b, 4)) {
1488                    if (q) {
1489                        return new NVcleQFp<float>(machInst, vd, vm);
1490                    } else {
1491                        return new NVcleDFp<float>(machInst, vd, vm);
1492                    }
1493                } else {
1494                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1495                            q, size, machInst, vd, vm);
1496                }
1497              case 0x4:
1498                if (bits(b, 4)) {
1499                    if (q) {
1500                        return new NVcltQFp<float>(machInst, vd, vm);
1501                    } else {
1502                        return new NVcltDFp<float>(machInst, vd, vm);
1503                    }
1504                } else {
1505                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1506                            q, size, machInst, vd, vm);
1507                }
1508              case 0x6:
1509                if (bits(machInst, 10)) {
1510                    if (q)
1511                        return new NVabsQFp<float>(machInst, vd, vm);
1512                    else
1513                        return new NVabsDFp<float>(machInst, vd, vm);
1514                } else {
1515                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1516                            q, size, machInst, vd, vm);
1517                }
1518              case 0x7:
1519                if (bits(machInst, 10)) {
1520                    if (q)
1521                        return new NVnegQFp<float>(machInst, vd, vm);
1522                    else
1523                        return new NVnegDFp<float>(machInst, vd, vm);
1524                } else {
1525                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1526                            q, size, machInst, vd, vm);
1527                }
1528            }
1529          case 0x2:
1530            switch (bits(b, 4, 1)) {
1531              case 0x0:
1532                if (q)
1533                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1534                else
1535                    return new NVswpD<uint64_t>(machInst, vd, vm);
1536              case 0x1:
1537                return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
1538                        q, size, machInst, vd, vm);
1539              case 0x2:
1540                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1541                        q, size, machInst, vd, vm);
1542              case 0x3:
1543                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1544                        q, size, machInst, vd, vm);
1545              case 0x4:
1546                if (b == 0x8) {
1547                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1548                            size, machInst, vd, vm);
1549                } else {
1550                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1551                            size, machInst, vd, vm);
1552                }
1553              case 0x5:
1554                if (q) {
1555                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1556                            size, machInst, vd, vm);
1557                } else {
1558                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1559                            size, machInst, vd, vm);
1560                }
1561              case 0x6:
1562                if (b == 0xc) {
1563                    const IntRegIndex vd =
1564                        (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1565                                           (bits(machInst, 22) << 4)));
1566                    const IntRegIndex vm =
1567                        (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1568                                           (bits(machInst, 5) << 4)));
1569                    unsigned size = bits(machInst, 19, 18);
1570                    return decodeNeonSTwoShiftUSReg<NVshll>(
1571                            size, machInst, vd, vm, 8 << size);
1572                } else {
1573                    return new Unknown(machInst);
1574                }
1575              case 0xc:
1576              case 0xe:
1577                if (b == 0x18) {
1578                    if (size != 1 || (vm % 2))
1579                        return new Unknown(machInst);
1580                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1581                } else if (b == 0x1c) {
1582                    if (size != 1 || (vd % 2))
1583                        return new Unknown(machInst);
1584                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1585                } else {
1586                    return new Unknown(machInst);
1587                }
1588              default:
1589                return new Unknown(machInst);
1590            }
1591          case 0x3:
1592            if (bits(b, 4, 3) == 0x3) {
1593                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1594                    return new Unknown(machInst);
1595                } else {
1596                    if (bits(b, 2)) {
1597                        if (bits(b, 1)) {
1598                            if (q) {
1599                                return new NVcvt2ufxQ<float>(
1600                                        machInst, vd, vm, 0);
1601                            } else {
1602                                return new NVcvt2ufxD<float>(
1603                                        machInst, vd, vm, 0);
1604                            }
1605                        } else {
1606                            if (q) {
1607                                return new NVcvt2sfxQ<float>(
1608                                        machInst, vd, vm, 0);
1609                            } else {
1610                                return new NVcvt2sfxD<float>(
1611                                        machInst, vd, vm, 0);
1612                            }
1613                        }
1614                    } else {
1615                        if (bits(b, 1)) {
1616                            if (q) {
1617                                return new NVcvtu2fpQ<float>(
1618                                        machInst, vd, vm, 0);
1619                            } else {
1620                                return new NVcvtu2fpD<float>(
1621                                        machInst, vd, vm, 0);
1622                            }
1623                        } else {
1624                            if (q) {
1625                                return new NVcvts2fpQ<float>(
1626                                        machInst, vd, vm, 0);
1627                            } else {
1628                                return new NVcvts2fpD<float>(
1629                                        machInst, vd, vm, 0);
1630                            }
1631                        }
1632                    }
1633                }
1634            } else if ((b & 0x1a) == 0x10) {
1635                if (bits(b, 2)) {
1636                    if (q) {
1637                        return new NVrecpeQFp<float>(machInst, vd, vm);
1638                    } else {
1639                        return new NVrecpeDFp<float>(machInst, vd, vm);
1640                    }
1641                } else {
1642                    if (q) {
1643                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1644                    } else {
1645                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1646                    }
1647                }
1648            } else if ((b & 0x1a) == 0x12) {
1649                if (bits(b, 2)) {
1650                    if (q) {
1651                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1652                    } else {
1653                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1654                    }
1655                } else {
1656                    if (q) {
1657                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1658                    } else {
1659                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1660                    }
1661                }
1662            } else {
1663                return new Unknown(machInst);
1664            }
1665        }
1666        return new Unknown(machInst);
1667    }
1668
1669    StaticInstPtr
1670    decodeNeonData(ExtMachInst machInst)
1671    {
1672        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1673        const uint32_t a = bits(machInst, 23, 19);
1674        const uint32_t b = bits(machInst, 11, 8);
1675        const uint32_t c = bits(machInst, 7, 4);
1676        if (bits(a, 4) == 0) {
1677            return decodeNeonThreeRegistersSameLength(machInst);
1678        } else if ((c & 0x9) == 1) {
1679            if ((a & 0x7) == 0) {
1680                return decodeNeonOneRegModImm(machInst);
1681            } else {
1682                return decodeNeonTwoRegAndShift(machInst);
1683            }
1684        } else if ((c & 0x9) == 9) {
1685            return decodeNeonTwoRegAndShift(machInst);
1686        } else if (bits(a, 2, 1) != 0x3) {
1687            if ((c & 0x5) == 0) {
1688                return decodeNeonThreeRegDiffLengths(machInst);
1689            } else if ((c & 0x5) == 4) {
1690                return decodeNeonTwoRegScalar(machInst);
1691            }
1692        } else if ((a & 0x16) == 0x16) {
1693            const IntRegIndex vd =
1694                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1695                                   (bits(machInst, 22) << 4)));
1696            const IntRegIndex vn =
1697                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1698                                   (bits(machInst, 7) << 4)));
1699            const IntRegIndex vm =
1700                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1701                                   (bits(machInst, 5) << 4)));
1702            if (!u) {
1703                if (bits(c, 0) == 0) {
1704                    unsigned imm4 = bits(machInst, 11, 8);
1705                    bool q = bits(machInst, 6);
1706                    if (imm4 >= 16 && !q)
1707                        return new Unknown(machInst);
1708                    if (q) {
1709                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1710                    } else {
1711                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1712                    }
1713                }
1714            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1715                return decodeNeonTwoRegMisc(machInst);
1716            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1717                unsigned length = bits(machInst, 9, 8) + 1;
1718                if ((uint32_t)vn / 2 + length > 32)
1719                    return new Unknown(machInst);
1720                if (bits(machInst, 6) == 0) {
1721                    switch (length) {
1722                      case 1:
1723                        return new NVtbl1(machInst, vd, vn, vm);
1724                      case 2:
1725                        return new NVtbl2(machInst, vd, vn, vm);
1726                      case 3:
1727                        return new NVtbl3(machInst, vd, vn, vm);
1728                      case 4:
1729                        return new NVtbl4(machInst, vd, vn, vm);
1730                    }
1731                } else {
1732                    switch (length) {
1733                      case 1:
1734                        return new NVtbx1(machInst, vd, vn, vm);
1735                      case 2:
1736                        return new NVtbx2(machInst, vd, vn, vm);
1737                      case 3:
1738                        return new NVtbx3(machInst, vd, vn, vm);
1739                      case 4:
1740                        return new NVtbx4(machInst, vd, vn, vm);
1741                    }
1742                }
1743            } else if (b == 0xc && (c & 0x9) == 0) {
1744                unsigned imm4 = bits(machInst, 19, 16);
1745                if (bits(imm4, 2, 0) == 0)
1746                    return new Unknown(machInst);
1747                unsigned size = 0;
1748                while ((imm4 & 0x1) == 0) {
1749                    size++;
1750                    imm4 >>= 1;
1751                }
1752                unsigned index = imm4 >> 1;
1753                const bool q = bits(machInst, 6);
1754                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1755                        q, size, machInst, vd, vm, index);
1756            }
1757        }
1758        return new Unknown(machInst);
1759    }
1760    '''
1761}};
1762
1763def format ThumbNeonMem() {{
1764    decode_block = '''
1765    return decodeNeonMem(machInst);
1766    '''
1767}};
1768
1769def format ThumbNeonData() {{
1770    decode_block = '''
1771    return decodeNeonData(machInst);
1772    '''
1773}};
1774
1775let {{
1776    header_output = '''
1777    StaticInstPtr
1778    decodeExtensionRegLoadStore(ExtMachInst machInst);
1779    '''
1780    decoder_output = '''
1781    StaticInstPtr
1782    decodeExtensionRegLoadStore(ExtMachInst machInst)
1783    {
1784        const uint32_t opcode = bits(machInst, 24, 20);
1785        const uint32_t offset = bits(machInst, 7, 0);
1786        const bool single = (bits(machInst, 8) == 0);
1787        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1788        RegIndex vd;
1789        if (single) {
1790            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1791                                      bits(machInst, 22));
1792        } else {
1793            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1794                                      (bits(machInst, 22) << 5));
1795        }
1796        switch (bits(opcode, 4, 3)) {
1797          case 0x0:
1798            if (bits(opcode, 4, 1) == 0x2 &&
1799                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1800                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1801                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1802                    break;
1803                }
1804                const IntRegIndex rt =
1805                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1806                const IntRegIndex rt2 =
1807                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1808                const bool op = bits(machInst, 20);
1809                uint32_t vm;
1810                if (single) {
1811                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1812                } else {
1813                    vm = (bits(machInst, 3, 0) << 1) |
1814                         (bits(machInst, 5) << 5);
1815                }
1816                if (op) {
1817                    return new Vmov2Core2Reg(machInst, rt, rt2,
1818                                             (IntRegIndex)vm);
1819                } else {
1820                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1821                                             rt, rt2);
1822                }
1823            }
1824            break;
1825          case 0x1:
1826            {
1827                if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1828                    break;
1829                }
1830                switch (bits(opcode, 1, 0)) {
1831                  case 0x0:
1832                    return new VLdmStm(machInst, rn, vd, single,
1833                                       true, false, false, offset);
1834                  case 0x1:
1835                    return new VLdmStm(machInst, rn, vd, single,
1836                                       true, false, true, offset);
1837                  case 0x2:
1838                    return new VLdmStm(machInst, rn, vd, single,
1839                                       true, true, false, offset);
1840                  case 0x3:
1841                    // If rn == sp, then this is called vpop.
1842                    return new VLdmStm(machInst, rn, vd, single,
1843                                       true, true, true, offset);
1844                }
1845            }
1846          case 0x2:
1847            if (bits(opcode, 1, 0) == 0x2) {
1848                // If rn == sp, then this is called vpush.
1849                return new VLdmStm(machInst, rn, vd, single,
1850                                   false, true, false, offset);
1851            } else if (bits(opcode, 1, 0) == 0x3) {
1852                return new VLdmStm(machInst, rn, vd, single,
1853                                   false, true, true, offset);
1854            }
1855            // Fall through on purpose
1856          case 0x3:
1857            const bool up = (bits(machInst, 23) == 1);
1858            const uint32_t imm = bits(machInst, 7, 0) << 2;
1859            RegIndex vd;
1860            if (single) {
1861                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1862                                          (bits(machInst, 22)));
1863            } else {
1864                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1865                                          (bits(machInst, 22) << 5));
1866            }
1867            if (bits(opcode, 1, 0) == 0x0) {
1868                if (single) {
1869                    if (up) {
1870                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1871                    } else {
1872                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1873                    }
1874                } else {
1875                    if (up) {
1876                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1877                                               rn, up, imm);
1878                    } else {
1879                        return new %(vstr_d)s(machInst, vd, vd + 1,
1880                                              rn, up, imm);
1881                    }
1882                }
1883            } else if (bits(opcode, 1, 0) == 0x1) {
1884                if (single) {
1885                    if (up) {
1886                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1887                    } else {
1888                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1889                    }
1890                } else {
1891                    if (up) {
1892                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1893                                               rn, up, imm);
1894                    } else {
1895                        return new %(vldr_d)s(machInst, vd, vd + 1,
1896                                              rn, up, imm);
1897                    }
1898                }
1899            }
1900        }
1901        return new Unknown(machInst);
1902    }
1903    ''' % {
1904        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1905        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1906        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1907        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1908        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1909        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1910        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1911        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1912    }
1913}};
1914
1915def format ExtensionRegLoadStore() {{
1916    decode_block = '''
1917    return decodeExtensionRegLoadStore(machInst);
1918    '''
1919}};
1920
1921let {{
1922    header_output = '''
1923    StaticInstPtr
1924    decodeShortFpTransfer(ExtMachInst machInst);
1925    '''
1926    decoder_output = '''
1927    StaticInstPtr
1928    decodeShortFpTransfer(ExtMachInst machInst)
1929    {
1930        const uint32_t l = bits(machInst, 20);
1931        const uint32_t c = bits(machInst, 8);
1932        const uint32_t a = bits(machInst, 23, 21);
1933        const uint32_t b = bits(machInst, 6, 5);
1934        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1935            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1936            return new Unknown(machInst);
1937        }
1938        if (l == 0 && c == 0) {
1939            if (a == 0) {
1940                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1941                                    bits(machInst, 7);
1942                const IntRegIndex rt =
1943                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1944                if (bits(machInst, 20) == 1) {
1945                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1946                } else {
1947                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1948                }
1949            } else if (a == 0x7) {
1950                const IntRegIndex rt =
1951                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1952                uint32_t specReg = bits(machInst, 19, 16);
1953                switch (specReg) {
1954                  case 0:
1955                    specReg = MISCREG_FPSID;
1956                    break;
1957                  case 1:
1958                    specReg = MISCREG_FPSCR;
1959                    break;
1960                  case 6:
1961                    specReg = MISCREG_MVFR1;
1962                    break;
1963                  case 7:
1964                    specReg = MISCREG_MVFR0;
1965                    break;
1966                  case 8:
1967                    specReg = MISCREG_FPEXC;
1968                    break;
1969                  default:
1970                    return new Unknown(machInst);
1971                }
1972                if (specReg == MISCREG_FPSCR) {
1973                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1974                } else {
1975                    return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1976                }
1977            }
1978        } else if (l == 0 && c == 1) {
1979            if (bits(a, 2) == 0) {
1980                uint32_t vd = (bits(machInst, 7) << 5) |
1981                              (bits(machInst, 19, 16) << 1);
1982                // Handle accessing each single precision half of the vector.
1983                vd += bits(machInst, 21);
1984                const IntRegIndex rt =
1985                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1986                if (bits(machInst, 22) == 1) {
1987                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1988                                            rt, bits(machInst, 6, 5));
1989                } else if (bits(machInst, 5) == 1) {
1990                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1991                                            rt, bits(machInst, 6));
1992                } else if (bits(machInst, 6) == 0) {
1993                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
1994                } else {
1995                    return new Unknown(machInst);
1996                }
1997            } else if (bits(b, 1) == 0) {
1998                bool q = bits(machInst, 21);
1999                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2000                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2001                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2002                IntRegIndex rt = (IntRegIndex)(uint32_t)
2003                    bits(machInst, 15, 12);
2004                if (q) {
2005                    switch (be) {
2006                      case 0:
2007                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2008                      case 1:
2009                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2010                      case 2:
2011                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2012                      case 3:
2013                        return new Unknown(machInst);
2014                    }
2015                } else {
2016                    switch (be) {
2017                      case 0:
2018                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2019                      case 1:
2020                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2021                      case 2:
2022                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2023                      case 3:
2024                        return new Unknown(machInst);
2025                    }
2026                }
2027            }
2028        } else if (l == 1 && c == 0) {
2029            if (a == 0) {
2030                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2031                                    bits(machInst, 7);
2032                const IntRegIndex rt =
2033                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2034                if (bits(machInst, 20) == 1) {
2035                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2036                } else {
2037                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2038                }
2039            } else if (a == 7) {
2040                const IntRegIndex rt =
2041                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042                uint32_t specReg = bits(machInst, 19, 16);
2043                switch (specReg) {
2044                  case 0:
2045                    specReg = MISCREG_FPSID;
2046                    break;
2047                  case 1:
2048                    specReg = MISCREG_FPSCR;
2049                    break;
2050                  case 6:
2051                    specReg = MISCREG_MVFR1;
2052                    break;
2053                  case 7:
2054                    specReg = MISCREG_MVFR0;
2055                    break;
2056                  case 8:
2057                    specReg = MISCREG_FPEXC;
2058                    break;
2059                  default:
2060                    return new Unknown(machInst);
2061                }
2062                if (rt == 0xf) {
2063                    CPSR cpsrMask = 0;
2064                    cpsrMask.n = 1;
2065                    cpsrMask.z = 1;
2066                    cpsrMask.c = 1;
2067                    cpsrMask.v = 1;
2068                    if (specReg == MISCREG_FPSCR) {
2069                        return new VmrsApsrFpscr(machInst, INTREG_CONDCODES,
2070                                (IntRegIndex)specReg, (uint32_t)cpsrMask);
2071                    } else {
2072                        return new VmrsApsr(machInst, INTREG_CONDCODES,
2073                                (IntRegIndex)specReg, (uint32_t)cpsrMask);
2074                    }
2075                } else if (specReg == MISCREG_FPSCR) {
2076                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2077                } else {
2078                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2079                }
2080            }
2081        } else {
2082            uint32_t vd = (bits(machInst, 7) << 5) |
2083                          (bits(machInst, 19, 16) << 1);
2084            // Handle indexing into each single precision half of the vector.
2085            vd += bits(machInst, 21);
2086            uint32_t index;
2087            const IntRegIndex rt =
2088                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2089            const bool u = (bits(machInst, 23) == 1);
2090            if (bits(machInst, 22) == 1) {
2091                index = bits(machInst, 6, 5);
2092                if (u) {
2093                    return new VmovRegCoreUB(machInst, rt,
2094                                             (IntRegIndex)vd, index);
2095                } else {
2096                    return new VmovRegCoreSB(machInst, rt,
2097                                             (IntRegIndex)vd, index);
2098                }
2099            } else if (bits(machInst, 5) == 1) {
2100                index = bits(machInst, 6);
2101                if (u) {
2102                    return new VmovRegCoreUH(machInst, rt,
2103                                             (IntRegIndex)vd, index);
2104                } else {
2105                    return new VmovRegCoreSH(machInst, rt,
2106                                             (IntRegIndex)vd, index);
2107                }
2108            } else if (bits(machInst, 6) == 0 && !u) {
2109                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2110            } else {
2111                return new Unknown(machInst);
2112            }
2113        }
2114        return new Unknown(machInst);
2115    }
2116    '''
2117}};
2118
2119def format ShortFpTransfer() {{
2120    decode_block = '''
2121    return decodeShortFpTransfer(machInst);
2122    '''
2123}};
2124
2125let {{
2126    header_output = '''
2127    StaticInstPtr
2128    decodeVfpData(ExtMachInst machInst);
2129    '''
2130    decoder_output = '''
2131    StaticInstPtr
2132    decodeVfpData(ExtMachInst machInst)
2133    {
2134        const uint32_t opc1 = bits(machInst, 23, 20);
2135        const uint32_t opc2 = bits(machInst, 19, 16);
2136        const uint32_t opc3 = bits(machInst, 7, 6);
2137        //const uint32_t opc4 = bits(machInst, 3, 0);
2138        const bool single = (bits(machInst, 8) == 0);
2139        // Used to select between vcmp and vcmpe.
2140        const bool e = (bits(machInst, 7) == 1);
2141        IntRegIndex vd;
2142        IntRegIndex vm;
2143        IntRegIndex vn;
2144        if (single) {
2145            vd = (IntRegIndex)(bits(machInst, 22) |
2146                    (bits(machInst, 15, 12) << 1));
2147            vm = (IntRegIndex)(bits(machInst, 5) |
2148                    (bits(machInst, 3, 0) << 1));
2149            vn = (IntRegIndex)(bits(machInst, 7) |
2150                    (bits(machInst, 19, 16) << 1));
2151        } else {
2152            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2153                    (bits(machInst, 15, 12) << 1));
2154            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2155                    (bits(machInst, 3, 0) << 1));
2156            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2157                    (bits(machInst, 19, 16) << 1));
2158        }
2159        switch (opc1 & 0xb /* 1011 */) {
2160          case 0x0:
2161            if (bits(machInst, 6) == 0) {
2162                if (single) {
2163                    return decodeVfpRegRegRegOp<VmlaS>(
2164                            machInst, vd, vn, vm, false);
2165                } else {
2166                    return decodeVfpRegRegRegOp<VmlaD>(
2167                            machInst, vd, vn, vm, true);
2168                }
2169            } else {
2170                if (single) {
2171                    return decodeVfpRegRegRegOp<VmlsS>(
2172                            machInst, vd, vn, vm, false);
2173                } else {
2174                    return decodeVfpRegRegRegOp<VmlsD>(
2175                            machInst, vd, vn, vm, true);
2176                }
2177            }
2178          case 0x1:
2179            if (bits(machInst, 6) == 1) {
2180                if (single) {
2181                    return decodeVfpRegRegRegOp<VnmlaS>(
2182                            machInst, vd, vn, vm, false);
2183                } else {
2184                    return decodeVfpRegRegRegOp<VnmlaD>(
2185                            machInst, vd, vn, vm, true);
2186                }
2187            } else {
2188                if (single) {
2189                    return decodeVfpRegRegRegOp<VnmlsS>(
2190                            machInst, vd, vn, vm, false);
2191                } else {
2192                    return decodeVfpRegRegRegOp<VnmlsD>(
2193                            machInst, vd, vn, vm, true);
2194                }
2195            }
2196          case 0x2:
2197            if ((opc3 & 0x1) == 0) {
2198                if (single) {
2199                    return decodeVfpRegRegRegOp<VmulS>(
2200                            machInst, vd, vn, vm, false);
2201                } else {
2202                    return decodeVfpRegRegRegOp<VmulD>(
2203                            machInst, vd, vn, vm, true);
2204                }
2205            } else {
2206                if (single) {
2207                    return decodeVfpRegRegRegOp<VnmulS>(
2208                            machInst, vd, vn, vm, false);
2209                } else {
2210                    return decodeVfpRegRegRegOp<VnmulD>(
2211                            machInst, vd, vn, vm, true);
2212                }
2213            }
2214          case 0x3:
2215            if ((opc3 & 0x1) == 0) {
2216                if (single) {
2217                    return decodeVfpRegRegRegOp<VaddS>(
2218                            machInst, vd, vn, vm, false);
2219                } else {
2220                    return decodeVfpRegRegRegOp<VaddD>(
2221                            machInst, vd, vn, vm, true);
2222                }
2223            } else {
2224                if (single) {
2225                    return decodeVfpRegRegRegOp<VsubS>(
2226                            machInst, vd, vn, vm, false);
2227                } else {
2228                    return decodeVfpRegRegRegOp<VsubD>(
2229                            machInst, vd, vn, vm, true);
2230                }
2231            }
2232          case 0x8:
2233            if ((opc3 & 0x1) == 0) {
2234                if (single) {
2235                    return decodeVfpRegRegRegOp<VdivS>(
2236                            machInst, vd, vn, vm, false);
2237                } else {
2238                    return decodeVfpRegRegRegOp<VdivD>(
2239                            machInst, vd, vn, vm, true);
2240                }
2241            }
2242            break;
2243          case 0xb:
2244            if ((opc3 & 0x1) == 0) {
2245                const uint32_t baseImm =
2246                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2247                if (single) {
2248                    uint32_t imm = vfp_modified_imm(baseImm, false);
2249                    return decodeVfpRegImmOp<VmovImmS>(
2250                            machInst, vd, imm, false);
2251                } else {
2252                    uint64_t imm = vfp_modified_imm(baseImm, true);
2253                    return decodeVfpRegImmOp<VmovImmD>(
2254                            machInst, vd, imm, true);
2255                }
2256            }
2257            switch (opc2) {
2258              case 0x0:
2259                if (opc3 == 1) {
2260                    if (single) {
2261                        return decodeVfpRegRegOp<VmovRegS>(
2262                                machInst, vd, vm, false);
2263                    } else {
2264                        return decodeVfpRegRegOp<VmovRegD>(
2265                                machInst, vd, vm, true);
2266                    }
2267                } else {
2268                    if (single) {
2269                        return decodeVfpRegRegOp<VabsS>(
2270                                machInst, vd, vm, false);
2271                    } else {
2272                        return decodeVfpRegRegOp<VabsD>(
2273                                machInst, vd, vm, true);
2274                    }
2275                }
2276              case 0x1:
2277                if (opc3 == 1) {
2278                    if (single) {
2279                        return decodeVfpRegRegOp<VnegS>(
2280                                machInst, vd, vm, false);
2281                    } else {
2282                        return decodeVfpRegRegOp<VnegD>(
2283                                machInst, vd, vm, true);
2284                    }
2285                } else {
2286                    if (single) {
2287                        return decodeVfpRegRegOp<VsqrtS>(
2288                                machInst, vd, vm, false);
2289                    } else {
2290                        return decodeVfpRegRegOp<VsqrtD>(
2291                                machInst, vd, vm, true);
2292                    }
2293                }
2294              case 0x2:
2295              case 0x3:
2296                {
2297                    const bool toHalf = bits(machInst, 16);
2298                    const bool top = bits(machInst, 7);
2299                    if (top) {
2300                        if (toHalf) {
2301                            return new VcvtFpSFpHT(machInst, vd, vm);
2302                        } else {
2303                            return new VcvtFpHTFpS(machInst, vd, vm);
2304                        }
2305                    } else {
2306                        if (toHalf) {
2307                            return new VcvtFpSFpHB(machInst, vd, vm);
2308                        } else {
2309                            return new VcvtFpHBFpS(machInst, vd, vm);
2310                        }
2311                    }
2312                }
2313              case 0x4:
2314                if (single) {
2315                    if (e) {
2316                        return new VcmpeS(machInst, vd, vm);
2317                    } else {
2318                        return new VcmpS(machInst, vd, vm);
2319                    }
2320                } else {
2321                    if (e) {
2322                        return new VcmpeD(machInst, vd, vm);
2323                    } else {
2324                        return new VcmpD(machInst, vd, vm);
2325                    }
2326                }
2327              case 0x5:
2328                if (single) {
2329                    if (e) {
2330                        return new VcmpeZeroS(machInst, vd, 0);
2331                    } else {
2332                        return new VcmpZeroS(machInst, vd, 0);
2333                    }
2334                } else {
2335                    if (e) {
2336                        return new VcmpeZeroD(machInst, vd, 0);
2337                    } else {
2338                        return new VcmpZeroD(machInst, vd, 0);
2339                    }
2340                }
2341              case 0x7:
2342                if (opc3 == 0x3) {
2343                    if (single) {
2344                        vm = (IntRegIndex)(bits(machInst, 5) |
2345                                (bits(machInst, 3, 0) << 1));
2346                        return new VcvtFpSFpD(machInst, vd, vm);
2347                    } else {
2348                        vd = (IntRegIndex)(bits(machInst, 22) |
2349                                (bits(machInst, 15, 12) << 1));
2350                        return new VcvtFpDFpS(machInst, vd, vm);
2351                    }
2352                }
2353                break;
2354              case 0x8:
2355                if (bits(machInst, 7) == 0) {
2356                    if (single) {
2357                        return new VcvtUIntFpS(machInst, vd, vm);
2358                    } else {
2359                        vm = (IntRegIndex)(bits(machInst, 5) |
2360                                (bits(machInst, 3, 0) << 1));
2361                        return new VcvtUIntFpD(machInst, vd, vm);
2362                    }
2363                } else {
2364                    if (single) {
2365                        return new VcvtSIntFpS(machInst, vd, vm);
2366                    } else {
2367                        vm = (IntRegIndex)(bits(machInst, 5) |
2368                                (bits(machInst, 3, 0) << 1));
2369                        return new VcvtSIntFpD(machInst, vd, vm);
2370                    }
2371                }
2372              case 0xa:
2373                {
2374                    const bool half = (bits(machInst, 7) == 0);
2375                    const uint32_t imm = bits(machInst, 5) |
2376                                         (bits(machInst, 3, 0) << 1);
2377                    const uint32_t size =
2378                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2379                    if (single) {
2380                        if (half) {
2381                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2382                        } else {
2383                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2384                        }
2385                    } else {
2386                        if (half) {
2387                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2388                        } else {
2389                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2390                        }
2391                    }
2392                }
2393              case 0xb:
2394                {
2395                    const bool half = (bits(machInst, 7) == 0);
2396                    const uint32_t imm = bits(machInst, 5) |
2397                                         (bits(machInst, 3, 0) << 1);
2398                    const uint32_t size =
2399                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2400                    if (single) {
2401                        if (half) {
2402                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2403                        } else {
2404                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2405                        }
2406                    } else {
2407                        if (half) {
2408                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2409                        } else {
2410                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2411                        }
2412                    }
2413                }
2414              case 0xc:
2415                if (bits(machInst, 7) == 0) {
2416                    if (single) {
2417                        return new VcvtFpUIntSR(machInst, vd, vm);
2418                    } else {
2419                        vd = (IntRegIndex)(bits(machInst, 22) |
2420                                (bits(machInst, 15, 12) << 1));
2421                        return new VcvtFpUIntDR(machInst, vd, vm);
2422                    }
2423                } else {
2424                    if (single) {
2425                        return new VcvtFpUIntS(machInst, vd, vm);
2426                    } else {
2427                        vd = (IntRegIndex)(bits(machInst, 22) |
2428                                (bits(machInst, 15, 12) << 1));
2429                        return new VcvtFpUIntD(machInst, vd, vm);
2430                    }
2431                }
2432              case 0xd:
2433                if (bits(machInst, 7) == 0) {
2434                    if (single) {
2435                        return new VcvtFpSIntSR(machInst, vd, vm);
2436                    } else {
2437                        vd = (IntRegIndex)(bits(machInst, 22) |
2438                                (bits(machInst, 15, 12) << 1));
2439                        return new VcvtFpSIntDR(machInst, vd, vm);
2440                    }
2441                } else {
2442                    if (single) {
2443                        return new VcvtFpSIntS(machInst, vd, vm);
2444                    } else {
2445                        vd = (IntRegIndex)(bits(machInst, 22) |
2446                                (bits(machInst, 15, 12) << 1));
2447                        return new VcvtFpSIntD(machInst, vd, vm);
2448                    }
2449                }
2450              case 0xe:
2451                {
2452                    const bool half = (bits(machInst, 7) == 0);
2453                    const uint32_t imm = bits(machInst, 5) |
2454                                         (bits(machInst, 3, 0) << 1);
2455                    const uint32_t size =
2456                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2457                    if (single) {
2458                        if (half) {
2459                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2460                        } else {
2461                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2462                        }
2463                    } else {
2464                        if (half) {
2465                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2466                        } else {
2467                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2468                        }
2469                    }
2470                }
2471              case 0xf:
2472                {
2473                    const bool half = (bits(machInst, 7) == 0);
2474                    const uint32_t imm = bits(machInst, 5) |
2475                                         (bits(machInst, 3, 0) << 1);
2476                    const uint32_t size =
2477                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2478                    if (single) {
2479                        if (half) {
2480                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2481                        } else {
2482                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2483                        }
2484                    } else {
2485                        if (half) {
2486                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2487                        } else {
2488                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2489                        }
2490                    }
2491                }
2492            }
2493            break;
2494        }
2495        return new Unknown(machInst);
2496    }
2497    '''
2498}};
2499
2500def format VfpData() {{
2501    decode_block = '''
2502    return decodeVfpData(machInst);
2503    '''
2504}};
2505